The KHolidays file format is based on the Plan file format, but has been heavily modified to cater for alternative calendar systems and proper category support. This page documents the basics of this format and the other conventions used in standardising the content of the files. You can use this page to create a new file or to maintain an existing page.
A single holiday file defines all the holidays for an administrative region translated into a language and optionally separated into categories. This is known in KHolidays as a Holiday Region and each file/region is listed separately in the user interface where they can be enabled and disabled separately. This provides a convenient and easy way for organising large groups of holidays, for example by splitting religious holidays into a separate file for a country, or even creating a global level file for all holidays for a religion.
The file name is of the format holiday_$region_$language[_$variant], for example "holiday_es_es" for general holidays in Spain in Spanish or "holiday_es_es_catholic" for Catholic holidays in Spain in Spanish.
When creating a new holiday file please copy this template and complete all the fields within the square brackets [ ] before adding the holidays under each category heading. See below for an explanation of the categories.
All lines starting with a ":" are comments and are ignored by the parser.
:: :: Country: [Name] :: :: Language: [Name] :: :: Author: [Name <firstname.lastname@example.org>] :: :: Updated: [YYYY-MM-DD] :: :: Source: [Source URL 1] :: [Source URL 2] :: Metadata country "XX" language "xx" :name "[optional - defaults to country name]" description "[please add description in source language, e.g. National holiday file for $country]" :: Public Holidays :: Civil :: Religious :: Government :: Financial :: Commemorative :: Cultural :: Historical :: School :: Daylight Saving (Winter/Summer Time) :: Seasons :: Name Days
The file header section contains documentation about the file contents:
The File Metadata section contains metadata about the file contents that will be used by the KHolidays library, so must always be completed:
After the File Metadata comes the holiday rules themselves. A typical rule is of the format:
"[Holiday Name]" [categories] on [calendar] [calculation]
"New Years Day" public cultural on january 1 "Valentines Day" cultural on february 14 "Easter" religious on easter "Christmas Day" public religious on december 25 "Eid ul-Fitr" religious on hijri shawwal 1
You must assign at least one category to a holiday, and can assign multiple categories if needed.
The calendar is the calendar system to use in the date calculation, such as Gregorian or Hijri. If omitted then Gregorian is assumed.
Calculations can be a simple day and month, or very complex logical and mathematical expressions, or be relative to other events, or even be shifted to other dates.
For convenience, we organise the list into categories, with each category sorted in date order. All Public Holidays should go in the first section regardless of any other category they may belong to.
Holiday categories can be managed in a number of ways, primarily by the category keywords in the file format. Holidays can also be categorised by splitting them into separate files and adding the category name as a variant tag in the filename.
You must assign one or more category keywords to every holiday rule.
While the file format doesn't distinguish between different types of category tags or assign any special meaning to them, KHolidays does infer special meaning from certain tags:
This means that while in most cases a single category tag is all that is required for a holiday, some holidays will have a second "Day Off" category tag to indicate the group of people who get that day off work or school. By convention the "Day Off" tags should come first.
The following category keywords are currently supported by the file format.
If you require other category tags please file a feature request.
Sometimes a national holiday file will hold too many holidays for a given category to be useful to most users, sometimes to the point that users will disable the file rather than have their calendar flooded with events. This usually applies to Religious holidays and Name Days. To prevent this you can split the holidays out into separate files that the user can then configure separately to display or not.
While it is recommended to keep each such file restricted to a single category, there is nothing to stop you mixing multiple categories in such a file. Where the file holds a single category then just append that category to the end of the filename (e.g. "holiday_es_es_religious") and KHolidays will automatically generate a Holiday Region Name including that category. If you mix the categories, or the generated name is not suitable, then populate teh "name" metadat field with the name you want.
The filename category supports extra categories for religions to allow for more detailed control over these holidays. The extra supported categories are:
If you require other category tags please file a feature request.
There are very many clever tricks to calculate holidays, most of which have already been used, so have a look in the existing files for inspiration or to see if your holiday has already been implemented.
The simplest holiday rule is to simply state the day of the year that the holiday occurs on:
"New Years Day" public on january 1
You can define the calendar system to use in calculating a holiday
"Islamic New Year" civil on hijri muharram 1
You can also define how long a holiday lasts for:
"3 Day Holiday" public on july 1 length 3
There are special keywords available for Easter and Orthodox Easter:
"Easter Sunday" public on easter "Orthodox Easter Sunday" public on pascha
Other custom formulas can be supported in the same way if needed.
To calculate a holiday relative to another date:
"Good Friday" public religious on easter minus 2 "Easter Monday" public on easter plus 1
To calculate a holiday on a given weekday in a given week in a month:
"Early May Bank Holiday" public on first monday in may "British Summer Time starts" seasonal on last sunday in march
You can use conditionals to restrict the year range that a holiday applies to, or that a calculation for a holiday applies to. note that conditionals can be nested, but it is advised not to nest too deep or it becomes difficult to read and understand.
To restrict a calendar to a single year then stipulate that year:
"Royal Wedding" public on 29 april 2011
To set the date range a holiday applies to (e.g. if a new holiday is introduced or an old one ended, or the calculation is changed):
"Old Holiday" public on ((year <= 2012) ? [june 1] : [noop]) "New Holiday" public on ((year >= 2012) ? [may 1] : [noop]) "Spring Bank Holiday" public on ((year == 2012) ? [june 4] : [last monday in may])
If the calculation has changed too many times, the rule may get too complex, so you may want to express it as multiple rules instead.
If you need to apply different categories depending on the date:
"Nationaldagen" civil on ((year <= 2004) ? [june 6] : [noop]) "Nationaldagen" public on ((year >= 2005) ? [june 6] : [noop])
You can shift a holiday to another date if it meets certain conditions:
"New Year's Day" public on january 1 shift to monday if sunday
However this can get confusing if, as in this case, the original date really is the "holiday" and the shifted date is just the day off. You should only use this form if the actual holiday itself gets moved. An alternative could be:
"New Year's Day" cultural on january 1 "New Year's Day Holiday" public on january 1 shift to monday if sunday
The problem here is you always get to see two entries where one would be sufficient most years. You can use conditionals to calculate exactly when to display the extra holiday, but it gets complicated:
"News Years Day Holiday" public on ( (([january 1] == [sunday after ([january 1])])) ? [monday after ([january 1])] : noop )
To observe a holiday on the Monday if it falls on a Saturday or Sunday while keeping the original day off as well:
"Christmas Day" public religious on december 25 "Christmas Day Bank Holiday" public on ( (([december 25] == [saturday after ([december 25])]) || ([december 25] == [sunday after ([december 25])])) ? [monday after ([december 25])] : noop )