Skip to content

Instantly share code, notes, and snippets.

@emiloberg
Last active August 13, 2020 21:18
Show Gist options
  • Save emiloberg/b4382b9a6946a183cddd to your computer and use it in GitHub Desktop.
Save emiloberg/b4382b9a6946a183cddd to your computer and use it in GitHub Desktop.
This is how you get a real date/time-stamp (such as article published date) in Freemarker in Liferay. With support for multilingual sites. When working with multilingual/non-English sites, date/time-stamp can be a bit of a headache as the date strings are strings with english words in them, such as Thu, 08 May 2014 11:48:00 +0000, rather than a …
<#-- ----------------------------------------------------------------- ->
-
- GETTING REAL TIME/DATE-STAMP
-
- When we ask Liferay for the create date of an article (or really we
- ask Liferay for the 'display-date' which is settable by the user) we get
- a string looking like this: 'Thu, 08 May 2014 11:48:00 +0000'. This
- string will always be in english and when we want to create a datetime
- object from it, we need to parse it with english locale.
-
- Therefor, when working with a non-english site we need to:
- 1) Save the original locale (e.g. 'sv_SE') to a variable
- 2) Set locale to 'en_US'
- 3) Parse the date string and create a date object from it
- 4) Set locale back to original locale, from variable.
- 5) Create a date string from the date object.
-
- Common pitfall:
- Swedish example: Most dates have similar names in Swedish and English.
- e.g.: the English dates '08 Jan 2014', '08 Feb 2014', '08 Mar 2014',
- '08 Apr 2014' are all the same as their Swedish counterpart,
- and are therefor parseable without doing any magic.
-
- However '08 May 2014' is not the same in Swedish ('08 maj 2014'),
- neither is 'oct'/'okt'.
-
- When developing, make sure you're working with content with
- display-date may or october.
-
<- ------------------------------------------------------------------ -->
<#-- Get Display Date (not created-date which is equal to when a user last
modified the content)
-->
<#assign date = .vars['reserved-article-display-date'].data>
<#-- Load timezone from language files, as we have multiple timezones.
If we just had one timezone, set it like:
<#setting time_zone = "Europe/Stockholm">
-->
<#setting time_zone = languageUtil.get(locale, "template-timezone")>
<#-- Saving original locale to be able to reset it to that later -->
<#assign originalLocale = locale>
<#-- Set locale to en_US to be able to parse the date string and make it a date object -->
<#setting locale = 'en_US'>
<#assign date = date?datetime("EEE, d MMM yyyy HH:mm:ss Z")>
<#-- Set locale to the real (original) locale -->
<#setting locale = originalLocale>
<#-- As we want to display the date in different formats depending on the
language we get the date/time-format from the language files. Else
we could set it like this:
<#assign dateTimeFormat = "d MMMM yyyy">
-->
<#assign dateTimeFormat = languageUtil.get(locale, "template-datetime-format")>
<#-- Create a date string from the date object -->
<#assign date = date?string(dateTimeFormat)>
<#-- END GETTING REAL TIME/DATE-STAMP -->
<#-- ----------------------------------------------------------------- -->
@deadcyclo
Copy link

This isn't quite accurate. This will only work on sites that have en_US as the default language. This will fail on sites that have a different locale set as default. See here: http://gsmblog.net/blog/date-objects-liferay-freemarker-web-content-templates/

@emiloberg
Copy link
Author

Hm, are you sure? I have a few sites with another language than en_US running as default.

The difference between your and my code is:

Line 8 <#setting locale = localeUtil.getDefault()>

vs

Line 48 <#setting locale = 'en_US'>

I'm explicity setting the locale to en_US and then parsing the string whereas you're asking for the default locale.

@petersiman
Copy link

Hi, I agree with @deadcyclo - we have ran into a problem using

<#setting locale = 'en_US'>

not while displaying the content on page, but during content export (to PDF) - using getDefault() fixed the problem.

@nhan0987
Copy link

@emilberg Hi, are you test with few language ? I got error when use vietnamese. "Th 4, 27 thg 6 2018 09:22:00 +0700" . This is date get from reserved-article-display-date.

Cant parse to date object from this. I got error on line

<#assign date = date?datetime("EEE, d MMM yyyy HH:mm:ss Z")>

@duracell80
Copy link

duracell80 commented Aug 13, 2020

Try this ... The trick I found working was to use ?long

<#assign date_display = .vars['reserved-article-display-date'].data>
<#assign date = .vars['reserved-article-modified-date'].data>
<#assign date = date?datetime("EEE, d MMM yyyy HH:mm:ss Z")>
<#assign date = date?long>

<#assign now = .now?long>

<p>1: ${date}</p>
<p>2: ${now}</p>
    

<#if date lt now>
    Past
<#elseif date gt now>
    Future
<#else>
    Present
</#if>

@duracell80
Copy link

duracell80 commented Aug 13, 2020

If as I do you need to check a modified date against a certain date. The following may help. My issue was that a Web Content Template referenced a new Structure field. Which works for this point forward but web content published in the past doesn't contain that field so chokes on if statements checking for stuff that doesn't exist. No matter how much I try using getData()?? I can't get freemarker to stop throwing errors.

// The date I made the fateful change and broke everyone's templates ...
<#assign changed = 1597352716000>

// When was this current now broken content last published ...
<#assign date = .vars['reserved-article-modified-date'].data>
<#assign date = date?datetime("EEE, d MMM yyyy HH:mm:ss Z")>
<#assign date = date?long>

// What is the epoch now
<#assign now = .now?long>

<p>1: ${date}</p>
<p>2: ${changed}</p>
<p>3: ${now}</p>
    
// Ok so was this content published before or after my fateful decision to add a field to the structure?
<#if date lt changed>
    Past
<#elseif date gt changed>
    Future
<#else>
    Present
</#if>

fresh-vs-stale-content-epoch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment