Search code examples
datedatetimestandards

Are there standards for expressing dates akin to holidays?


For example, Foo Holiday is the 3rd Tuesday in March. Bar Holiday is the 7th minute of the 7th hour of the 7th day of the 7th Month.

I have looked at standards like ISO8601 but it seems those are more concerned with explicit points in time.


Solution

  • As AlexApps99 described in their answer, there is no standard that will cover all holidays.

    For example, the start of Ramadan often depends on physically sighting the new moon, so it's impossible to predict the exact date, as cloudy weather might prevent anybody from spotting it in your country for a few days.

    However, for many repeating events the follow simpler rules (e.g. Foo & Bar Holiday in your question), there is iCalendar's RRULE (Recurrence Rule), which is a standard for creating repeating patterns for recurring events.

    Many calendar apps will have a GUI for creating RRULE.

    RRULE is documented in RFC 5545 Section 3.8.5.3.

    For example, an event for U.S. Presidential Election day would be:

    Every 4 years, the first Tuesday after a Monday in November, forever (U.S. Presidential Election day):

    DTSTART;TZID=America/New_York:19961105T090000
    RRULE:FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8
    

    Example taken from RFC 5545 Section 3.8.5.3 Page 129

    Foo Holiday (3rd Tuesday in March) could be described with:

    RRULE;FREQ=YEARLY;BYMONTH=3;BYDAY=TU;BYMONTHDAY=15,16,17,18,19,20,21
    

    Bar Holiday could be described with (7th minute of the 7th hour of the 7th day of the 7th Month) could be described with:

    RRULE;FREQ=YEARLY;BYMONTH=7;BYMONTHDAY==7;BYHOUR=7;BYMINUTE=7
    

    Unfortunately, the iCalendar RRULE spec can't can't handle more complicated rules. Easter can't be done, (although https://github.com/sappjw/calendars contains Easter RRULEs accurate for 1900-2099, and the Python dateutil library's RRULE has an unofficial extension called BYEASTER, but even then, it only supports Western Easter).

    Non-Gregorian calendars are also not supported, however, there is a draft spec RFC7529 that adds RRULE support for additional calendars, which would allow you to describe Chinese New Year using the following syntax:

    DTSTART;VALUE=DATE:20130210
    RRULE:RSCALE=CHINESE;FREQ=YEARLY
    SUMMARY:Chinese New Year
    

    These define a recurring event for the Chinese New Year, with the first instance being the one in Gregorian year 2013.

    Example taken from RFC7529#Section 4.3.1