Sunday, 3 December 2017

This week 14/2017 - Jollyday

Jollyday is a small library to get dates of holidays. 
When you open project documentation page, you can think that this project is dead. The sourceforge page wasn't updated for last 2 years. However when you check GitHub repository, it is still developed since 2010. When I write this blog the most fresh version for JDK8 is 0.5.2.

Jollyday handles fixed, related to day of month and religious holidays. To be more advanced, it handles additional rules to define moving free days related to holidays, ex when holiday is on Saturday, next Monday will be holiday as well.

Below there is piece US configuration file. The Jollyday jar file includes default configuration for 64 countries. Some of them include holidays changes in time in the past. Polish configuration doesn't.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
..
14
15
16
17
18
19
20
<tns:Configuration hierarchy="us" description="United States"
                   xmlns:tns="http://www.example.org/Holiday" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.example.org/Holiday/Holiday.xsd">
    <tns:Holidays>
        <tns:Fixed month="JANUARY" day="1" descriptionPropertiesKey="NEW_YEAR"/>
        <tns:Fixed month="JULY" day="4" validFrom="1776" descriptionPropertiesKey="INDEPENDENCE"/>
        <tns:Fixed month="NOVEMBER" day="11" validFrom="1938" descriptionPropertiesKey="VETERANS"/>
        <tns:Fixed month="DECEMBER" day="25" descriptionPropertiesKey="CHRISTMAS"/>
        <tns:Fixed month="MAY" day="30" validFrom="1869" validTo="1967" descriptionPropertiesKey="MEMORIAL"/>
        <tns:FixedWeekday which="LAST" weekday="MONDAY" month="MAY" validFrom="1968" descriptionPropertiesKey="MEMORIAL"/>
        <tns:FixedWeekday which="FIRST" weekday="MONDAY" month="SEPTEMBER" validFrom="1895" descriptionPropertiesKey="LABOUR_DAY"/>
        <tns:FixedWeekday which="FOURTH" weekday="THURSDAY" month="NOVEMBER" validFrom="1863" descriptionPropertiesKey="THANKSGIVING"/>
    </tns:Holidays>
....
    <tns:SubConfigurations hierarchy="la" description="Louisiana">
        <tns:Holidays>
            <tns:FixedWeekday which="THIRD" weekday="MONDAY" month="JANUARY" validFrom="1986" descriptionPropertiesKey="MARTIN_LUTHER_KING"/>
            <tns:ChristianHoliday type="GOOD_FRIDAY"/>
            <tns:ChristianHoliday type="MARDI_GRAS"/>
        </tns:Holidays>
    </tns:SubConfigurations>

The HolidayManager is main interface of Jollyday library. Below there is a piece of code which create HolidayManager instance for US using default configuration.

1
2
ManagerParameter params = ManagerParameters.create(Locale.US));
HolidayManager holidayManager = HolidayManager.getInstance(params);

If we'd like to get holidays for US we need to execute code as below.

1
holidayManager.getHolidays(2017)


If we'd like to get holidays for Louisiana in US we need to call code as below


1
holidayManager.getHolidays(2017, "la")

It is possible to create deeper hierarchy of calendar. You must only create sub-configuration for this node and call get Holidays with additional code - code of sub-configuration.

To use custom configuration, you need create ManagerParameters from URL where is configuration file available, ex


1
2
3
URL url = ClassLoader.getSystemResource("Holidays_pl.xml");
ManagerParameter params = ManagerParameters.create(url);
HolidayManager m = HolidayManager.getInstance(params);

Below I added a few example of most common usage of HolidayManager.

1
2
3
4
5
m.getHolidays(2017)
m.getHolidays(LocalDate.now(), LocalDate.now().plusYears(5))
m.isHoliday(LocalDate.now())
m.isHoliday(LocalDate.now(), "an")
m.isHoliday(LocalDate.now(), HolidayType.UNOFFICIAL_HOLIDAY)

For more demanding, it is possible to implement:
  • country specific HolidayManager
  • configuration data source
  • change implementation of parsers
Then you need create your own properties as below (default properties file)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
manager.impl=de.jollyday.impl.DefaultHolidayManager
# Holiday manager for Japan implements some specific Japanese holiday rule.
manager.impl.jp=de.jollyday.impl.JapaneseHolidayManager
# Implementation class for holiday configurations
configuration.datasource.impl=de.jollyday.datasource.impl.XmlFileDataSource

# Configure the parsers to be used for each individual configuration type
parser.impl.de.jollyday.config.Fixed=de.jollyday.parser.impl.FixedParser
parser.impl.de.jollyday.config.FixedWeekdayInMonth=de.jollyday.parser.impl.FixedWeekdayInMonthParser
parser.impl.de.jollyday.config.IslamicHoliday=de.jollyday.parser.impl.IslamicHolidayParser
parser.impl.de.jollyday.config.ChristianHoliday=de.jollyday.parser.impl.ChristianHolidayParser
parser.impl.de.jollyday.config.RelativeToFixed=de.jollyday.parser.impl.RelativeToFixedParser
parser.impl.de.jollyday.config.RelativeToWeekdayInMonth=de.jollyday.parser.impl.RelativeToWeekdayInMonthParser
parser.impl.de.jollyday.config.FixedWeekdayBetweenFixed=de.jollyday.parser.impl.FixedWeekdayBetweenFixedParser
parser.impl.de.jollyday.config.FixedWeekdayRelativeToFixed=de.jollyday.parser.impl.FixedWeekdayRelativeToFixedParser
parser.impl.de.jollyday.config.EthiopianOrthodoxHoliday=de.jollyday.parser.impl.EthiopianOrthodoxHolidayParser
parser.impl.de.jollyday.config.RelativeToEasterSunday=de.jollyday.parser.impl.RelativeToEasterSundayParser

and setting VM options:

1
-Dde.jollyday.config.urls=file:/some/path/new.properties,http://myserver/some/path/further.properties,jar:file:myLibrary.jar!/my.properties  

I didn't find out if data source or parsers can be country specific and how to create your own parser.

Resources:
  1. jollyday.sourceforge.net
  2. github repository


1 comment:

  1. Thank you for this blogpost, really helpful. I was curious on how the sub-configuration worked so your example was helpful. Fun fact: i also have a code blog with the same background picture and similar theme :) https://intocodemode.blogspot.com/

    ReplyDelete