Working Days 
API for Developers 
v1.2


Introduction

Our HTTP JSON API exposes 3 kind of services you can plug to:

  • Analyse a period. You provide a start date and an end date, we respond with the number of days, working days, work hours, weekend days, the list of the public holidays over the period.
  • Add any number of working days / public holidays / weekend days to a given date. You provide a start date, we return the end date. We also return the days ventilation over that period.
  • List all the non working dates between 2 dates (they can be weekend days, public holidays or custom dates)


  • We currently cover 40 countries and more than 230 regional calendars. We also cover main stock exchanges calendars. The quality of our data is our top priority. We work hard to keep our database up to date by following government announcements regarding public holidays changes.

    We can locate any postal address and tell you which calendar configuration is relevant to it, and it is possible to take into account your personal custom dates.

    Without a key, you can immediately evaluate the service as long as your dates are inside the year 2013. In order to access the API without dates limitations, you will be needing a personal API key. Get your key right now, it comes with a SLA and a Data Quality Insurance .

    Note that the period you want to analyze must not exceed 1600 days (4.4 years) in order not to overload our servers and be within the years 1970 to 2037.

    Give also a try to our API test tool, it will let you understand the API behavior very quickly.

    Now let's look at the API, some sample HTTP requests and JSON replies, and some PHP code examples (JSON libraries are available in all languages).



    Analyse a period

    Arguments

    Name Description

    key

    Required
    Your personal API key

    country_code

    Required
    The ISO country code (2 letters).
    See the list of countries
    For instance, if you want to take into account the french calendar, send country_code=FR

    command

    Required
    The name of the service you want to call. analyse

    start_date

    Required
    The start date (YYYY-MM-DD)

    end_date

    Required
    The end date (YYYY-MM-DD)

    configuration

    Optional
    The name of the regional preset configuration. See the list of configurations
    Each country comes with a set of preset configurations (applicable public holidays in that region).
    For instance in the USA, you don't have the same public holidays in New York and in California. If you are interested with the working days calendar in New York State, you would go : contry_code=US&configuration=New+York. If you are interested in the american stock exchange opening calendar, you would go : contry_code=US&configuration=New+York+Stock+Exchange.
    If you don't provide the configuration parameter, the default configuration will be applied. In the case of the USA, the default configuration is California.
    Many countries have only one preset configuration (Chile, Denmark, China, Colombia, etc..), in that case this parameter is not necessary and will be ignored.

    weekend

    Optional
    Your weekend structure. Sunday-Monday-Tuesday-Wednesday-Thursday-Friday-Saturday.
    Default value is 1000001 (weekend days on saturday, sunday).
    If the weekend for you is sunday and monday, you can send : 1100000

    week_hours

    Optional
    Your week hours structure. This parameter maybe useful when computing work hours over a period.
    Sunday morning*Sunday afternoon*Monday morning*Monday afternoon*Tuesday morning*Tuesday afternoon*Wednesday morning*Wednesday afternoon*Thursday morning*Thursday afternoon*Friday morning*Friday afternoon*Saturday morning*Saturday afternoon.
    Default value is 0*0*4*4*4*4*4*4*4*4*4*4*0*0* ( 4 hours every morning and 4 hours every afternoon except on saturday, sunday ; the morning ending at 13h or 1pm).
    See this example.

    use_custom_configuration

    Optional
    Take into account your own personal configuration.
    Send 1 for true. Default value is false.
    See this example.

    Suppose we want to analyse the period from 1st january 2013 to 31th december 2013 in Canada, with default parameters, the URL to request is going to be :

    https://api.workingdays.org/1.2/api.php?key=MYPERSONALKEY&country_code=CA&command=analyse&start_date=2013-01-01&end_date=2013-12-31

    and the service is going to reply with a JSON response like that (because the parameter is omitted, default configuration Ontario is used):



    Suppose now we want to analyse the period from 1st january 2013 to 31th december 2013 in Germany with the public holidays calendar applicable in the state of Baden-Württemberg, and our non working weekend days are on sundays and mondays, the URL to request is going to be :

    https://api.workingdays.org/1.2/api.php?key=MYPERSONALKEY&command=analyse&country_code=DE&configuration=Baden-Württemberg&start_date=2013-01-01&end_date=2013-12-31&weekend=1100000

    and the service is going to reply with a JSON response like that:



    Example PHP client code

    Add working days to a date

    Arguments

    Name Description

    key

    Required
    Your personal API key

    country_code

    Required
    The ISO country code (2 letters).
    See the list of countries
    For instance, if you want to take into account the french calendar, send country_code=FR

    command

    Required
    The name of the service you want to call. add_working_days

    start_date

    Required
    The start date (YYYY-MM-DD)

    increment

    Required
    The number of working days you want to add to your start date (positive or negative integer but not zero)

    configuration

    Optional
    The name of the regional preset configuration. See the list of configurations
    Each country comes with a set of preset configurations (applicable public holidays in that region).
    For instance in the USA, you don't have the same public holidays in New York and in California. If you are interested with the working days calendar in New York State, you would go : contry_code=US&configuration=New+York. If you are interested in the american stock exchange opening calendar, you would go : contry_code=US&configuration=New+York+Stock+Exchange.
    If you don't provide the configuration parameter, the default configuration will be applied. In the case of the USA, the default configuration is California.
    Many countries have only one preset configuration (Chile, Denmark, China, Colombia, etc..), in that case this parameter is not necessary and will be ignored.

    weekend

    Optional
    Your weekend structure. Sunday-Monday-Tuesday-Wednesday-Thursday-Friday-Saturday.
    Default value is 1000001 (weekend days on saturday, sunday).
    If the weekend for you is sunday and monday, you can send : 1100000

    use_custom_configuration

    Optional
    Take into account your own personal configuration.
    Send 1 for true. Default value is false.
    See this example.

    Suppose we want to add 90 working days to the 1st january 2013 over the french usual calendar, with default parameters, the URL to request is going to be :

    https://api.workingdays.org/1.2/api.php?key=MYPERSONALKEY&country_code=FR&command=add_working_days&start_date=2013-01-01&increment=90

    and the service is going to reply with a JSON response like that:



    Example PHP client code

    Add public holidays to a date

    Just change the command to add_public_holidays . The same logic remain unchanged (see add working days just above).

    Add weekend days to a date

    Just change the command to add_weekend_days . The same logic remain unchanged (see add working days just above).

    Locating a postal address

    Sometimes you may wonder which calendar configuration is relevant to a given customer's postal address.
    Locating a postal address will remove 600 days from your monthly quota.

    Arguments

    Name Description

    key

    Required
    Your personal API key

    command

    Required
    The name of the service you want to call. Here address_to_configuration

    address

    Required
    The postal address. It is a string with no constraint.

    Suppose we need to know which calendar is applicable to this customer address: "Paseo del Violón 18006 Granada España"

    https://api.workingdays.org/1.2/api.php?key=MYPERSONALKEY&command=address_to_configuration&address=Paseo del Violón 18006 Granada España

    and the service is going to reply with a JSON response like that:



    Example PHP client code



    Then you can use the resulting $country_code and $configuration to query any of the previous API methods.
    (Note that if you query a postal address belonging to a region of the world we do not cover, for example Greenland, the address_to_configuration may still be successfully locating your address and reply with a country code and a region but the calendar method will then reply with an invalid country_code parameter.)

    Using custom configuration

    Sometimes you may need to choose your public holidays one by one or add custom dates (your personal none working dates).
    If you use this parameter (use_custom_configuration=1 when sending any command) then the configuration used is the one you defined when you are connected into the corresponding working days web site (using the same email as the one associated with your API account).
    You can thus completely customize your calendar and be able to query it through the API. When you add use_custom_configuration=1, the parameters configuration and weekend are simply ignored as the configuration applied is the one of your personal account (your custom dates are taken into account).


    Let's get through a business case example to make it clear:
    A flower shop located in Paris (country_code=FR) is willing to accept online orders for bouquets from its website. Preparing a bouquet requires a full working day delay (we want to use command=add_working_days&increment=2 ). The shop follows the usual french calendar but is closed every monday and opens on saturdays.
    The shop has also a few annual closure, and that's why we need to define custom dates:

    1. Go to the www.joursouvres.fr and connect ("connexion" button on the top right corner).
    You can connect using any method you prefer (local account, Google or Facebook login) but you need to be using the same email than the one associated with you API account

    2. From the setup screen, choose the public holidays when the shop is closed, and define your default weekend days.

    3. In any calendar views, define your custom dates clicking on the period.
    This shop is closing after the 15 august (the 14th is a french public holiday and then starts the annual closure period) :



    Now our calendar is fully personalised, and we are ready to integrate that PHP code onto the shop website :



    This script will output :
    Next working day following 2017-06-14 is 2017-06-15
    Next working day following 2017-08-05 is 2017-08-08
    Next working day following 2017-08-12 is 2017-09-01

    Work hours

    When you analyse a period, the response also includes the number of work hours over the period.
    By default, the value is simply the number of working days * 8, because 8 is the default number of working hours per day.
    However, you can configure and use a custom week time schedule.
    Let's go through an example to make it clear:


    Suppose in your firm located in Bern, Switzerland, friday is a day where your firm closes at 5pm, other days at 6pm.

    1. Go to the www.arbeitstage.ch and connect ("connexion" button on the top right corner).
    You can connect using any method you prefer (local account, Google or Facebook login) but you need to be using the same email than the one associated with you API account

    2. From the setup screen, define your default weekly time schedule:






    Now our calendar is personalised, and we are ready to integrate adding the parameter "use_custom_configuration=1".

    Let's get the number of work hours on may 2019.



    This script will output :
    Number of work hours in may 2019 : 171
    (because there is one public holidays in that month falling on a thursday)

    Suppose now, this firm has 2 offices, one in Freiburg and one Bern. The two offices have the same corporate week schedule, but the public holidays are not the same following canton's local laws.
    Suppose you want to compare the work hours in may between those 2 locations. Because the "Bern" configuration is associated with our custom configuration, you cannot use the parameter "use_custom_configuration=1". Instead, you can use the optional parameter at request level "week_hours=0*0*4*4*4*4*4*4*4*4*4*3*0*0*" which defines our week hours structure. It is the number of work hours in sunday morning, sunday afternoon, monday morning, monday afternoon, .., .., saturday morning, saturday afternoon, separated by '*'.
    Let's look at the some sample code:



    This script will output:
    Number of work hours in may 2013 in Bern: 163
    Number of work hours in may 2013 in Freiburg: 155
    because those two cantons don't have same public holidays in may.

    List non working days

    This command let you list the non working days (weekend days, public holidays and custom dates) between 2 dates.

    Arguments

    Name Description

    key

    Required
    Your personal API key

    country_code

    Required
    The ISO country code (2 letters). See the list of countries

    command

    Required
    The name of the service you want to call. Here list_non_working_days

    start_date

    Required
    The start date (YYYY-MM-DD)

    end_date

    Required
    The end date (YYYY-MM-DD)

    configuration

    Optional
    The name of the regional preset configuration. See the list of configurations
    Each country comes with a set of preset configurations (applicable public holidays in that region).
    For instance in the USA, you don't have the same public holidays in New York and in California. If you are interested with the working days calendar in New York State, you would go : contry_code=US&configuration=New+York. If you are interested in the american stock exchange opening calendar, you would go : contry_code=US&configuration=New+York+Stock+Exchange.
    If you don't provide the configuration parameter, the default configuration will be applied. In the case of the USA, the default configuration is California.
    Many countries have only one preset configuration (Chile, Denmark, China, Colombia, etc..), in that case this parameter is not necessary and will be ignored.

    weekend

    Optional
    Your weekend structure. Sunday-Monday-Tuesday-Wednesday-Thursday-Friday-Saturday.
    Default value is 1000001 (weekend days on saturday, sunday).
    If the weekend for you is sunday and monday, you can send : 1100000

    use_custom_configuration

    Optional
    Take into account your own personal configuration.
    Send 1 for true. Default value is false.
    See this example.

    Suppose we want to get the list of all the non working days (weekend days, public holidays or custom dates) from 1st january 2013 to 31th december 2013 in Canada, with default parameters, the URL to request is going to be:

    https://api.workingdays.org/1.2/api.php?key=MYPERSONALKEY&country_code=CA&command=list_non_working_days&start_date=2013-01-01&end_date=2013-12-31


    and the service is going to reply with a JSON response like that:



    Now, let's go for some sample code.

    Our flower shop of the previous example needs to build a custom date picker to let its customers choose a delivery date from the flower online shop (from today and within the next 3 months). We need to take into account the custom calendar of the shop (it is managed in a confortable way within the corrsponding working days site).

    First, let's see how we can invalidate some dates with a standard jquery date picker (here we forbid 3 dates from being picked just for demonstration purpose):



    And here is the result, with those 3 dates being none selectable:



    Now, we need to replace those 3 dates with our real non working days over the next 3 months, by sending server side PHP request to our API command list_non_working_days, we can generate that javascript array at runtime :



    <?php
      
    $key
    ="MYPERSONALKEY";
    $country_code="FR";
    $url="http://api.workingdays.org/1.2/api.php?key=$key&command=list_non_working_days&country_code=$country_code&start_date=2017-05-01&end_date=2017-08-01&weekend=1100000&use_custom_dates=1";
    $options = array(
        
    'http' => array(
        
    'method'  => 'GET',
        
    'ignore_errors' => true
        
    )
    );
    $context  stream_context_create($options);
    $json_response file_get_contents($url,false$context);

    if (
    mb_strrpos($http_response_header[0], '400')) 
    {
            echo 
    "Something's wrong with my request : " .$json_response;
            return;
    }
    else if (
    mb_strrpos($http_response_header[0], '200')) //HTTP RESPONSE 200, all is OK
    {
            
    $obj json_decode($json_response);
            
            
    $non_working_days=$obj->{'result'}->{'non_working_days'};
            foreach(
    $non_working_days as $key => $value) {
              echo 
    "'$key',";
            }
        
    }
            
      
    ?>

    and here is the result (may 11 is a custom closure date, may 25 is a standard public holiday)

    Stock exchange calendars

    We do cover the following stock exchanges:

    Europe
  • London Stock Exchange
  • Paris, Amsterdam, Brussels, Lisbon, Madrid, Milan
  • Börse Frankfurt
  • Börse Zürich

  • America
  • New York Stock Exchange
  • Toronto Stock Exchange

  • Pacific
  • Australian Stock Exchange

  • When you query the API, the response's working days value correponds to the number of trading days.

    Note that in Paris, Amsterdam, Brussels, Lisbon, Madrid, Milan, Sydney, trading ceases at 14:00 on the 24th and 31th of december. Therefore, the API will count each of those days as 0.5 working day and 0.5 public holiday.

    What about hours of quotation?

    By default, it you omit the work_hours parameter, we apply the week hours schedule of the stock exchange, so the work_hours field in the response correponds to the number of hours of trading hours over the period.
    Let's have a look at an example:

    Suppose we want to know how many hours the market was open at Euronext on 2013-12-31:



    This script will output "Number of trading hours at Paris Euronext on 2013-12-31 : 5.083 h (5h05)"
    Indeed the market opens at 9:00 and closes at 14:05 on december 24th and 31th.

    If you want to visualize the week time schedule applied, you can go to the correponding working days website, in the setup screen, choose the "Bourse de Paris (Euronext)" preset configuation, under the "Work hours" tab-pane :


    Know your quota

    Each API call consumes part of your monthly quota. The days removed from your quota after a query is equal to the lengh in days of the resulting period.
    When you send a request like "country_code=CA&command=analyse&start_date=2019-01-01&end_date=2019-12-31" , it will take off 365 days of your monthly quota because they are 365 days in the year 2019.
    When you send a request like "country_code=FR&command=add_working_days&start_date=2020-01-01&increment=100", it will take off 147 days of your monthly quota because the resulting period is 147 days long.
    Note that when you send a request like "command=address_to_configuration", it will remove 600 days from your monthly quota for any given address.
    The monthly quota is reset at the end of each month at midgnight UTC+1.
    During the month, you will receive an automatic email alert when you reach 80% of your quota, and when you reach 100% of your quota.

    At any time, you can query your quota through the API, with the command quata. It will return the state of your plan (1:active, 2:cancelled, -1:error), your current quota (days left to be analysed within this month) and the quota that will be available next month.

    A request on command=quota does not consume any of your quota.

    Arguments

    Name Description

    key

    Required
    Your personal API key

    command

    Required
    The name of the service you want to call. quota


    The URL

    https://api.workingdays.org/1.2/api.php?key=MYPERSONALKEY&command=quota


    and the service is going to reply with a JSON response like that:

    Securing your code

    Before you go live, you want to make sure your code is robust.

    First, adding a changing HTTP parameter can be a good hack to avoid all the caches mechanism that could be met on the road.

    Next handling exception properly is a key thing to do.
    You need to check the HTTP STATUS code of the web service response.
    If you get an HTTP 200, all is ok.
    If you get 400, something is wrong with your request or your quota has been exceeded: you should look at the response string and maybe implement some alert for yourself.
    In any other case, you might want to implement one or several retries because networks failures happen.

    After you get an HTTP 200, you need to parse the response string (decode the JSON). This operation can fail too for an unknown reason: we suggest handling and logging any exception there also.

    PHP example