Repository: vacanza/holidays
Pull request #2081 (2024-10-26 09:42:20)

Update Thailand holidays in 2025
<!--
  Thanks for contributing to holidays!
-->

## Proposed change

<!--
  Describe the big picture of your changes.
  Don't forget to link your PR to an existing issue if any.
-->

Update Thailand holidays in 2025, as well as refractoring Thailand testcases to modern standards.
 - "Royal Ploughing Ceremony" date for 2025 is now confirmed as [May 9, 2025](https://www.myhora.com/ปฏิทิน/วันพืชมงคล.aspx).
 - `SUN-MON-TUE` format for "Songkran" holidays do indeed has in-lieu observance on `WED` as seen in [2014](https://hilight.kapook.com/view/88096) and [2025](https://www.thairath.co.th/lifestyle/life/2812118), and has been fixed accordingly.

## Type of change

<!--
  Type of change you want to introduce. Please, check one (1) box only!
  If your PR requires multiple boxes to be checked, most likely it needs to
  be split into multiple PRs.
-->

- [ ] New country/market holidays support (thank you!)
- [x] Supported country/market holidays update (calendar discrepancy fix, localization)
- [ ] Existing code/documentation/test/process quality improvement (best practice, cleanup, refactoring, optimization)
- [ ] Dependency update (version deprecation/pin/upgrade)
- [ ] Bugfix (non-breaking change which fixes an issue)
- [ ] Breaking change (a code change causing existing functionality to break)
- [ ] New feature (new `holidays` functionality in general)

## Checklist

<!--
  Put an `x` in the boxes that apply. You can change them after PR is created.
-->

- [x] I've followed the [contributing guidelines][contributing-guidelines]
- [x] I've run `make pre-commit`, it didn't generate any changes
- [x] I've run `make test`, all tests passed locally

<!--
  Thanks again for your contribution!
-->

[contributing-guidelines]: https://github.com/vacanza/holidays/blob/dev/CONTRIBUTING.rst
[docs]: https://github.com/vacanza/holidays/tree/dev/docs/source


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081)


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/vacanza/holidays/pull/2081?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vacanza) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 100.00%. Comparing base [(`0adc4be`)](https://app.codecov.io/gh/vacanza/holidays/commit/0adc4beb89bed5e08e94fb845cae9da41b3ebd23?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vacanza) to head [(`8f00478`)](https://app.codecov.io/gh/vacanza/holidays/commit/8f0047829f37d0c5094cde41a75c633bdb8bd62f?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vacanza).

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff            @@
##               dev     #2081   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          191       191           
  Lines        11546     11546           
  Branches      1743      1743           
=========================================
  Hits         11546     11546           
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/vacanza/holidays/pull/2081?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vacanza).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=vacanza).

sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081)


KJhellico: In [L614](https://github.com/vacanza/holidays/blob/b308bde5577c1330bc9f62a62cd6956bee8ae5da/tests/countries/test_thailand.py#L614):
```python
            Thailand(categories=GOVERNMENT, years=range(1960, 2024)),
```
everything works correctly (due to auto-expand), but for accuracy:
```suggestion
            Thailand(categories=GOVERNMENT, years=range(1960, 2026)),
```

sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [1 New issue](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081)


PPsyrius: @KJhellico I ended up refactoring all Thailand test cases to modern standards, so additional reviews will be needed here.
sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081)


sonarcloud[bot]: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vacanza_python-holidays&pullRequest=2081&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vacanza_python-holidays&pullRequest=2081&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarCloud](https://sonarcloud.io/dashboard?id=vacanza_python-holidays&pullRequest=2081)



Patch:
diff --git a/holidays/countries/thailand.py b/holidays/countries/thailand.py
index 9ccd2e07..37c99f64 100644
--- a/holidays/countries/thailand.py
+++ b/holidays/countries/thailand.py
@@ -19,11 +19,11 @@ from holidays.groups import InternationalHolidays, StaticHolidays, ThaiCalendarH
 from holidays.observed_holiday_base import (
     ObservedHolidayBase,
     SAT_TO_NEXT_MON,
-    SAT_TO_NEXT_TUE,
-    THU_FRI_TO_NEXT_MON,
+    THU_FRI_TO_NEXT_WORKDAY,
     SAT_SUN_TO_NEXT_MON,
     SAT_SUN_TO_NEXT_TUE,
     SAT_SUN_TO_NEXT_MON_TUE,
+    SAT_SUN_TO_NEXT_WORKDAY,
 )
 
 
@@ -39,6 +39,7 @@ class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiC
             - https://resolution.soc.go.th/?prep_id=99159317
             - https://resolution.soc.go.th/?prep_id=196007
             - https://github.com/vacanza/holidays/pull/929
+            - https://www.thairath.co.th/lifestyle/life/2812118
         - [New Year's Day]
             `wikisource.org <http://tiny.cc/wa_wiki_thai_newyear_2483>`_
         - [National Children's Day]
@@ -95,6 +96,7 @@ class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiC
             https://dl.parliament.go.th/handle/20.500.13072/92816
             https://e-manage.mju.ac.th/timeline_detail.aspx?key=MTk4
             https://resolution.soc.go.th/PDF_UPLOAD/2510/932141.pdf
+            https://www.myhora.com/ปฏิทิน/วันพืชมงคล.aspx
         - [Royal Thai Armed Forces Day]
             `<https://th.wikipedia.org/wiki/วันกองทัพไทย>`_
         - [Teacher's Day]
@@ -115,7 +117,7 @@ class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiC
             Applied Automatically for Workday if on Weekends: 2001-Present
 
     Limitations:
-        - This is only 100% accurate for 1997-2024; any future dates are up to the
+        - This is only 100% accurate for 1997-2025; any future dates are up to the
           Royal Thai Government Gazette which updates on a year-by-year basis.
 
         - Approx. date only goes as far back as 1941 (B.E. 2484) as the Thai
@@ -129,8 +131,6 @@ class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiC
         - Royal Ploughing Ceremony Day is date is announced on an annual basis
           by the Court Astrologers, thus need an annual update to the library here
 
-        - This doesn't cover Thai regional public holidays yet, only stubs added
-
     Country created by: `arkid15r <https://github.com/arkid15r>`__
 
     Country maintained by: `PPsyrius <https://github.com/PPsyrius>`__
@@ -221,15 +221,16 @@ class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiC
 
             # วันหยุดชดเชยวันสงกรานต์
             # If Songkran happened to be held on the weekends, only one in-lieu
-            #   public holiday is added, No in lieus for SUN-MON-TUE case.
+            #   public holiday is added.
             #   - CASE 1: THU-FRI-SAT -> 1 in-lieu on MON
             #   - CASE 2: FRI-SAT-SUN -> 1 in-lieu on MON
             #   - CASE 3: SAT-SUN-MON -> 1 in-lieu on TUE
+            #   - CASE 4: SUN-MON-TUE -> 1 in-lieu on WED
             # See in lieu logic in `_add_observed(dt: date)`.
             # Status: In Use.
 
             if self._year >= 1995:
-                self._add_observed(dt, rule=THU_FRI_TO_NEXT_MON + SAT_TO_NEXT_TUE)
+                self._add_observed(dt, rule=THU_FRI_TO_NEXT_WORKDAY + SAT_SUN_TO_NEXT_WORKDAY)
 
         # วันแรงงานแห่งชาติ
         # Status: In-Use.
@@ -433,17 +434,13 @@ class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiC
         # Status: In-Use.
 
         # Makha Bucha.
-        makha_bucha_date = self._add_makha_bucha(tr("วันมาฆบูชา"))
-        if makha_bucha_date:
-            self._add_observed(makha_bucha_date)
+        self._add_observed(self._add_makha_bucha(tr("วันมาฆบูชา")))
 
         # วันวิสาขบูชา
         # Status: In-Use.
 
         # Visakha Bucha.
-        visakha_bucha_date = self._add_visakha_bucha(tr("วันวิสาขบูชา"))
-        if visakha_bucha_date:
-            self._add_observed(visakha_bucha_date)
+        self._add_observed(self._add_visakha_bucha(tr("วันวิสาขบูชา")))
 
         # วันอาสาฬหบูชา
         # Status: In-Use.
@@ -452,9 +449,9 @@ class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiC
         #  - CASE 3: SUN-MON -> 1 in-lieu on TUE
 
         # Asarnha Bucha.
-        asarnha_bucha_date = self._add_asarnha_bucha(tr("วันอาสาฬหบูชา"))
-        if asarnha_bucha_date:
-            self._add_observed(asarnha_bucha_date, rule=SAT_SUN_TO_NEXT_MON_TUE)
+        self._add_observed(
+            self._add_asarnha_bucha(tr("วันอาสาฬหบูชา")), rule=SAT_SUN_TO_NEXT_MON_TUE
+        )
 
         # วันเข้าพรรษา
         # Status: In-Use.
@@ -463,9 +460,7 @@ class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiC
         #  - CASE 3: SUN-MON -> 1 in-lieu on TUE
 
         # Buddhist Lent Day.
-        khao_phansa_date = self._add_khao_phansa(tr("วันเข้าพรรษา"))
-        if khao_phansa_date:
-            self._add_observed(khao_phansa_date, rule=SAT_TO_NEXT_MON)
+        self._add_observed(self._add_khao_phansa(tr("วันเข้าพรรษา")), rule=SAT_TO_NEXT_MON)
 
     def _populate_armed_forces_holidays(self):
         # วันกองทัพไทย
@@ -525,8 +520,9 @@ class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiC
         # Is dated on an annual basis by the Royal Palace, always on weekdays.
         # For historic research, วันเกษตรแห่งชาติ (National Agricultural Day) also concides with
         #   this from 1966 onwards. For earlier records the date was refered as วันแรกนาขวัญ.
-        # This isn't even fixed even by the Thai Lunar Calendar, but instead
-        #   by Court Astrologers; All chosen dates are all in the first three weeks of May.
+        # This isn't even fixed even by the Thai Lunar Calendar besides being in Month 6
+        #   to concides with the rainy season, but instead by Court Astrologers; All chosen dates
+        #   so far are all in the first three weeks of May.
         # *** NOTE: only observed by government sectors.
         # TODO: Update this annually around Dec of each year.
 
@@ -597,8 +593,9 @@ class Thailand(ObservedHolidayBase, InternationalHolidays, StaticHolidays, ThaiC
             2022: (MAY, 13),
             2023: (MAY, 17),
             2024: (MAY, 10),
+            2025: (MAY, 9),
         }
-        if 1960 <= self._year <= 2024 and self._year != 1999:
+        if 1960 <= self._year <= 2025 and self._year != 1999:
             self._add_observed(
                 # Royal Ploughing Ceremony.
                 self._add_holiday(tr("วันพืชมงคล"), raeknakhwan_dates.get(self._year, (MAY, 13)))
diff --git a/snapshots/countries/TH_COMMON.json b/snapshots/countries/TH_COMMON.json
index 429cdc34..debc0c28 100644
--- a/snapshots/countries/TH_COMMON.json
+++ b/snapshots/countries/TH_COMMON.json
@@ -1287,6 +1287,7 @@
     "2003-04-13": "Songkran Festival",
     "2003-04-14": "Songkran Festival",
     "2003-04-15": "Songkran Festival",
+    "2003-04-16": "Songkran Festival (in lieu)",
     "2003-05-01": "National Labor Day",
     "2003-05-05": "Coronation Day",
     "2003-05-08": "Royal Ploughing Ceremony",
@@ -1463,6 +1464,7 @@
     "2008-04-13": "Songkran Festival",
     "2008-04-14": "Songkran Festival",
     "2008-04-15": "Songkran Festival",
+    "2008-04-16": "Songkran Festival (in lieu)",
     "2008-05-01": "National Labor Day",
     "2008-05-05": "Coronation Day",
     "2008-05-09": "Royal Ploughing Ceremony",
@@ -1677,6 +1679,7 @@
     "2014-04-13": "Songkran Festival",
     "2014-04-14": "Songkran Festival",
     "2014-04-15": "Songkran Festival",
+    "2014-04-16": "Songkran Festival (in lieu)",
     "2014-05-01": "National Labor Day",
     "2014-05-05": "Coronation Day",
     "2014-05-09": "Royal Ploughing Ceremony",
@@ -2087,9 +2090,11 @@
     "2025-04-13": "Songkran Festival",
     "2025-04-14": "Songkran Festival",
     "2025-04-15": "Songkran Festival",
+    "2025-04-16": "Songkran Festival (in lieu)",
     "2025-05-01": "National Labor Day",
     "2025-05-04": "Coronation Day",
     "2025-05-05": "Coronation Day (in lieu)",
+    "2025-05-09": "Royal Ploughing Ceremony",
     "2025-05-11": "Visakha Bucha",
     "2025-05-12": "Visakha Bucha (in lieu)",
     "2025-06-03": "HM Queen Suthida's Birthday",
@@ -2301,6 +2306,7 @@
     "2031-04-13": "Songkran Festival",
     "2031-04-14": "Songkran Festival",
     "2031-04-15": "Songkran Festival",
+    "2031-04-16": "Songkran Festival (in lieu)",
     "2031-05-01": "National Labor Day",
     "2031-05-04": "Coronation Day",
     "2031-05-05": "Coronation Day (in lieu)",
@@ -2480,6 +2486,7 @@
     "2036-04-13": "Songkran Festival",
     "2036-04-14": "Songkran Festival",
     "2036-04-15": "Songkran Festival",
+    "2036-04-16": "Songkran Festival (in lieu)",
     "2036-05-01": "National Labor Day",
     "2036-05-04": "Coronation Day",
     "2036-05-05": "Coronation Day (in lieu)",
@@ -2691,6 +2698,7 @@
     "2042-04-13": "Songkran Festival",
     "2042-04-14": "Songkran Festival",
     "2042-04-15": "Songkran Festival",
+    "2042-04-16": "Songkran Festival (in lieu)",
     "2042-05-01": "National Labor Day",
     "2042-05-04": "Coronation Day",
     "2042-05-05": "Coronation Day (in lieu)",


Test patch:
diff --git a/tests/calendars/test_thai.py b/tests/calendars/test_thai.py
index c2a2a380..af114fff 100644
--- a/tests/calendars/test_thai.py
+++ b/tests/calendars/test_thai.py
@@ -31,10 +31,26 @@ class TestThaiLunisolarCalendar(unittest.TestCase):
         asarnha_bucha_year_date = {
             self.calendar.START_YEAR - 1: None,
             self.calendar.END_YEAR + 1: None,
+            2010: date(2010, JUL, 26),
+            2011: date(2011, JUL, 15),
+            2012: date(2012, AUG, 2),
+            2013: date(2013, JUL, 22),
+            2014: date(2014, JUL, 11),
+            2015: date(2015, JUL, 30),
+            2016: date(2016, JUL, 19),
+            2017: date(2017, JUL, 8),
+            2018: date(2018, JUL, 27),
+            2019: date(2019, JUL, 16),
+            2020: date(2020, JUL, 5),
+            2021: date(2021, JUL, 24),
             2022: date(2022, JUL, 13),
             2023: date(2023, AUG, 1),
             2024: date(2024, JUL, 20),
             2025: date(2025, JUL, 10),
+            2026: date(2026, JUL, 29),
+            2027: date(2027, JUL, 18),
+            2028: date(2028, JUL, 6),
+            2029: date(2029, JUL, 25),
             2030: date(2030, JUL, 14),
             2040: date(2040, JUL, 23),
             2050: date(2050, AUG, 2),
@@ -148,10 +164,26 @@ class TestThaiLunisolarCalendar(unittest.TestCase):
         khao_phansa_year_date = {
             self.calendar.START_YEAR - 1: None,
             self.calendar.END_YEAR + 1: None,
+            2010: date(2010, JUL, 27),
+            2011: date(2011, JUL, 16),
+            2012: date(2012, AUG, 3),
+            2013: date(2013, JUL, 23),
+            2014: date(2014, JUL, 12),
+            2015: date(2015, JUL, 31),
+            2016: date(2016, JUL, 20),
+            2017: date(2017, JUL, 9),
+            2018: date(2018, JUL, 28),
+            2019: date(2019, JUL, 17),
+            2020: date(2020, JUL, 6),
+            2021: date(2021, JUL, 25),
             2022: date(2022, JUL, 14),
             2023: date(2023, AUG, 2),
             2024: date(2024, JUL, 21),
             2025: date(2025, JUL, 11),
+            2026: date(2026, JUL, 30),
+            2027: date(2027, JUL, 19),
+            2028: date(2028, JUL, 7),
+            2029: date(2029, JUL, 26),
             2030: date(2030, JUL, 15),
             2040: date(2040, JUL, 24),
             2050: date(2050, AUG, 3),
@@ -205,10 +237,26 @@ class TestThaiLunisolarCalendar(unittest.TestCase):
         makha_bucha_year_date = {
             self.calendar.START_YEAR - 1: None,
             self.calendar.END_YEAR + 1: None,
+            2010: date(2010, FEB, 28),
+            2011: date(2011, FEB, 18),
+            2012: date(2012, MAR, 7),
+            2013: date(2013, FEB, 25),
+            2014: date(2014, FEB, 14),
+            2015: date(2015, MAR, 4),
+            2016: date(2016, FEB, 22),
+            2017: date(2017, FEB, 11),
+            2018: date(2018, MAR, 1),
+            2019: date(2019, FEB, 19),
+            2020: date(2020, FEB, 8),
+            2021: date(2021, FEB, 26),
             2022: date(2022, FEB, 16),
             2023: date(2023, MAR, 6),
             2024: date(2024, FEB, 24),
             2025: date(2025, FEB, 12),
+            2026: date(2026, MAR, 3),
+            2027: date(2027, FEB, 21),
+            2028: date(2028, FEB, 10),
+            2029: date(2029, FEB, 27),
             2030: date(2030, FEB, 17),
             2040: date(2040, FEB, 26),
             2050: date(2050, MAR, 7),
@@ -303,10 +351,26 @@ class TestThaiLunisolarCalendar(unittest.TestCase):
         visakha_bucha_year_date = {
             self.calendar.START_YEAR - 1: None,
             self.calendar.END_YEAR + 1: None,
+            2010: date(2010, MAY, 28),
+            2011: date(2011, MAY, 17),
+            2012: date(2012, JUN, 4),
+            2013: date(2013, MAY, 24),
+            2014: date(2014, MAY, 13),
+            2015: date(2015, JUN, 1),
+            2016: date(2016, MAY, 20),
+            2017: date(2017, MAY, 10),
+            2018: date(2018, MAY, 29),
+            2019: date(2019, MAY, 18),
+            2020: date(2020, MAY, 6),
+            2021: date(2021, MAY, 26),
             2022: date(2022, MAY, 15),
             2023: date(2023, JUN, 3),
             2024: date(2024, MAY, 22),
             2025: date(2025, MAY, 11),
+            2026: date(2026, MAY, 31),
+            2027: date(2027, MAY, 20),
+            2028: date(2028, MAY, 8),
+            2029: date(2029, MAY, 27),
             2030: date(2030, MAY, 16),
             2040: date(2040, MAY, 25),
             2050: date(2050, JUN, 4),
diff --git a/tests/countries/test_thailand.py b/tests/countries/test_thailand.py
index 1ed5df75..6a4ab287 100644
--- a/tests/countries/test_thailand.py
+++ b/tests/countries/test_thailand.py
@@ -20,19 +20,17 @@ from tests.common import CommonCountryTests
 class TestThailand(CommonCountryTests, TestCase):
     @classmethod
     def setUpClass(cls):
-        support_range = list(range(1941, 2059)) + [2158]
+        support_range = range(1941, 2050)
         super().setUpClass(Thailand, years=support_range, years_non_observed=support_range)
 
     def test_country_aliases(self):
         self.assertAliases(Thailand, TH, THA)
 
     def test_no_holidays(self):
-        self.assertNoHolidays(Thailand(years=1940))
-        self.assertNoHolidays(Thailand(years=1958, categories=ARMED_FORCES))
+        self.assertNoHolidays(Thailand(years=1940, categories=(PUBLIC, WORKDAY)))
         self.assertNoHolidays(Thailand(years=1942, categories=BANK))
-        self.assertNoHolidays(Thailand(years=1956, categories=GOVERNMENT))
-        self.assertNoHolidays(Thailand(years=1956, categories=SCHOOL))
-        self.assertNoHolidays(Thailand(years=1940, categories=WORKDAY))
+        self.assertNoHolidays(Thailand(years=1956, categories=(GOVERNMENT, SCHOOL)))
+        self.assertNoHolidays(Thailand(years=1958, categories=ARMED_FORCES))
 
     def test_special_holidays(self):
         dt = (
@@ -117,72 +115,9 @@ class TestThailand(CommonCountryTests, TestCase):
         self.assertHoliday(dt, dt_observed)
         self.assertNoNonObservedHoliday(dt_observed)
 
-    def test_2022_all(self):
-        self.assertHolidays(
-            Thailand(categories=(ARMED_FORCES, GOVERNMENT, PUBLIC, SCHOOL, WORKDAY), years=2022),
-            ("2022-01-01", "วันขึ้นปีใหม่"),
-            ("2022-01-03", "ชดเชยวันขึ้นปีใหม่"),
-            ("2022-01-08", "วันเด็กแห่งชาติ"),
-            ("2022-01-13", "วันการบินแห่งชาติ"),
-            ("2022-01-14", "วันอนุรักษ์ทรัพยากรป่าไม้ของชาติ"),
-            ("2022-01-16", "วันครู"),
-            ("2022-01-17", "วันพ่อขุนรามคำแหงมหาราช"),
-            ("2022-01-18", "วันกองทัพไทย"),
-            ("2022-02-03", "วันทหารผ่านศึก"),
-            ("2022-02-16", "วันมาฆบูชา"),
-            ("2022-02-26", "วันศิลปินแห่งชาติ"),
-            ("2022-03-08", "วันสตรีสากล"),
-            ("2022-04-06", "วันจักรี"),
-            ("2022-04-13", "วันสงกรานต์"),
-            ("2022-04-14", "วันสงกรานต์"),
-            ("2022-04-15", "วันสงกรานต์"),
-            ("2022-05-01", "วันแรงงานแห่งชาติ"),
-            ("2022-05-02", "ชดเชยวันแรงงานแห่งชาติ"),
-            ("2022-05-04", "วันฉัตรมงคล"),
-            ("2022-05-13", "วันพืชมงคล"),
-            ("2022-05-15", "วันวิสาขบูชา"),
-            ("2022-05-16", "ชดเชยวันวิสาขบูชา"),
-            (
-                "2022-06-03",
-                "วันเฉลิมพระชนมพรรษาสมเด็จพระนางเจ้าสุทิดา พัชรสุธาพิมลลักษณ พระบรมราชินี",
-            ),
-            ("2022-07-13", "วันอาสาฬหบูชา"),
-            ("2022-07-14", "วันเข้าพรรษา"),
-            ("2022-07-15", "วันหยุดพิเศษ (เพิ่มเติม)"),
-            (
-                "2022-07-28",
-                (
-                    "วันเฉลิมพระชนมพรรษาพระบาทสมเด็จพระปรเมนทรรามาธิบดี"
-                    "ศรีสินทรมหาวชิราลงกรณ พระวชิรเกล้าเจ้าอยู่หัว"
-                ),
-            ),
-            ("2022-07-29", "วันหยุดพิเศษ (เพิ่มเติม)"),
-            ("2022-08-12", "วันเฉลิมพระชนมพรรษาสมเด็จพระบรมราชชนนีพันปีหลวง; วันแม่แห่งชาติ"),
-            ("2022-08-18", "วันวิทยาศาสตร์แห่งชาติ"),
-            ("2022-09-28", "วันพระราชทานธงชาติไทย"),
-            (
-                "2022-10-13",
-                "วันคล้ายวันสวรรคตพระบาทสมเด็จพระบรมชนกาธิเบศร มหาภูมิพลอดุลยเดชมหาราช บรมนาถบพิตร",
-            ),
-            ("2022-10-14", "วันหยุดพิเศษ (เพิ่มเติม)"),
-            ("2022-10-23", "วันปิยมหาราช"),
-            ("2022-10-24", "ชดเชยวันปิยมหาราช"),
-            ("2022-11-08", "วันลอยกระทง"),
-            (
-                "2022-12-05",
-                (
-                    "วันคล้ายวันเฉลิมพระชนมพรรษาพระบาทสมเด็จพระบรมชนกาธิเบศร "
-                    "มหาภูมิพลอดุลยเดชมหาราช บรมนาถบพิตร; วันชาติ; วันพ่อแห่งชาติ"
-                ),
-            ),
-            ("2022-12-10", "วันรัฐธรรมนูญ"),
-            ("2022-12-12", "ชดเชยวันรัฐธรรมนูญ"),
-            ("2022-12-30", "วันหยุดพิเศษ (เพิ่มเติม)"),
-            ("2022-12-31", "วันสิ้นปี"),
-        )
-
     def test_new_years_day(self):
-        self.assertHoliday(f"{year}-01-01" for year in range(1941, 2058))
+        name = "วันขึ้นปีใหม่"
+        self.assertHolidayName(name, (f"{year}-01-01" for year in range(1941, 2050)))
 
         self.assertNoNonObservedHoliday(
             "2011-01-03",
@@ -195,7 +130,6 @@ class TestThailand(CommonCountryTests, TestCase):
 
     def test_national_childrens_day(self):
         name = "วันเด็กแห่งชาติ"
-
         dt = (
             # First Iteration
             "1955-10-03",
@@ -218,10 +152,11 @@ class TestThailand(CommonCountryTests, TestCase):
             "2025-01-11",
         )
         self.assertHolidayName(name, dt)
-        self.assertNoHolidayName(name, 1954, 1964)
+        self.assertNoHolidayName(name, range(1941, 1955), 1964)
 
     def test_chakri_memorial_day(self):
-        self.assertHoliday(f"{year}-04-06" for year in range(1941, 2058))
+        name = "วันจักรี"
+        self.assertHolidayName(name, (f"{year}-04-06" for year in range(1941, 2050)))
 
         self.assertNoNonObservedHoliday(
             "2013-04-08",
@@ -234,29 +169,29 @@ class TestThailand(CommonCountryTests, TestCase):
 
     def test_songkran_festival(self):
         name = "วันสงกรานต์"
-
-        self.assertNoHolidayName(name, 1947)
-        for year in range(1948, 1954):
-            self.assertHoliday(f"{year}-04-13", f"{year}-04-14", f"{year}-04-15")
-        self.assertNoHolidayName(name, range(1954, 1957))
-        self.assertHolidayName(name, (f"{year}-04-13" for year in range(1957, 1989)))
+        # APR 13-14-15
+        for year in [*range(1948, 1954), *range(1998, 2020), *range(2021, 2050)]:
+            self.assertHolidayName(name, (f"{year}-04-13", f"{year}-04-14", f"{year}-04-15"))
+        # APR 12-13-14
         for year in range(1989, 1998):
-            self.assertHoliday(f"{year}-04-12", f"{year}-04-13", f"{year}-04-14")
-        for year in range(1998, 2020):
-            self.assertHoliday(f"{year}-04-13", f"{year}-04-14", f"{year}-04-15")
-        self.assertNoHoliday("2020-04-13", "2020-04-14", "2020-04-15")
-        for year in range(2021, 2058):
-            self.assertHoliday(f"{year}-04-13", f"{year}-04-14", f"{year}-04-15")
+            self.assertHolidayName(name, (f"{year}-04-12", f"{year}-04-13", f"{year}-04-14"))
+        # APR 13
+        self.assertHolidayName(name, (f"{year}-04-13" for year in range(1957, 1989)))
+        # None (2020 is special_public_holidays instead)
+        self.assertNoHolidayName(name, "2020-04-13", "2020-04-14", "2020-04-15")
+        self.assertNoHolidayName(name, range(1941, 1948), range(1954, 1957))
 
         self.assertNoNonObservedHoliday(
             "2012-04-16",
             "2013-04-16",
+            "2014-04-16",
             "2017-04-17",
             "2018-04-16",
             "2019-04-16",
             # 2020 Songkran Festival special in lieus doesn't counts
             "2023-04-17",
             "2024-04-16",
+            "2025-04-16",
             "2028-04-17",
             "2029-04-16",
             "2030-04-16",
@@ -264,10 +199,8 @@ class TestThailand(CommonCountryTests, TestCase):
 
     def test_national_labour_day(self):
         name = "วันแรงงานแห่งชาติ"
-
-        self.assertNoHoliday("1973-05-01")
-        self.assertNoHolidayName(name, 1973)
-        self.assertHoliday(f"{year}-05-01" for year in range(1974, 2058))
+        self.assertHolidayName(name, (f"{year}-05-01" for year in range(1974, 2050)))
+        self.assertNoHolidayName(name, range(1941, 1974))
 
         self.assertNoNonObservedHoliday(
             "2010-05-03",
@@ -280,12 +213,9 @@ class TestThailand(CommonCountryTests, TestCase):
 
     def test_coronation_day(self):
         name = "วันฉัตรมงคล"
-
-        self.assertNoHoliday("1957-05-05")
-        self.assertNoHolidayName(name, 1957)
-        self.assertHoliday(f"{year}-05-05" for year in range(1958, 2017))
-        self.assertNoHolidayName(name, range(2017, 2020))
-        self.assertHoliday(f"{year}-05-04" for year in range(2020, 2058))
+        self.assertHolidayName(name, (f"{year}-05-05" for year in range(1958, 2017)))
+        self.assertHolidayName(name, (f"{year}-05-04" for year in range(2020, 2050)))
+        self.assertNoHolidayName(name, range(1941, 1958), range(2017, 2020))
 
         self.assertNoNonObservedHoliday(
             "2012-05-07",
@@ -297,10 +227,8 @@ class TestThailand(CommonCountryTests, TestCase):
 
     def test_queen_suthida_birthday(self):
         name = "วันเฉลิมพระชนมพรรษาสมเด็จพระนางเจ้าสุทิดา พัชรสุธาพิมลลักษณ พระบรมราชินี"
-
-        self.assertNoHoliday("2018-06-03")
-        self.assertNoHolidayName(name, 2018)
-        self.assertHoliday(f"{year}-06-03" for year in range(2019, 2058))
+        self.assertHolidayName(name, (f"{year}-06-03" for year in range(2019, 2050)))
+        self.assertNoHolidayName(name, range(1941, 2019))
 
         self.assertNoNonObservedHoliday(
             "2023-06-05",
@@ -309,18 +237,17 @@ class TestThailand(CommonCountryTests, TestCase):
         )
 
     def test_national_day(self):
-        self.assertHoliday(f"{year}-06-24" for year in range(1941, 1960))
-        self.assertHoliday(f"{year}-12-05" for year in range(1960, 2058))
+        name = "วันชาติ"
+        self.assertHolidayName(name, (f"{year}-06-24" for year in range(1941, 1960)))
+        self.assertHolidayName(name, (f"{year}-12-05" for year in range(1960, 2050)))
 
         # No in lieus during its existense on June 24th
         # 1960+ In lieus are same as HM King Bhumibol Adulyadej's Birthday
 
     def test_rama_x_birthday(self):
-        name = "วันเฉลิมพระชนมพรรษา พระบาทสมเด็จพระเจ้าอยู่หัว"
-
-        self.assertNoHoliday("2016-07-28")
-        self.assertNoHolidayName(name, 2016)
-        self.assertHoliday(f"{year}-07-28" for year in range(2017, 2058))
+        name = "วันเฉลิมพระชนมพรรษาพระบาทสมเด็จพระปรเมนทรรามาธิบดีศรีสินทรมหาวชิราลงกรณ พระวชิรเกล้าเจ้าอยู่หัว"
+        self.assertHolidayName(name, (f"{year}-07-28" for year in range(2017, 2050)))
+        self.assertNoHolidayName(name, range(1941, 2017))
 
         self.assertNoNonObservedHoliday(
             "2018-07-30",
@@ -333,13 +260,14 @@ class TestThailand(CommonCountryTests, TestCase):
     def test_queen_sirikit_birthday(self):
         name_ix = "วันเฉลิมพระชนมพรรษาสมเด็จพระนางเจ้าสิริกิติ์ พระบรมราชินีนาถ"
         name_x = "วันเฉลิมพระชนมพรรษาสมเด็จพระบรมราชชนนีพันปีหลวง"
+        years_pre = range(1941, 1976)
+        years_ix = range(1976, 2017)
+        years_x = range(2017, 2050)
 
-        self.assertNoHoliday("1975-08-12")
-        self.assertNoHolidayName(name_ix, 1975)
-        self.assertHolidayName(name_ix, (f"{year}-08-12" for year in range(1976, 2017)))
-        self.assertNoHolidayName(name_x, range(1941, 2017))
-        self.assertHolidayName(name_x, (f"{year}-08-12" for year in range(2017, 2058)))
-        self.assertNoHolidayName(name_ix, range(2017, 2058))
+        self.assertHolidayName(name_ix, (f"{year}-08-12" for year in years_ix))
+        self.assertHolidayName(name_x, (f"{year}-08-12" for year in years_x))
+        self.assertNoHolidayName(name_ix, years_pre, years_x)
+        self.assertNoHolidayName(name_x, years_pre, years_ix)
 
         self.assertNoNonObservedHoliday(
             "2012-08-13",
@@ -353,10 +281,9 @@ class TestThailand(CommonCountryTests, TestCase):
     def test_national_mothers_day(self):
         name = "วันแม่แห่งชาติ"
 
-        self.assertNoHolidayName(name, 1949)
         self.assertHolidayName(name, (f"{year}-04-15" for year in range(1950, 1958)))
-        self.assertNoHolidayName(name, range(1958, 1976))
-        self.assertHolidayName(name, (f"{year}-08-12" for year in range(1976, 2058)))
+        self.assertHolidayName(name, (f"{year}-08-12" for year in range(1976, 2050)))
+        self.assertNoHolidayName(name, range(1941, 1950), range(1958, 1976))
 
         # April 15 (1950-1958) exists prior to in lieu laws
         # In lieus are same as HM Queen Sirikit's Birthday
@@ -365,16 +292,17 @@ class TestThailand(CommonCountryTests, TestCase):
         name_ix = "วันคล้ายวันสวรรคตพระบาทสมเด็จพระปรมินทรมหาภูมิพลอดุลยเดช บรมนาถบพิตร"
         name_x = "วันคล้ายวันสวรรคตพระบาทสมเด็จพระบรมชนกาธิเบศร มหาภูมิพลอดุลยเดชมหาราช บรมนาถบพิตร"
         name_x_memorial = "วันนวมินทรมหาราช"
-
-        self.assertNoHoliday("2016-10-13")
-        self.assertNoHolidayName(name_ix, 2016)
-        self.assertNoHolidayName(name_x, range(1941, 2019))
-        self.assertNoHolidayName(name_x_memorial, range(1941, 2023))
-        self.assertHolidayName(name_ix, (f"{year}-10-13" for year in range(2017, 2019)))
-        self.assertHolidayName(name_x, (f"{year}-10-13" for year in range(2019, 2023)))
-        self.assertHolidayName(name_x_memorial, (f"{year}-10-13" for year in range(2023, 2058)))
-        self.assertNoHolidayName(name_ix, range(2019, 2058))
-        self.assertNoHolidayName(name_x, range(2023, 2058))
+        years_pre = range(1941, 2017)
+        years_ix = range(2017, 2019)
+        years_x = range(2019, 2023)
+        years_x_memorial = range(2023, 2050)
+
+        self.assertHolidayName(name_ix, (f"{year}-10-13" for year in years_ix))
+        self.assertHolidayName(name_x, (f"{year}-10-13" for year in years_x))
+        self.assertHolidayName(name_x_memorial, (f"{year}-10-13" for year in years_x_memorial))
+        self.assertNoHolidayName(name_ix, years_pre, years_x, years_x_memorial)
+        self.assertNoHolidayName(name_x, years_pre, years_ix, years_x_memorial)
+        self.assertNoHolidayName(name_x_memorial, years_pre, years_ix, years_x)
 
         self.assertNoNonObservedHoliday(
             "2018-10-15",
@@ -386,9 +314,7 @@ class TestThailand(CommonCountryTests, TestCase):
 
     def test_rama_five_memorial_day(self):
         name = "วันปิยมหาราช"
-        self.assertHoliday(f"{year}-10-23" for year in range(1941, 2058))
-        self.assertNoHoliday("1910-10-23", "1940-10-23")
-        self.assertNoHolidayName(name, Thailand(years=[1910, 1940]))
+        self.assertHolidayName(name, (f"{year}-10-23" for year in range(1941, 2050)))
 
         self.assertNoNonObservedHoliday(
             "2010-10-25",
@@ -405,16 +331,17 @@ class TestThailand(CommonCountryTests, TestCase):
         name_great = (
             "วันคล้ายวันเฉลิมพระชนมพรรษาพระบาทสมเด็จพระบรมชนกาธิเบศร มหาภูมิพลอดุลยเดชมหาราช บรมนาถบพิตร"
         )
+        years_pre = range(1941, 1960)
+        years_reign = range(1960, 2016)
+        years_dead = range(2016, 2019)
+        years_great = range(2019, 2050)
 
-        self.assertNoHoliday("1959-12-05")
-        self.assertNoHolidayName(name_reign, range(1941, 1960))
-        self.assertNoHolidayName(name_dead, range(1941, 2016))
-        self.assertNoHolidayName(name_great, range(1941, 2019))
-        self.assertHolidayName(name_reign, (f"{year}-12-05" for year in range(1976, 2016)))
-        self.assertHolidayName(name_dead, (f"{year}-12-05" for year in range(2016, 2019)))
-        self.assertHolidayName(name_great, (f"{year}-12-05" for year in range(2019, 2058)))
-        self.assertNoHolidayName(name_reign, range(2016, 2058))
-        self.assertNoHolidayName(name_dead, range(2019, 2058))
+        self.assertHolidayName(name_reign, (f"{year}-12-05" for year in years_reign))
+        self.assertHolidayName(name_dead, (f"{year}-12-05" for year in years_dead))
+        self.assertHolidayName(name_great, (f"{year}-12-05" for year in years_great))
+        self.assertNoHolidayName(name_reign, years_pre, years_dead, years_great)
+        self.assertNoHolidayName(name_dead, years_pre, years_reign, years_great)
+        self.assertNoHolidayName(name_great, years_pre, years_reign, years_dead)
 
         self.assertNoNonObservedHoliday(
             "2010-12-06",
@@ -429,13 +356,14 @@ class TestThailand(CommonCountryTests, TestCase):
         name = "วันพ่อแห่งชาติ"
 
         # This concides with HM King Bhumibol Adulyadej's Birthday
-        self.assertNoHolidayName(name, 1979)
-        self.assertHolidayName(name, (f"{year}-12-05" for year in range(1980, 2058)))
+        self.assertHolidayName(name, (f"{year}-12-05" for year in range(1980, 2050)))
+        self.assertNoHolidayName(name, range(1941, 1980))
 
         # In lieus are same as HM King Bhumibol Adulyadej's Birthday
 
     def test_constitution_day(self):
-        self.assertHoliday(f"{year}-12-10" for year in range(1941, 2058))
+        name = "วันรัฐธรรมนูญ"
+        self.assertHolidayName(name, (f"{year}-12-10" for year in range(1941, 2050)))
 
         self.assertNoNonObservedHoliday(
             "2011-12-12",
@@ -447,7 +375,8 @@ class TestThailand(CommonCountryTests, TestCase):
         )
 
     def test_new_years_eve(self):
-        self.assertHoliday(f"{year}-12-31" for year in range(1941, 2058))
+        name = "วันสิ้นปี"
+        self.assertHolidayName(name, (f"{year}-12-31" for year in range(1941, 2050)))
 
         self.assertNoNonObservedHoliday(
             "2012-01-03",
@@ -457,150 +386,30 @@ class TestThailand(CommonCountryTests, TestCase):
             "2029-01-02",
         )
 
-    def test_makha_bucha(self):
-        name = "วันมาฆบูชา"
-
-        dt = (
-            "2010-02-28",
-            "2011-02-18",
-            "2012-03-07",
-            "2013-02-25",
-            "2014-02-14",
-            "2015-03-04",
-            "2016-02-22",
-            "2017-02-11",
-            "2018-03-01",
-            "2019-02-19",
-            "2020-02-08",
-            "2021-02-26",
-            "2022-02-16",
-            "2023-03-06",
-            "2024-02-24",
-            "2025-02-12",
-            "2026-03-03",
-            "2027-02-21",
-            "2028-02-10",
-            "2029-02-27",
-            "2030-02-17",
-        )
-        self.assertHolidayName(name, dt)
-        self.assertNoHolidayName(name, 2158)
-
+    def test_buddhist_holidays_in_lieu(self):
         self.assertNoNonObservedHoliday(
+            # Makha Bucha
             "2010-03-01",
             "2017-02-13",
             "2020-02-10",
             "2024-02-26",
             "2024-02-22",
             "2030-02-18",
-        )
-
-    def test_visakha_bucha(self):
-        name = "วันวิสาขบูชา"
-
-        dt = (
-            "2010-05-28",
-            "2011-05-17",
-            "2012-06-04",
-            "2013-05-24",
-            "2014-05-13",
-            "2015-06-01",
-            "2016-05-20",
-            "2017-05-10",
-            "2018-05-29",
-            "2019-05-18",
-            "2020-05-06",
-            "2021-05-26",
-            "2022-05-15",
-            "2023-06-03",
-            "2024-05-22",
-            "2025-05-11",
-            "2026-05-31",
-            "2027-05-20",
-            "2028-05-08",
-            "2029-05-27",
-            "2030-05-16",
-        )
-        self.assertHolidayName(name, dt)
-        self.assertNoHolidayName(name, 2158)
-
-        self.assertNoNonObservedHoliday(
+            # Visakha Bucha
             "2019-05-20",
             "2022-05-16",
             "2023-06-05",
             "2025-05-12",
             "2026-06-01",
             "2029-05-28",
-        )
-
-    def test_asarnha_bucha(self):
-        name = "วันอาสาฬหบูชา"
-
-        dt = (
-            "2010-07-26",
-            "2011-07-15",
-            "2012-08-02",
-            "2013-07-22",
-            "2014-07-11",
-            "2015-07-30",
-            "2016-07-19",
-            "2017-07-08",
-            "2018-07-27",
-            "2019-07-16",
-            "2020-07-05",
-            "2021-07-24",
-            "2022-07-13",
-            "2023-08-01",
-            "2024-07-20",
-            "2025-07-10",
-            "2026-07-29",
-            "2027-07-18",
-            "2028-07-06",
-            "2029-07-25",
-            "2030-07-14",
-        )
-        self.assertHolidayName(name, dt)
-        self.assertNoHolidayName(name, 2158)
-
-        self.assertNoNonObservedHoliday(
+            # Asarnha Bucha
             "2017-07-10",
             "2020-07-07",
             "2021-07-26",
             "2024-07-22",
             "2027-07-20",
             "2030-07-16",
-        )
-
-    def test_khao_phansa(self):
-        name = "วันเข้าพรรษา"
-
-        dt = (
-            "2010-07-27",
-            "2011-07-16",
-            "2012-08-03",
-            "2013-07-23",
-            "2014-07-12",
-            "2015-07-31",
-            "2016-07-20",
-            "2017-07-09",
-            "2018-07-28",
-            "2019-07-17",
-            "2020-07-06",
-            "2021-07-25",
-            "2022-07-14",
-            "2023-08-02",
-            "2024-07-21",
-            "2025-07-11",
-            "2026-07-30",
-            "2027-07-19",
-            "2028-07-07",
-            "2029-07-26",
-            "2030-07-15",
-        )
-        self.assertHolidayName(name, dt)
-        self.assertNoHolidayName(name, 2158)
-
-        self.assertNoNonObservedHoliday(
+            # Khao Phansa
             "2011-07-18",
             "2014-07-14",
             "2018-07-30",
@@ -608,118 +417,117 @@ class TestThailand(CommonCountryTests, TestCase):
 
     def test_raeknakhwan(self):
         name = "วันพืชมงคล"
-        self.assertHolidays(
-            Thailand(categories=GOVERNMENT, years=range(1960, 2024)),
-            ("1960-05-02", name),
-            ("1961-05-11", name),
-            ("1962-05-07", name),
-            ("1963-05-10", name),
-            ("1964-05-08", name),
-            ("1965-05-13", name),
-            ("1966-05-13", name),
-            ("1967-05-11", name),
-            ("1968-05-10", name),
-            ("1969-05-09", name),
-            ("1970-05-08", name),
-            ("1971-05-07", name),
-            ("1972-05-08", name),
-            ("1973-05-07", name),
-            ("1974-05-08", name),
-            ("1975-05-07", name),
-            ("1976-05-10", name),
-            ("1977-05-12", name),
-            ("1978-05-11", name),
-            ("1979-05-07", name),
-            ("1980-05-14", name),
-            ("1981-05-07", name),
-            ("1982-05-19", name),
-            ("1983-05-11", name),
-            ("1984-05-10", name),
-            ("1985-05-09", name),
-            ("1986-05-09", name),
-            ("1987-05-08", name),
-            ("1988-05-11", name),
-            ("1989-05-11", name),
-            ("1990-05-11", name),
-            ("1991-05-10", name),
-            ("1992-05-14", name),
-            ("1993-05-17", name),
-            ("1994-05-11", name),
-            ("1995-05-10", name),
-            ("1996-05-16", name),
-            ("1997-05-09", name),
-            ("1998-05-08", name),
+        dt = (
+            "1960-05-02",
+            "1961-05-11",
+            "1962-05-07",
+            "1963-05-10",
+            "1964-05-08",
+            "1965-05-13",
+            "1966-05-13",
+            "1967-05-11",
+            "1968-05-10",
+            "1969-05-09",
+            "1970-05-08",
+            "1971-05-07",
+            "1972-05-08",
+            "1973-05-07",
+            "1974-05-08",
+            "1975-05-07",
+            "1976-05-10",
+            "1977-05-12",
+            "1978-05-11",
+            "1979-05-07",
+            "1980-05-14",
+            "1981-05-07",
+            "1982-05-19",
+            "1983-05-11",
+            "1984-05-10",
+            "1985-05-09",
+            "1986-05-09",
+            "1987-05-08",
+            "1988-05-11",
+            "1989-05-11",
+            "1990-05-11",
+            "1991-05-10",
+            "1992-05-14",
+            "1993-05-17",
+            "1994-05-11",
+            "1995-05-10",
+            "1996-05-16",
+            "1997-05-09",
+            "1998-05-08",
             # Not a holiday in 1999 date, was held on MAY, 14.
-            ("2000-05-15", name),
-            ("2001-05-16", name),
-            ("2002-05-09", name),
-            ("2003-05-08", name),
-            ("2004-05-07", name),
-            ("2005-05-11", name),
-            ("2006-05-11", name),
-            ("2007-05-10", name),
-            ("2008-05-09", name),
-            ("2009-05-11", name),
-            ("2010-05-13", name),
-            ("2011-05-13", name),
-            ("2012-05-09", name),
-            ("2013-05-13", name),
-            ("2014-05-09", name),
-            ("2015-05-13", name),
-            ("2016-05-09", name),
-            ("2017-05-12", name),
-            ("2018-05-14", name),
-            ("2019-05-09", name),
-            ("2020-05-11", name),
-            ("2021-05-10", name),
-            ("2022-05-13", name),
-            ("2023-05-17", name),
-            ("2024-05-10", name),
-        )
+            "2000-05-15",
+            "2001-05-16",
+            "2002-05-09",
+            "2003-05-08",
+            "2004-05-07",
+            "2005-05-11",
+            "2006-05-11",
+            "2007-05-10",
+            "2008-05-09",
+            "2009-05-11",
+            "2010-05-13",
+            "2011-05-13",
+            "2012-05-09",
+            "2013-05-13",
+            "2014-05-09",
+            "2015-05-13",
+            "2016-05-09",
+            "2017-05-12",
+            "2018-05-14",
+            "2019-05-09",
+            "2020-05-11",
+            "2021-05-10",
+            "2022-05-13",
+            "2023-05-17",
+            "2024-05-10",
+            "2025-05-09",
+        )
+        gov_holidays = Thailand(categories=GOVERNMENT, years=range(1959, 2026))
+        self.assertHolidayName(name, gov_holidays, dt)
+        self.assertNoHolidayName(name, gov_holidays, 1959, 1999)
+        self.assertNoHolidayName(name)
 
     def test_armed_forces_holiday(self):
         name = "วันกองทัพไทย"
-        self.assertHolidays(
-            Thailand(categories=ARMED_FORCES, years=range(1958, 1960)), ("1959-04-08", name)
+        armed_forces_holidays = Thailand(categories=ARMED_FORCES, years=range(1958, 2050))
+        self.assertHolidayName(
+            name, armed_forces_holidays, (f"{year}-04-08" for year in range(1959, 1980))
         )
-        self.assertHolidays(
-            Thailand(categories=ARMED_FORCES, years=range(1979, 1981)),
-            ("1979-04-08", name),
-            ("1980-01-25", name),
+        self.assertHolidayName(
+            name, armed_forces_holidays, (f"{year}-01-25" for year in range(1980, 2007))
         )
-        self.assertHolidays(
-            Thailand(categories=ARMED_FORCES, years=range(2006, 2008)),
-            ("2006-01-25", name),
-            ("2007-01-18", name),
+        self.assertHolidayName(
+            name, armed_forces_holidays, (f"{year}-01-18" for year in range(2007, 2050))
         )
+        self.assertNoHolidayName(name, armed_forces_holidays, 1958)
+        self.assertNoHolidayName(name)
 
     def test_bank_holiday(self):
-        a_name = "วันหยุดเพิ่มเติมสำหรับการปิดบัญชีประจำปีของธนาคารเพื่อการเกษตรและสหกรณ์การเกษตร"
-        m_name = "วันหยุดภาคครึ่งปีของสถาบันการเงินและสถาบันการเงินเฉพาะกิจ"
-
-        # Start
-        self.assertHolidays(
-            Thailand(categories=BANK, years=range(1942, 1944)),
-            ("1943-04-01", a_name),
-            ("1943-07-01", m_name),
+        name_agri = "วันหยุดเพิ่มเติมสำหรับการปิดบัญชีประจำปีของธนาคารเพื่อการเกษตรและสหกรณ์การเกษตร"
+        name_mid = "วันหยุดภาคครึ่งปีของสถาบันการเงินและสถาบันการเงินเฉพาะกิจ"
+        bank_holidays = Thailand(categories=BANK, years=range(1942, 2023))
+        self.assertHolidayName(
+            name_agri, bank_holidays, (f"{year}-04-01" for year in range(1943, 2022))
         )
-        # End
-        self.assertHolidays(
-            Thailand(categories=BANK, years=range(2017, 2023)),
-            ("2017-04-01", a_name),
-            ("2017-07-01", m_name),
-            ("2018-04-01", a_name),
-            ("2018-07-01", m_name),
-            ("2019-04-01", a_name),
-            ("2020-04-01", a_name),
-            ("2021-04-01", a_name),
+        self.assertHolidayName(
+            name_mid, bank_holidays, (f"{year}-07-01" for year in range(1943, 2019))
         )
+        self.assertNoHolidayName(name_agri, bank_holidays, 1942, range(2022, 2050))
+        self.assertNoHolidayName(name_mid, bank_holidays, 1942, range(2019, 2050))
+        self.assertNoHolidayName(name_agri)
+        self.assertNoHolidayName(name_mid)
 
     def test_school_holiday(self):
-        self.assertHolidays(
-            Thailand(categories=SCHOOL, years=range(1956, 1958)),
-            ("1957-01-16", "วันครู"),
+        name = "วันครู"
+        school_holidays = Thailand(categories=SCHOOL, years=range(1956, 2050))
+        self.assertHolidayName(
+            name, school_holidays, (f"{year}-01-16" for year in range(1957, 2050))
         )
+        self.assertNoHolidayName(name, school_holidays, 1956)
+        self.assertNoHolidayName(name)
 
     def test_workday_1947(self):
         self.assertHolidays(