Pure-Python library for handling Japanese public holidays based on official Cabinet Office data
npx @tessl/cli install tessl/pypi-jpholiday@1.0.00
# JPHoliday
1
2
A comprehensive Python library for handling Japanese public holidays based on official data from the Japanese Cabinet Office. JPHoliday enables developers to easily check if specific dates are holidays, retrieve holiday names, get all holidays for a given year or month, and filter holidays within date ranges. The library supports both datetime.date and datetime.datetime objects, includes accurate holiday calculations through 2026 (with extended calculations beyond that), implements substitute holidays for holidays falling on weekends, and provides extensibility through custom holiday checkers.
3
4
## Package Information
5
6
- **Package Name**: jpholiday
7
- **Language**: Python
8
- **Installation**: `pip install jpholiday`
9
10
## Core Imports
11
12
```python
13
import jpholiday
14
```
15
16
Class-based API:
17
18
```python
19
from jpholiday import JPHoliday
20
```
21
22
Custom holiday checker interface:
23
24
```python
25
from jpholiday import OriginalHolidayCheckerInterface
26
```
27
28
Holiday model:
29
30
```python
31
from jpholiday.model.holiday import Holiday
32
```
33
34
Exceptions:
35
36
```python
37
from jpholiday.exception import JPHolidayTypeError
38
```
39
40
## Basic Usage
41
42
```python
43
import jpholiday
44
import datetime
45
46
# Check if a date is a holiday
47
is_holiday = jpholiday.is_holiday(datetime.date(2024, 1, 1)) # True
48
print(is_holiday)
49
50
# Get holiday name
51
holiday_name = jpholiday.is_holiday_name(datetime.date(2024, 1, 1)) # '元日'
52
print(holiday_name)
53
54
# Get all holidays for a year
55
holidays_2024 = jpholiday.year_holidays(2024)
56
for date, name in holidays_2024:
57
print(f"{date}: {name}")
58
59
# Get holidays in a date range
60
holidays_jan = jpholiday.between(
61
datetime.date(2024, 1, 1),
62
datetime.date(2024, 1, 31)
63
)
64
for date, name in holidays_jan:
65
print(f"{date}: {name}")
66
```
67
68
Class-based usage:
69
70
```python
71
from jpholiday import JPHoliday
72
import datetime
73
74
jpholiday = JPHoliday()
75
76
# Get Holiday objects instead of tuples
77
holidays = jpholiday.holidays(datetime.date(2024, 1, 1))
78
for holiday in holidays:
79
print(f"{holiday.date}: {holiday.name}")
80
81
# Check if date is holiday
82
is_holiday = jpholiday.is_holiday(datetime.date(2024, 1, 1))
83
print(is_holiday)
84
```
85
86
## Capabilities
87
88
### Holiday Checking Functions
89
90
Check if specific dates are Japanese public holidays and retrieve holiday names.
91
92
```python { .api }
93
from typing import Union, Optional
94
import datetime
95
96
def is_holiday(date: Union[datetime.date, datetime.datetime]) -> bool:
97
"""
98
Check if a given date is a Japanese public holiday.
99
100
Args:
101
date: Date to check, supports both datetime.date and datetime.datetime
102
103
Returns:
104
True if the date is a holiday, False otherwise
105
106
Raises:
107
JPHolidayTypeError: If date is not datetime.date or datetime.datetime
108
"""
109
110
def is_holiday_name(date: Union[datetime.date, datetime.datetime]) -> Optional[str]:
111
"""
112
Get the holiday name for a given date.
113
114
Args:
115
date: Date to check, supports both datetime.date and datetime.datetime
116
117
Returns:
118
Holiday name as string if the date is a holiday, None otherwise
119
120
Raises:
121
JPHolidayTypeError: If date is not datetime.date or datetime.datetime
122
"""
123
```
124
125
### Holiday Collection Functions
126
127
Retrieve collections of holidays for years, months, or date ranges.
128
129
```python { .api }
130
import datetime
131
132
def year_holidays(year: int) -> list[tuple[datetime.date, str]]:
133
"""
134
Get all holidays for a given year.
135
136
Args:
137
year: Year to get holidays for
138
139
Returns:
140
List of (date, name) tuples for all holidays in the year
141
"""
142
143
def month_holidays(year: int, month: int) -> list[tuple[datetime.date, str]]:
144
"""
145
Get all holidays for a given month.
146
147
Args:
148
year: Year containing the month
149
month: Month to get holidays for (1-12)
150
151
Returns:
152
List of (date, name) tuples for all holidays in the month
153
"""
154
155
def between(
156
start_date: Union[datetime.date, datetime.datetime],
157
end_date: Union[datetime.date, datetime.datetime]
158
) -> list[tuple[datetime.date, str]]:
159
"""
160
Get holidays between two dates (inclusive).
161
162
Args:
163
start_date: Start of date range
164
end_date: End of date range
165
166
Returns:
167
List of (date, name) tuples for all holidays in the range
168
169
Raises:
170
JPHolidayTypeError: If dates are not datetime.date or datetime.datetime
171
"""
172
```
173
174
### Custom Holiday Management
175
176
Register and unregister custom holiday checkers to extend the library with additional holidays.
177
178
```python { .api }
179
from jpholiday import OriginalHolidayCheckerInterface
180
181
def register(checker: OriginalHolidayCheckerInterface):
182
"""
183
Register a custom holiday checker to add additional holidays.
184
185
Args:
186
checker: Custom holiday checker implementing OriginalHolidayCheckerInterface
187
"""
188
189
def unregister(checker: OriginalHolidayCheckerInterface):
190
"""
191
Unregister a previously registered custom holiday checker.
192
193
Args:
194
checker: Custom holiday checker to remove
195
"""
196
```
197
198
### JPHoliday Class API
199
200
Object-oriented interface providing the same functionality with Holiday objects instead of tuples.
201
202
```python { .api }
203
from typing import Union, Iterator
204
import datetime
205
from jpholiday.model.holiday import Holiday
206
from jpholiday import OriginalHolidayCheckerInterface
207
208
class JPHoliday:
209
"""
210
Main class for Japanese holiday operations with caching and custom checker support.
211
"""
212
213
def __init__(self):
214
"""Create a new JPHoliday instance with in-memory cache and registry."""
215
216
def holidays(self, date: Union[datetime.date, datetime.datetime]) -> list[Holiday]:
217
"""
218
Get Holiday objects for a given date.
219
220
Args:
221
date: Date to check
222
223
Returns:
224
List of Holiday objects for the date (empty if no holidays)
225
226
Raises:
227
JPHolidayTypeError: If date is not datetime.date or datetime.datetime
228
"""
229
230
def is_holiday(self, date: Union[datetime.date, datetime.datetime]) -> bool:
231
"""
232
Check if a given date is a holiday.
233
234
Args:
235
date: Date to check
236
237
Returns:
238
True if the date is a holiday, False otherwise
239
"""
240
241
def year_holidays(self, year: int) -> list[Holiday]:
242
"""
243
Get all holidays for a year as Holiday objects.
244
245
Args:
246
year: Year to get holidays for
247
248
Returns:
249
List of Holiday objects for the year
250
"""
251
252
def iter_year_holidays(self, year: int) -> Iterator[Holiday]:
253
"""
254
Get iterator over holidays for a year.
255
256
Args:
257
year: Year to get holidays for
258
259
Returns:
260
Iterator yielding Holiday objects
261
"""
262
263
def month_holidays(self, year: int, month: int) -> list[Holiday]:
264
"""
265
Get all holidays for a month as Holiday objects.
266
267
Args:
268
year: Year containing the month
269
month: Month to get holidays for (1-12)
270
271
Returns:
272
List of Holiday objects for the month
273
"""
274
275
def iter_month_holidays(self, year: int, month: int) -> Iterator[Holiday]:
276
"""
277
Get iterator over holidays for a month.
278
279
Args:
280
year: Year containing the month
281
month: Month to get holidays for (1-12)
282
283
Returns:
284
Iterator yielding Holiday objects
285
"""
286
287
def between(
288
self,
289
start_date: Union[datetime.date, datetime.datetime],
290
end_date: Union[datetime.date, datetime.datetime]
291
) -> list[Holiday]:
292
"""
293
Get holidays between two dates as Holiday objects.
294
295
Args:
296
start_date: Start of date range
297
end_date: End of date range
298
299
Returns:
300
List of Holiday objects in the range
301
"""
302
303
def iter_between(
304
self,
305
start_date: Union[datetime.date, datetime.datetime],
306
end_date: Union[datetime.date, datetime.datetime]
307
) -> Iterator[Holiday]:
308
"""
309
Get iterator over holidays between two dates.
310
311
Args:
312
start_date: Start of date range
313
end_date: End of date range
314
315
Returns:
316
Iterator yielding Holiday objects
317
"""
318
319
def register(self, checker: OriginalHolidayCheckerInterface):
320
"""
321
Register a custom holiday checker.
322
323
Args:
324
checker: Custom holiday checker to register
325
"""
326
327
def unregister(self, checker: OriginalHolidayCheckerInterface):
328
"""
329
Unregister a custom holiday checker.
330
331
Args:
332
checker: Custom holiday checker to unregister
333
"""
334
```
335
336
## Types
337
338
```python { .api }
339
import dataclasses
340
import datetime
341
from abc import ABC, abstractmethod
342
343
@dataclasses.dataclass(frozen=True)
344
class Holiday:
345
"""
346
Immutable dataclass representing a Japanese holiday.
347
"""
348
date: datetime.date # The holiday date
349
name: str # The holiday name in Japanese
350
351
def to_tuple(self) -> tuple[datetime.date, str]:
352
"""
353
Convert to (date, name) tuple for compatibility with functional API.
354
355
Returns:
356
Tuple of (date, name)
357
"""
358
359
class OriginalHolidayCheckerInterface(ABC):
360
"""
361
Abstract base class for implementing custom holiday checkers.
362
"""
363
364
@abstractmethod
365
def is_holiday(self, date: datetime.date) -> bool:
366
"""
367
Check if the given date is a holiday according to this checker.
368
369
Args:
370
date: Date to check
371
372
Returns:
373
True if the date is a holiday, False otherwise
374
"""
375
376
@abstractmethod
377
def holiday_name(self, date: datetime.date) -> str:
378
"""
379
Get the holiday name for the given date.
380
381
Args:
382
date: Date to get holiday name for
383
384
Returns:
385
Holiday name as string
386
"""
387
388
# Exception types
389
class JPHolidayException(Exception):
390
"""Base exception for jpholiday library."""
391
pass
392
393
class JPHolidayTypeError(JPHolidayException):
394
"""Raised when invalid types are passed to functions."""
395
pass
396
```
397
398
## Custom Holiday Example
399
400
```python
401
import jpholiday
402
from jpholiday import OriginalHolidayCheckerInterface
403
import datetime
404
405
# Define a custom holiday checker
406
class CompanyHolidayChecker(OriginalHolidayCheckerInterface):
407
def is_holiday(self, date: datetime.date) -> bool:
408
# Company founding day
409
if date == datetime.date(date.year, 3, 15):
410
return True
411
return False
412
413
def holiday_name(self, date: datetime.date) -> str:
414
return '創立記念日'
415
416
# Register the custom checker
417
custom_checker = CompanyHolidayChecker()
418
jpholiday.register(custom_checker)
419
420
# Now company holidays are included
421
print(jpholiday.is_holiday(datetime.date(2024, 3, 15))) # True
422
print(jpholiday.is_holiday_name(datetime.date(2024, 3, 15))) # '創立記念日'
423
424
# Unregister when done
425
jpholiday.unregister(custom_checker)
426
```
427
428
## Error Handling
429
430
The library validates input types and raises `JPHolidayTypeError` for invalid inputs:
431
432
```python
433
import jpholiday
434
from jpholiday.exception import JPHolidayTypeError
435
436
try:
437
# This will raise JPHolidayTypeError
438
jpholiday.is_holiday("2024-01-01") # String instead of date
439
except JPHolidayTypeError as e:
440
print(f"Type error: {e}")
441
442
try:
443
# This will raise JPHolidayTypeError
444
jpholiday.is_holiday(20240101) # Integer instead of date
445
except JPHolidayTypeError as e:
446
print(f"Type error: {e}")
447
```
448
449
## Import Patterns
450
451
```python
452
# Functional API (most common)
453
import jpholiday
454
jpholiday.is_holiday(datetime.date(2024, 1, 1))
455
456
# Class-based API
457
from jpholiday import JPHoliday
458
jp = JPHoliday()
459
jp.is_holiday(datetime.date(2024, 1, 1))
460
461
# Custom holiday implementation
462
from jpholiday import OriginalHolidayCheckerInterface
463
464
# Working with Holiday objects
465
from jpholiday.model.holiday import Holiday
466
467
# Exception handling
468
from jpholiday.exception import JPHolidayTypeError, JPHolidayException
469
```