Liquid Solutions: Find the next Monday after a specific date (+ Ordinalized dates)

  • 11 July 2023
  • 0 replies
  • 128 views

Userlevel 2
Badge

Hello all,

 

Just sharing a solution that we came up with while working with a customer in case it might help future travelers. The customer wanted to use Liquid to find a date that is at least two weeks out, and then, if the date is not a Monday, find the next Monday after that given date.

 

Example: instead of the date Friday, July 14th, find the next possible Monday (Monday, July 17th), and then print out “the week of July 17th”.

 

The goal was to use the output in a message, so that is all we’ll cover here. This post doesn’t cover adding this output to a profile attribute to re-use later.

 

Solution

 

Here’s the Liquid we landed on (NOTE: formatting might be off if you copy and paste, so I would suggest the codeblock at the end of this message that has no “newline” characters or extra spaces):

{% assign start_date = YOUR_EPOCH_OR_ISO_TIMESTAMP | date: '%s' | plus: 0 %}
{% assign additional_days = 14 %}
{% assign day_of_week_after_additional_days = start_date | add_day: additional_days | date: '%u' %}
{% case day_of_week_after_additional_days %}
{% when 1 %}{% assign additional_days = additional_days | plus: 0 %}
{% when 2 %}{% assign additional_days = additional_days | plus: 6 %}
{% when 3 %}{% assign additional_days = additional_days | plus: 5 %}
{% when 4 %}{% assign additional_days = additional_days | plus: 4 %}
{% when 5 %}{% assign additional_days = additional_days | plus: 3 %}
{% when 6 %}{% assign additional_days = additional_days | plus: 2 %}
{% when 7 %}{% assign additional_days = additional_days | plus: 1 %}
{% endcase %}
{% assign month = start_date | add_day: additional_days | date: '%B' %}
{% assign day = start_date | add_day: additional_days | date: '%e' %}
{% capture ordinalized_day %}
{% case day %}
{% when "1" or "21" or "31" %}
{{ day }}st
{% when "2" or "22" %}{{ day }}nd
{% when "3" or "23" %}{{ day }}rd
{% else %}{{ day }}th
{% endcase %}
{% endcapture %}
Occurring during the week of {{month}} {{ordinalized_day}}

 

There are a few things happening in this code block: assignments, timestamp conversions, determining which day of the week the timestamp lands on, and ordinalization.

 

The following assignments are made: 

  • start_date correlates to the timestamp you wish to base the evaluation off of. For instance, you would replace YOUR_EPOCH_OR_ISO_TIMESTAMP with event.start_time if that variable exists. The timestamp can be either the epoch timestamp in seconds (preferred), or a valid ISO timestamp.
  • additional_days correlates to the number of days to look ahead, we’re using 14 so that the timestamp is always at least two weeks out.
  • day_of_week_after_additional_days is the day of the week after adding additional_days to the start_date variable.
  • month is the month the new timestamp lands in 
  • day is the day of the month the new timestamp lands in
  • ordinalized_day is the ordinalized version of the variable day

 

The following liquid tags and filters are used:

  • assign and capture (to set variables)
  • case (a simplified method of handling a lengthy if statement)
  • date to convert timestamp values. See the table in this document under the subheading “strptime(date, format, now=self.now)” for the date filter codes used.
  • plus, specifically I’m using plus: 0 to ensure the converted values are captured as a number and not a string without modifying the input
  • add_day a simplified method of adding the total of 86400 (seconds in one day) multiplied by the number of days

How to write your own solution

 

To do something similar, you can copy and edit the code block below, or follow these steps:

  1. Convert your timestamp to the epoch timestamp in seconds. Customer.io uses epoch timestamps for all sorts of date related things, so it’s best if you can begin with an epoch timestamp. However, if you have an ISO timestamp, you can convert that using the Liquid filter date: ‘%s’
  2. Find out which day of the week your target timestamp will fall on using the date filter and the value %u (returns a number between 1-71 being Monday and 7 being Sunday)
  3. After figuring out which day of the week your timestamp lands on, to get to your ideal date, add N number of days to your target timestamp where N is the difference in the number of days based on the day of the week your target timestamp landed on.
  4. Finally, if you want to ordinalize your date, use the date filter with the code %e to get the value of the the day of the month without the 0 (zero) left padding, and then use a case statement:
    1. If the value is  121, or  31, append “st
    2. If the value is 2 or 22, append “nd
    3. If the value is 3, or 23, append “rd
    4. Otherwise, append “th

 

Here’s a better format of the codeblock shared above:

 

{% assign start_date = YOUR_EPOCH_OR_ISO_TIMESTAMP | date: '%s' | plus: 0 %}{% assign additional_days = 14 %}{% assign day_of_week_after_additional_days = start_date | add_day: additional_days | date: '%u' %}{% case day_of_week_after_additional_days %}{% when 1 %}{% assign additional_days = additional_days | plus: 0 %}{% when 2 %}{% assign additional_days = additional_days | plus: 6 %}{% when 3 %}{% assign additional_days = additional_days | plus: 5 %}{% when 4 %}{% assign additional_days = additional_days | plus: 4 %}{% when 5 %}{% assign additional_days = additional_days | plus: 3 %}{% when 6 %}{% assign additional_days = additional_days | plus: 2 %}{% when 7 %}{% assign additional_days = additional_days | plus: 1 %}{% endcase %}{% assign month = start_date | add_day: additional_days | date: '%B' %}{% assign day = start_date | add_day: additional_days | date: '%e' %}{% capture ordinalized_day %}{% case day %}{% when "1" or "21" or "31" %}{{ day }}st{% when "2" or "22" %}{{ day }}nd{% when "3" or "23" %}{{ day }}rd{% else %}{{ day }}th{% endcase %}{% endcapture %}Occurring during the week of {{month}} {{ordinalized_day}}

 

Hopefully this helps someone else out there working with dates in Liquid! 😊

 

 


0 replies

Be the first to reply!

Reply