|
14 | 14 | from typing import Optional
|
15 | 15 |
|
16 | 16 | from holidays.calendars.custom import _CustomCalendar
|
17 |
| -from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, SEP, OCT, NOV |
| 17 | +from holidays.calendars.gregorian import JAN, FEB, MAR, APR, MAY, JUN, SEP, OCT, NOV, DEC |
18 | 18 |
|
19 | 19 | CHINESE_CALENDAR = "CHINESE_CALENDAR"
|
20 | 20 | KOREAN_CALENDAR = "KOREAN_CALENDAR"
|
@@ -1307,6 +1307,24 @@ class _ChineseLunisolar:
|
1307 | 1307 | 2053: (FEB, 18),
|
1308 | 1308 | }
|
1309 | 1309 |
|
| 1310 | + WINTER_SOLSTICE_THRESHOLDS: dict[str, dict[str, dict[int, int]]] = { |
| 1311 | + # UTC+7. |
| 1312 | + VIETNAMESE_CALENDAR: { |
| 1313 | + "dec_21": {0: 1980, 1: 2017, 2: 2050, 3: 2083}, |
| 1314 | + "dec_23": {3: 1943}, |
| 1315 | + }, |
| 1316 | + # UTC+8. |
| 1317 | + CHINESE_CALENDAR: { |
| 1318 | + "dec_21": {0: 1988, 1: 2021, 2: 2058, 3: 2091}, |
| 1319 | + "dec_23": {3: 1947}, |
| 1320 | + }, |
| 1321 | + # UTC+9. |
| 1322 | + KOREAN_CALENDAR: { |
| 1323 | + "dec_21": {0: 1992, 1: 2029, 2: 2062, 3: 2099}, |
| 1324 | + "dec_23": {3: 1955}, |
| 1325 | + }, |
| 1326 | + } |
| 1327 | + |
1310 | 1328 | def __init__(self, calendar: str = CHINESE_CALENDAR) -> None:
|
1311 | 1329 | self.__verify_calendar(calendar)
|
1312 | 1330 | self.__calendar = calendar
|
@@ -1359,6 +1377,26 @@ def lunar_new_year_date(self, year: int, calendar=None) -> tuple[Optional[date],
|
1359 | 1377 | def mid_autumn_date(self, year: int, calendar=None) -> tuple[Optional[date], bool]:
|
1360 | 1378 | return self._get_holiday(MID_AUTUMN, year, calendar)
|
1361 | 1379 |
|
| 1380 | + def winter_solstice_date(self, year: int, calendar=None) -> tuple[Optional[date], bool]: |
| 1381 | + """Return Winter Solstice (22nd solar term in Chinese Lunisolar calendar) date. |
| 1382 | +
|
| 1383 | + !!! note "Note" |
| 1384 | + This approximation is reliable for 1941-2099 years. |
| 1385 | + """ |
| 1386 | + calendar = calendar or self.__calendar |
| 1387 | + self.__verify_calendar(calendar) |
| 1388 | + |
| 1389 | + thresholds = self.WINTER_SOLSTICE_THRESHOLDS[calendar] |
| 1390 | + year_mod = year % 4 |
| 1391 | + if year >= thresholds["dec_21"][year_mod]: |
| 1392 | + day = 21 |
| 1393 | + elif year <= thresholds["dec_23"].get(year_mod, 0): |
| 1394 | + day = 23 |
| 1395 | + else: |
| 1396 | + day = 22 |
| 1397 | + |
| 1398 | + return date(year, DEC, day), not (1941 <= year <= 2099) |
| 1399 | + |
1362 | 1400 |
|
1363 | 1401 | class _CustomChineseHolidays(_CustomCalendar, _ChineseLunisolar):
|
1364 | 1402 | pass
|
0 commit comments