Handling Date objects in Thymeleaf
In this post, We will see how to format and work with date objects in thymeleaf templates using the #dates utility with an example.
Table of contents
Introduction
Before getting in further, read a little about thymeleaf and how it can help build dynamic web applications. The #dates object in thymeleaf deals with date objects in thymeleaf model. With its help, we can format and extract date components.
Formatting Dates in Thymeleaf
The typical way to format a date object would be through SimpleDateFormat.
@RequestMapping("/test")
public String test(Model model) {
DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
String dateString = dateFormat.format(new Date());
model.addAttribute("myDate", dateString);
return "test";
}
Code language: Java (java)
However, If we retained it as a date object, we could use it in many places of thymeleaf templates. For this reason, you should always use the #dates utility. For instance, we can remove the entire format logic in the controller by doing the below.
<div>`dd/MM/yyyy` format is : <span th:text="${#dates.format(myDate, 'dd/MM/yyyy')}"></span></div>
<div>`yyyy-MMM-dd` format is : <span th:text="${#dates.format(myDate, 'yyyy-MMM-dd')}"></span></div>
<div>`yyyy-MM-dd : hh:mm:ss a` format is : <span th:text="${#dates.format(myDate, 'yyyy-MM-dd : hh:mm:ss a')}"></span></div>
Code language: HTML, XML (xml)
With this approach, the date object is preserved throughout the thymeleaf template execution. That is, you get to use the date object in different ways. Also, The format string follows the SimpleDateFormat specifications. This way, you don’t have to learn anything new.
Default date Format
By Default thymeleaf uses the toString() method for object to String conversion. So you can safely print date if you don’t mind the default formatting from Date.toString() method.
<div>Default Format : <time th:text="${myDate}"></time></div>
Code language: HTML, XML (xml)
ISO date Format
To convert dates into ISO strings, you can use the #dates.formatISO method.
<div>ISO format is : <time th:text="${#dates.formatISO(myDate)}"></time></div>
Code language: HTML, XML (xml)
Notice how all the formatting uses default locale of the application. To change this behaviour you need to use #temporals.
Creating Date objects
Occasionally, you may need to use a specific date or the current date within the templates. For this reason, thymeleaf provides two ways to create date objects.
Date object with current Timestamp
If you want a new date object with current timestamp,the #dates.createNow() will help you.
<div>Current Date : <time th:text="${#dates.createNow()}"></time></div>
Code language: HTML, XML (xml)
This approach is helpful when you need to show the generated timestamp of the view in thymeleaf. Also, there are other variants like #dates.createToday() which creates only date without time component.
Creating objects for Specific Date
Thymeleaf offers methods to create dates based on date and time components.
<div>Specific Date : <time th:text="${#dates.create(1989,10,18)}"></time></div>
<div>Specific Date and time : <time th:text="${#dates.create(1989,10,18,22,12,47,345)}"></time></div>
Code language: HTML, XML (xml)
Accessing Date Components in Thymeleaf
Furthermore, You can decompose the date object into it’s components. For example, you can do the following.
<h2>Date Components</h2>
<div>The Day of Week is : <time th:text="${#dates.dayOfWeekName(myDate)}"></time></div>
<div>The name of the month is : <time th:text="${#dates.monthName(myDate)}"></time></div>
<div>The year is : <time th:text="${#dates.year(myDate)}"></time></div>
<div>The hour is : <time th:text="${#dates.hour(myDate)}"></time></div>
<div>The milliseconds is : <time th:text="${#dates.millisecond(myDate)}"></time></div>
Code language: HTML, XML (xml)
It is important here to note that the results are relative to the server timezone.
Handling Arrays and collections of Date
All the above methods in both formatting and component can be applied to an Array or list of Objects as well. To perform operations on Arrays, you should use the methods prefixed with ‘array’. For example, if the given array of dates is arrayOfDates, then you can format all at one go as shown below.
<div th:each="date , stat : ${#dates.arrayFormat(arrayOfDates,'yyyy-MM-dd')}">
The formatted array [<span th:text="${stat.count}"></span>] is : <time th:text="${date}"></time>
</div>
Code language: HTML, XML (xml)
Similarly you can handle lists and sets using #dates.listFormat() and #dates.setFormat() methods. All the above methods return a formatted array or collection string which can then be looped through th:each.
Along with this, you can even use component extraction methods as shown below.
<div th:each="date , stat : ${#dates.arrayDay(arrayOfDates)}">The Day of array element [<span th:text="${stat.count}"></span>] is : <time th:text="${date}"></time></div>
<div th:each="date , stat : ${#dates.listDay(arrayOfDates)}">The Day of list element [<span th:text="${stat.count}"></span>] is : <time th:text="${date}"></time></div>
<div th:each="date , stat : ${#dates.setDay(listOfDates)}">The Day of set element [<span th:text="${stat.count}"></span>] is : <time th:text="${date}"></time></div>
Code language: HTML, XML (xml)
You can find more about all the methods here in this official documentation.
Conclusion
To summarize, you can perform various types of date formatting using the #dates utility in thymeleaf. It can also be helpful when you have to extract specific components of a date like hours/minutes/seconds etc.
If you are interested in this article, you might also appreciate reading the following titles.