CASE: use advance_date filters

Today we are going to show you an example of how you can work with the date filters advance_months, advance_days, advance_weeks and retract_days (and by extension other advance_date filters which are listed here) to interact with dates and retrieve a certain date automatically. These filters enable you to simply move forward (for the advance filters) or go back (for the retract filters) a calculated number of days, months or weeks. Although the use might be straightforward as you’re just adding/subtracting days, weeks or months, these filters can be a great asset when trying to calculate dates, limiting the need to loop over data (thus increasing performance).

In this case, we want to automatically calculate the date of the next ordinary shareholders meeting based on inputs provided by the user. First, we need to create input fields where the user can input the required data. In this case, the user can indicate that the shareholders meeting falls on “the xth day of a certain month (e.g. the third Friday of May)”.

1. Creation of inputs

We will start this case by creating 3 inputs:

  • A dropdown to select the applicable day of the week (Monday, Tuesday, etc.)
  • A dropdown to select the applicable month
  • A dropdown to enable the user to select which day of the month it should be (e.g. the first, second, third, fourth or last Friday of that month). We will add the following options to the dropdown: “1”, “2”, “3”, “4” and “last”.

First, we will assign variables containing the options for the 3 inputs:

{% comment %}Assign options and option values to pick the applicable day of the week. We left Sunday out as day usually isn not picked for the shareholders meeting.{% endcomment %}
{% assign days_options = "Monday|Tuesday|Wednesday|Thursday|Friday|Saturday" %}
{% assign days_option_values = "1|2|3|4|5|6" %}

{% comment %}Assign options and option values to pick the applicable month. {% endcomment %}
{% assign months_options = "January|February|March|April|May|June|July|August|September|October|November|December" %}
{% assign months_option_values = "01|02|03|04|05|06|07|08|09|10|11|12" %}

{% comment %}Assign options and option values to pick the number of the day. Often, the last day of a month is chosen, so we have foreseen this option. In addition to this, users can the select the firs, second, third or fourth applicable day of the month.{% endcomment %}
{% assign number_options = "1st|2nd|3rd|4th|last" %}
{% assign number_option_values = "1|2|3|4|last" %}

With these variables, we can now create the relevant inputs. The user will able to select the number, the applicable day and the applicable month to enable to date calculation.

{% stripnewlines %}  
{% input custom.av.number_days as:select options:number_options option_values:number_option_values %}    
{% input custom.av.chosen_day as:select options:days_options option_values:days_option_values %}  of   
{% input custom.av.chosen_month as:select options:months_options option_values:months_option_values %}    
{% endstripnewlines %}

Based on this data we can now proceed to automatically calculate the exact date for the shareholders meeting.

We first assign the above mentioned database variables to local variables in accordance with our liquid guidelines. This will make these variables much easier to reference further down the code.

{% assign chosen_month = custom.av.chosen_month %} 
{% assign chosen_day = custom.av.chosen_day %} 
{% assign chosen_number_day = custom.av.number_days %}

We will also assign the end date of the book year to a variable and apply the filter %m in order to retrieve the correct month in a number format. This filter will give us the month as a 2 digit number, the same format of the option values assigned to the variable months_option_values above. This will enable to us to make successful calculations later on.

{% assign year_end_date = period.year_end_date %}
{% assign month_year_end_date = year_end_date | date:"%m" %}

2. Calculations

We now have the relevant data we need to calculate the exact date of the shareholders meeting. Let’s move on to the actual calculation.

Step 1: Calculate in what year the applicable month falls

We first need to make sure we calculate the correct month and year where the next shareholders meeting will take place. We will do this by calculating how many months we need to advance to get to the correct date, calculating from the year end date we already assigned.

To do this, we calculate the difference between the year end date of the book year and the month selected in the dropdown. As we applied the %m filter on the date, we will get a value (01, 02, 03, etc.) to calculate with, similar to what we have as option values in the chosen month.

:information_source: When doing the calculation, remember to wrap the variables with INT() to convert the data to an integer. If you don’t do this, the calculation wouldn’t be successful as these variables contain strings (this is always the case for data originating from dates).

{% assign difference_months = INT(month_year_end_date)-INT(chosen_month) %}

This difference can then be used to calculate how many months we need to advance to reach the chosen month and assign this number to a new variable called months_to_advance. The formula to calculate the months to advance is different depending on whether the difference calculated above is greater or lower than 0 as explained in the code below.

  {% if difference_months > 0 %}
    {% comment %}If the difference is > 0, then we need to use the formula '12-(number of the current month)+(number of the chosen month)'. E.g. if the month of the year end is 12 and the shareholders meeting is held in April, the formula is 12-12+4. This results in 4, which is indeed the number of months we need to advance to get from December to April.{% endcomment %}
    {% assign months_to_advance = 12-INT(month_year_end_date)+INT(chosen_month) | integer %}
  {% else %}
    {% comment %}If the difference is anything else, we can use a simple formula by subtracting the number of the chosen month from the month of the year end date. E.g. if the year end month is March and the shareholders meeting is held in September, then we can do 9-3. By advancing 6 months, we will indeed go from March to September.{% endcomment %}
    {% assign months_to_advance = INT(chosen_month)-INT(month_year_end_date) | integer %}
  {% endif %}

We can now use the number stored in the months_to_advance variable in combination with the advance_months filter to retrieve the end date of the applicable month and year, starting from the year end date.

{% assign applicable_month_end_date = year_end_date | advance_months:months_to_advance %}

Step 2: Calculate the first applicable weekday of the month

We are now in the correct month of the correct year. The next step is reaching the first applicable day (Monday/Friday/…) the user selected in the dropdown. For this, we need to calculate the first day of that applicable and check what day it is using the %u filter, which gives us a value of 1 to 7, depending on the applicable day. Remember, we have already used the some format in the option values of the relevant input (although we didn’t add the 7 to exclude Sunday).

{% assign first_day_of_applicable_month = applicable_month_end_date | date:"1/%m/%Y"  %} 
{% assign day_of_applicable_month = first_day_of_applicable_month | date:"%u" %}

Similar to what we already did above in step 1, we will now calculate the difference between the calculated first day of the applicable month and the day chosen by the user in the dropdown. This difference will be used to calculate how many days we need to advance to reach the chosen day (if needed). We again wrap the variables with INT().

{% assign difference_days = INT(day_of_applicable_month)-INT(chosen_day) %}`

This difference can then be used to calculate how many days we need to advance to reach the chosen month and assign this number to a new variable called days_to_advance. The formula to calculate the days to advance is different depending on whether the difference calculated above is greater or lower than 0 as explained in the code below.

{% if difference_days > 0 %}
   {% comment %}If the difference is > 0, then we need to use the formula 7-(number of the current day)+(number of the chosen day). E.g. if the first day of the Month is Sunday, which is number 7 and the chosen day is Friday, the formula is 7-7+5. This results in 5, which is indeed the number of days we need to advance to get from Sunday to Friday.{% endcomment %}
   {% assign days_to_advance = 7-INT(day_of_applicable_month)+INT(chosen_day) %}
{% else %}
   {% comment %}If the difference is anything else, we can use a simple formula by subtracting the number of the chosen day from the first day of the applicable month.{% endcomment %}
   {% assign days_to_advance = INT(chosen_day)-INT(day_of_applicable_month) %}
{% endif %}

We can now use the advance_days filter in combination with the value stored in the days_to_advance variable to advance to the first applicable day (e.g. the first Monday) of the applicable month.

{% assign first_applicable_day_of_applicable_month = first_day_of_applicable_month | advance_days:days_to_advance %}

Step 3: Calculate the exact date of the shareholders meeting

We have now calculated the first applicable day of the correct month. Finally, we now need to reach the xth time that day is present within the month. E.g. we now have the first Monday of the month. But if the user selected the 3rd Monday, we’ll need to advance to that day.

The calculation on how to do this differs depending on whether the user has selected “last” or not. If the user has selected “last”, we will do things differently as we won’t need step 2. We will just count back from the end date of the applicable month (stored in applicable_month_end_date) which we already calculated in step 1.

Below, you can find the find the calculation for both the “last’ option and the others. The correct calculation is scoped in based on an unless-statement. We have provided more information on what’s being calculated within the comments in the code.


  {% unless chosen_number_day == "last" %}

    {% comment %}if the user didn not select the last day of the month, we can calculate the weeks to advance by subtracting 1 from the relevant input. The user will have selected 1, 2, 3 or 4. As an example, the below calculation will return 0 if it is the first day of the month (stored as 1). As we already calculated that day in step 2, we don not need to advance anymore. Subtracting 1 from the chosen number will give us the exact number we need to advance to the xth applicable day within that month. We will then use the "advance_weeks" filter to advance to the correct date.{% endcomment %}

    {% assign weeks_to_advance = INT(chosen_number_day)-1 %}
    {% assign date_shareholders_meeting = first_applicable_day_of_applicable_month | advance_weeks:weeks_to_advance %}

  {% else %}

    {% comment %}If the user chose the "last" applicable day. We can calculate the difference between the end day of that month and the applicable day selected by the user. Similar to steps 1 and 2, the calculation is again different based on whether the difference is greater or lower than 0. We will then know how many days we need to go back to reach the correct day. We can use the "retract_days" filter to go back the calculated number of days{% endcomment %}

    {% assign day_of_applicable_month = applicable_month_end_date | date:"%u" %}
    {% assign difference_days = INT(day_of_applicable_month)-INT(chosen_day) %}

    {% if difference_days > 0 %}
      {% assign days_to_retract = difference_days %}
      {% assign date_av = applicable_month_end_date | retract_days:difference_days %}
    {% else %}
      {% assign days_to_retract = 7-INT(chosen_day)+INT(day_of_applicable_month) %}
      {% assign date_shareholders_meeting = applicable_month_end_date | retract_days:days_to_retract %}
    {% endif %}

  {% endunless %}

3. Printing the calculated date

The correct calculated date of the shareholders meeting is now stored in the date_shareholders_meeting variable. We can now assign print this date with the date filter to make sure it is printed in the date format we require.

Date general meeting: {{ date_shareholders_meeeting | "%d/%m/%Y" }}

Let’s test our code with the following input (3rd Friday of May):

Printing the above mentioned code will give us the following date:
image (1)

When checking the calendar, the next shareholders meeting should indeed fall on 20 May 2022.


That concludes this use-case concerning the advance_date filters. Other use-cases could be:

  • Calculating pre-set deadlines automatically (e.g. a certain action needs to be performed within 30 days of a certain date)
  • Calculating the exact date for holidays (e.g. in Belgium, the holiday “Ascension day” is always celebrated the 40th day after Easter).

If you have any questions or remarks as regards this case, please do not hesitate to ask questions. We are always happy to provide assistance whenever needed.