# China Workday Calendar (`awake_froghopper/china-workday-calendar`) Actor

Check whether any date is a working day in mainland China, including official holidays and adjusted make-up workdays.

- **URL**: https://apify.com/awake_froghopper/china-workday-calendar.md
- **Developed by:** [Wayne Blomfield](https://apify.com/awake_froghopper) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## China Workday & Holiday Calendar API (调休, Lunar, Solar Terms)

**Is this date a working day in mainland China?** Weekends are not enough: China moves working days onto Saturdays and Sundays (调休 / make-up workdays) around every major holiday, and the schedule changes every year. This Actor answers that question from the **official State Council notices**, and adds the lunar date, the 24 solar terms and business-day arithmetic, all in one call.

- ✅ Official schedules typed from the State Council notices for **2024, 2025 and 2026**, with the source URL on every row
- ✅ Make-up working days (`adjusted_workday`), holiday periods, and the legally defined **statutory holidays** (法定节假日, the days that carry triple pay)
- ✅ `addWorkdays` / `countWorkdays` for SLAs, delivery dates, payroll and settlement cycles
- ✅ Lunar date (农历), ganzhi year and zodiac, plus all 24 solar terms (节气) with exact Beijing time
- ✅ Honest about uncertainty: years whose schedule is not published yet are marked `"dataStatus": "estimated"`
- ⚡ No scraping, no proxy, no external calls at run time; runs finish in about a second on 256 MB

### Who uses it

- **AI agents and MCP clients** that need "is it a working day in China?" or "what date is 10 working days after X?"
- **Logistics, cross-border e-commerce and supplier management**: factory closures, ETA and lead-time calculation around Chinese New Year and Golden Week
- **Finance and payroll**: settlement days, statutory holiday pay
- **Marketing and content calendars**: lunar festivals and solar terms

### Operations

| `operation` | Input | Output (one row each) |
|---|---|---|
| `check` (default) | `dates`: list of `YYYY-MM-DD` (max 1000) | one row per date |
| `range` | `startDate`, `endDate`, optional `maxDays` (default 366, max 3660) | one row per day |
| `addWorkdays` | `startDate`, `days` (−2000…2000) | 1 row with `resultDate` |
| `countWorkdays` | `startDate`, `endDate` (inclusive) | 1 row with counts |
| `holidays` | `year` | one row per holiday period |
| `solarTerms` | `year` | 24 rows |

`includeLunar` (default `true`) adds the lunar block to day rows.

### Example: check dates

Input:

```json
{ "operation": "check", "dates": ["2026-10-01", "2026-10-10", "2027-02-06"] }
```

Output (second row):

```json
{
  "date": "2026-10-10",
  "weekday": 6,
  "weekdayName": "Saturday",
  "isWorkday": true,
  "dayType": "adjusted_workday",
  "holidayName": null,
  "holidayNameZh": null,
  "isStatutoryHoliday": false,
  "solarTerm": null,
  "dataStatus": "official",
  "sourceUrl": "https://www.gov.cn/zhengce/zhengceku/202511/content_7047091.htm",
  "lunar": { "year": 2026, "month": 9, "day": 1, "isLeapMonth": false, "text": "九月初一", "ganzhiYear": "丙午", "zodiac": "马" }
}
```

`dayType` is one of `workday`, `weekend`, `holiday`, `adjusted_workday`. `isWorkday` is `true` for `workday` and `adjusted_workday`.

### Example: add working days

```json
{ "operation": "addWorkdays", "startDate": "2026-09-30", "days": 10 }
```

```json
{ "operation": "addWorkdays", "startDate": "2026-09-30", "days": 10, "resultDate": "2026-10-20", "resultWeekdayName": "Tuesday", "dataStatus": "official" }
```

`days: 0` returns `startDate` if it is a working day, otherwise the next working day. Negative values count backwards.

### Example: count working days

```json
{ "operation": "countWorkdays", "startDate": "2026-01-01", "endDate": "2026-12-31" }
```

```json
{ "operation": "countWorkdays", "startDate": "2026-01-01", "endDate": "2026-12-31", "calendarDays": 365, "workdays": 248, "adjustedWorkdays": 6, "weekendDays": 84, "holidayDays": 33, "dataStatus": "official" }
```

### Example: holiday periods

```json
{ "operation": "holidays", "year": 2026 }
```

```json
{ "year": 2026, "name": "Spring Festival", "nameZh": "春节", "startDate": "2026-02-15", "endDate": "2026-02-23", "daysOff": 9, "adjustedWorkdays": ["2026-02-14", "2026-02-28"], "dataStatus": "official", "notice": "国办发明电〔2025〕7号", "sourceUrl": "https://www.gov.cn/zhengce/zhengceku/202511/content_7047091.htm" }
```

### Example: solar terms

```json
{ "operation": "solarTerms", "year": 2026 }
```

```json
{ "year": 2026, "name": "Cold Dew", "nameZh": "寒露", "date": "2026-10-08", "datetimeBeijing": "2026-10-08T14:29:17+08:00", "datetimeUtc": "2026-10-08T06:29:17+00:00" }
```

### Data sources and accuracy

- Holiday and make-up workday schedules: annual notices of the General Office of the State Council (国务院办公厅关于部分节假日安排的通知) on www.gov.cn. Each row carries the notice URL.
  - 2024: 国办发明电〔2023〕7号, 2025: 国办发明电〔2024〕12号, 2026: 国办发明电〔2025〕7号
- Statutory holiday definition: the *National Measures on Holidays* as amended by State Council Decree No. 795 (effective 2025-01-01): 13 days from 2025 (11 days before).
- Every day of 2024–2026 is cross-checked in the test suite against an independent open-source dataset.
- **Years without a published schedule** (for example 2027, until the State Council publishes it, usually in late October or November): statutory holidays and weekends only. Bridge days and make-up workdays are unknown, so rows are flagged `"dataStatus": "estimated"`. The Actor is updated after each new notice.
- Lunar dates and solar terms are computed astronomically (Beijing time, UTC+8).
- Mainland China only. Hong Kong, Macau and Taiwan have different holidays.

### Pricing

Pay per event:

- **Actor start**: charged once per run
- **Result**: per row in the dataset (one per date for `check` and `range`, one per calculation, one per holiday period or solar term)

Set a maximum charge per run and the Actor stops cleanly at the limit. Invalid input fails immediately and produces no results.

### Use from an AI agent (MCP)

The Actor has a single clear purpose and a typed input schema, so MCP clients can call it directly through the Apify MCP server. Typical prompts: *"Is 2026-10-10 a working day in China?"*, *"Add 15 Chinese working days to 2026-09-25"*.

### Limits

- `check`: 1000 dates per run. `range`: up to 3660 days. `addWorkdays`: ±2000 working days. Years 1950–2099.
- This is a reference tool, not legal advice. Local governments and individual employers can set extra rules.

### Changelog

- 0.1: first release. Official schedules for 2024–2026, lunar calendar, solar terms, add/count working days.

# Actor input Schema

## `operation` (type: `string`):

check = classify specific dates; range = one row per day between startDate and endDate; addWorkdays = date that is N China working days after/before startDate; countWorkdays = number of working days between two dates (inclusive); holidays = official holiday periods for a year; solarTerms = the 24 solar terms of a year with exact Beijing time.

## `dates` (type: `array`):

Dates in YYYY-MM-DD format. Up to 1000 per run.

## `startDate` (type: `string`):

YYYY-MM-DD

## `endDate` (type: `string`):

YYYY-MM-DD, inclusive

## `days` (type: `integer`):

Positive moves forward, negative moves backward. 0 returns startDate if it is a working day, otherwise the next working day.

## `year` (type: `integer`):

Gregorian year, 1950-2099.

## `includeLunar` (type: `boolean`):

Add the Chinese lunar date, ganzhi year and zodiac to day rows.

## `maxDays` (type: `integer`):

Safety cap for the range operation (each day is one billed result).

## Actor input object example

```json
{
  "operation": "check",
  "dates": [
    "2026-10-01",
    "2026-10-10",
    "2027-02-06"
  ],
  "includeLunar": true,
  "maxDays": 366
}
```

# Actor output Schema

## `results` (type: `string`):

All dataset items produced by the run (every operation).

## `days` (type: `string`):

Per-day classification: working day, weekend, statutory holiday or make-up workday (调休), plus lunar date and solar term.

## `calculations` (type: `string`):

Result date of adding N China working days, or the working/weekend/holiday day counts between two dates.

## `holidays` (type: `string`):

Official State Council holiday periods of a year with their make-up workdays and source notice.

## `solarTerms` (type: `string`):

The 24 solar terms of a year with exact Beijing and UTC time.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "operation": "check",
    "dates": [
        "2026-10-01",
        "2026-10-10",
        "2027-02-06"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("awake_froghopper/china-workday-calendar").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "operation": "check",
    "dates": [
        "2026-10-01",
        "2026-10-10",
        "2027-02-06",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("awake_froghopper/china-workday-calendar").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "operation": "check",
  "dates": [
    "2026-10-01",
    "2026-10-10",
    "2027-02-06"
  ]
}' |
apify call awake_froghopper/china-workday-calendar --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,awake_froghopper/china-workday-calendar"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ibhaNxtDbWpI8bTKg/builds/tNMskPm8LiuBVLNno/openapi.json
