> 完整文档索引见 [llms.txt](https://docs.wanduanapi.com/llms.txt)。本站每个文档页均提供 Markdown 镜像；当前页面的 Markdown 版本见 [此处](https://docs.wanduanapi.com/products/china-calendar/rest/reference.md)。

# REST 参考

本页提供中国大陆节假日 REST API 的人工可读契约，包含端点、请求参数、响应字段、枚举值和错误响应。所有端点的基础地址为：

```text
https://api.wanduanapi.com
```

## 端点

| operationCode | 方法与路径 | 用途 |
| --- | --- | --- |
| `chinaCalendar.getDateStatus` | `GET /v1/china-calendar/dates/{date}` | 查询单日状态 |
| `chinaCalendar.getDateRangeStatus` | `GET /v1/china-calendar/date-ranges` | 查询日期区间的逐日状态 |
| `chinaCalendar.calculateWorkdays` | `GET /v1/china-calendar/workdays` | 统计工作日、休息日与未知日期 |
| `chinaCalendar.getNextHoliday` | `GET /v1/china-calendar/next-holiday` | 查询指定日期起的下一节假日 |

所有端点均使用 `GET`，请求参数通过路径或查询字符串传递，不使用请求体。

## 请求参数

| operationCode | 参数 | 位置 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `chinaCalendar.getDateStatus` | `date` | 路径 | string | 是 | ISO 8601 日历日期，格式为 `yyyy-MM-dd`。 |
| `chinaCalendar.getDateRangeStatus` | `startDate` | 查询 | string | 是 | 区间起始日期，格式为 `yyyy-MM-dd`，包含当天。 |
| `chinaCalendar.getDateRangeStatus` | `endDate` | 查询 | string | 是 | 区间结束日期，格式为 `yyyy-MM-dd`，包含当天。 |
| `chinaCalendar.calculateWorkdays` | `startDate` | 查询 | string | 是 | 区间起始日期，格式为 `yyyy-MM-dd`，包含当天。 |
| `chinaCalendar.calculateWorkdays` | `endDate` | 查询 | string | 是 | 区间结束日期，格式为 `yyyy-MM-dd`，包含当天。 |
| `chinaCalendar.getNextHoliday` | `fromDate` | 查询 | string | 是 | 查找起始日期，格式为 `yyyy-MM-dd`，从当天开始查找。 |

日期区间的首尾均包含，跨度不得超过 366 天，且 `startDate` 不得晚于 `endDate`。所有日期参数都不带时间、时区或其他后缀。

## 单日状态响应

`GET /v1/china-calendar/dates/{date}` 直接返回 JSON 对象，不使用统一的 `data` 外壳。

| 字段 | JSON 类型 | 可空 | 说明 |
| --- | --- | --- | --- |
| `date` | string | 否 | 查询的业务日期，格式为 `yyyy-MM-dd`。 |
| `dayOfWeek` | string | 否 | 星期枚举，取值见下表。 |
| `workStatus` | string | 否 | 粗粒度工作状态，取值见下表。 |
| `dayStatus` | string | 否 | 细粒度日期状态，取值见下表。 |
| `holidays` | array | 否 | 当前日期关联的节日列表，无关联时为空数组；元素结构见[关联节日](#关联节日)。 |
| `datasetVersion` | string | 是 | 实际使用的数据集版本；目标年度官方安排尚未发布时为 `null`。 |

### `dayOfWeek`

使用语言无关的字符串枚举，不返回数字或本地化名称。

| 取值 | 含义 |
| --- | --- |
| `MONDAY` | 星期一 |
| `TUESDAY` | 星期二 |
| `WEDNESDAY` | 星期三 |
| `THURSDAY` | 星期四 |
| `FRIDAY` | 星期五 |
| `SATURDAY` | 星期六 |
| `SUNDAY` | 星期日 |

### `workStatus`

面向排班、考勤等场景的粗粒度结论，由 `dayStatus` 唯一推导。

| 取值 | 含义 |
| --- | --- |
| `WORKDAY` | 当天需要上班，包括普通工作日和调休补班日。 |
| `REST_DAY` | 当天休息，包括周末和节假日安排中的休息日。 |
| `UNKNOWN` | 目标年度的官方安排尚未发布，暂时无法确定当天是上班还是休息。 |

对应关系如下：

| `dayStatus` | `workStatus` |
| --- | --- |
| `WORKDAY` | `WORKDAY` |
| `ADJUSTED_WORKDAY` | `WORKDAY` |
| `WEEKEND` | `REST_DAY` |
| `HOLIDAY` | `REST_DAY` |
| `UNKNOWN` | `UNKNOWN` |

### `dayStatus`

说明日期具体原因的细粒度状态。官方节假日安排的优先级高于普通星期判断。

| 取值 | 含义 |
| --- | --- |
| `WORKDAY` | 普通工作日。 |
| `ADJUSTED_WORKDAY` | 因节假日安排产生的调休补班日。 |
| `WEEKEND` | 未被官方节假日安排覆盖的周六或周日。 |
| `HOLIDAY` | 官方节假日安排中的休息日，可能是法定节假日当天，也可能是安排的其他休息日。 |
| `UNKNOWN` | 目标年度的官方安排尚未发布，暂时无法确定日期状态。 |

## 关联节日

`holidays` 中的每个元素包含以下字段。一个日期可以关联多个节日。

| 字段 | JSON 类型 | 可空 | 说明 |
| --- | --- | --- | --- |
| `code` | string | 否 | 稳定的语言无关节日代码，供程序判断。可能取值见下表。 |
| `name` | string | 否 | 官方简体中文名称，仅用于展示。 |
| `statutoryDate` | boolean | 否 | 当前查询日期是否为该节日的法定节假日当天。 |

### `code`

| 取值 | 含义                                                 |
| --- |------------------------------------------------------|
| `NEW_YEAR` | 元旦                                                 |
| `SPRING_FESTIVAL` | 春节                                                 |
| `QINGMING_FESTIVAL` | 清明节                                               |
| `LABOR_DAY` | 劳动节                                               |
| `DRAGON_BOAT_FESTIVAL` | 端午节                                               |
| `MID_AUTUMN_FESTIVAL` | 中秋节                                               |
| `NATIONAL_DAY` | 国庆节                                               |
| `VICTORY_DAY_70TH_ANNIVERSARY` | 中国人民抗日战争暨世界反法西斯战争胜利 70 周年纪念日 |

### `statutoryDate`

| 取值 | 含义 |
| --- | --- |
| `true` | 当前日期是该节日对应的法定节假日当天。 |
| `false` | 当前日期与该节日安排有关，但不是法定节假日当天，例如延长休息日或调休补班日。 |

## 日期区间响应

`GET /v1/china-calendar/date-ranges` 返回按日期升序排列的 JSON 数组。数组中的每个元素都是单日状态响应，字段结构与[单日状态响应](#单日状态响应)相同；首尾日期均包含，单次请求最多返回 366 天。

## 工作日统计响应

`GET /v1/china-calendar/workdays` 返回以下 JSON 对象：

| 字段 | JSON 类型 | 可空 | 说明 |
| --- | --- | --- | --- |
| `startDate` | string | 否 | 统计区间的起始日期，格式为 `yyyy-MM-dd`，包含当天。 |
| `endDate` | string | 否 | 统计区间的结束日期，格式为 `yyyy-MM-dd`，包含当天。 |
| `totalDays` | integer | 否 | 区间包含的自然日总数。 |
| `workdayCount` | integer | 否 | 已确定为工作日的日期数量，包括普通工作日和调休补班日。 |
| `restDayCount` | integer | 否 | 已确定为休息日的日期数量，包括周末和节假日安排中的休息日。 |
| `unknownDayCount` | integer | 否 | 尚未发布官方安排、无法确定工作或休息属性的日期数量。 |

这些计数满足 `totalDays = workdayCount + restDayCount + unknownDayCount`。

## 下一节假日响应

`GET /v1/china-calendar/next-holiday` 返回从 `fromDate`（含当天）开始的第一个官方安排节假日日期，不要求该日期是关联节日的法定节假日当天。

| 字段 | JSON 类型 | 可空 | 说明 |
| --- | --- | --- | --- |
| `status` | string | 否 | 查询结果状态，取值见下表。 |
| `date` | string | 是 | 找到结果时为下一节假日日期，格式为 `yyyy-MM-dd`；`status=UNKNOWN` 时为 `null`。 |
| `holidays` | array | 否 | `date` 关联的节日列表；`status=UNKNOWN` 时为空数组，元素结构见[关联节日](#关联节日)。 |
| `datasetVersion` | string | 是 | 找到结果时为实际使用的数据集版本；`status=UNKNOWN` 时为 `null`。 |

| `status` 取值 | 含义 |
| --- | --- |
| `FOUND` | 已找到下一节假日，并返回 `date`、`holidays` 和 `datasetVersion`。 |
| `UNKNOWN` | 后续年度的官方安排尚未发布，暂时无法确定下一节假日；`date` 和 `datasetVersion` 为 `null`，`holidays` 为空数组。 |

## 错误响应

错误响应使用 RFC 9457 Problem Details 格式。响应媒体类型为 `application/problem+json`，HTTP 响应头为：

```http
Content-Type: application/problem+json
```

| 字段 | JSON 类型 | 可空 | 说明 |
| --- | --- | --- | --- |
| `type` | string | 否 | 问题类型的稳定 URI，指向对应的[错误说明](../../../problems/index.md)页面。 |
| `title` | string | 否 | 面向用户的错误标题。 |
| `status` | integer | 否 | 与 HTTP 响应一致的状态码。 |
| `detail` | string | 否 | 本次请求的具体错误详情。 |
| `instance` | string | 否 | 触发问题的请求路径。 |
| `code` | string | 否 | 稳定的程序可读错误码。 |
| `requestId` | string | 否 | 本次请求的定位标识，反馈问题时应一并提供。 |

常见错误码：

| 错误码 | HTTP 状态 | 说明 |
| --- | --- | --- |
| [`INVALID_DATE_FORMAT`](../../../problems/invalid-date-format.md) | 400 | 日期格式或日期值不合法。 |
| [`MISSING_PARAMETER`](../../../problems/missing-parameter.md) | 400 | 缺少必填参数。 |
| [`INVALID_DATE_RANGE`](../../../problems/invalid-date-range.md) | 400 | `startDate` 晚于 `endDate`。 |
| [`DATE_RANGE_TOO_LARGE`](../../../problems/date-range-too-large.md) | 400 | 日期区间跨度超过 366 天。 |
| [`DATE_OUT_OF_SUPPORTED_RANGE`](../../../problems/date-out-of-supported-range.md) | 400 | 日期早于 `2008-01-01`。 |
| [`RESOURCE_NOT_FOUND`](../../../problems/resource-not-found.md) | 404 | 请求路径不存在。 |
| [`METHOD_NOT_ALLOWED`](../../../problems/method-not-allowed.md) | 405 | 请求方法不被支持。 |
| [`CALENDAR_DATA_UNAVAILABLE`](../../../problems/calendar-data-unavailable.md) | 503 | 已发布范围内的日历数据暂时无法读取。 |
| [`INTERNAL_ERROR`](../../../problems/internal-error.md) | 500 | 服务端发生未预期错误。 |

目标年度的官方安排尚未发布不是错误，相关查询返回 HTTP `200`，并通过 `UNKNOWN` 表示暂时未知。
