Skip to content

Commit e36d928

Browse files
maibinKevinGilmore
authored andcommitted
How to work with dates in Thymeleaf (eugenp#960)
* How to work with dates in Thymeleaf * Fixes in PR for Thymeleaf
1 parent 82fc8cf commit e36d928

File tree

6 files changed

+94
-18
lines changed

6 files changed

+94
-18
lines changed

spring-thymeleaf/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target/

spring-thymeleaf/pom.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515
<org.slf4j.version>1.7.21</org.slf4j.version>
1616
<logback.version>1.1.7</logback.version>
1717
<!-- thymeleaf -->
18-
<org.thymeleaf-version>3.0.2.RELEASE</org.thymeleaf-version>
18+
<org.thymeleaf-version>3.0.3.RELEASE</org.thymeleaf-version>
19+
<org.thymeleaf.extras-version>3.0.0.RELEASE</org.thymeleaf.extras-version>
1920
<thymeleaf-layout-dialect.version>2.1.2</thymeleaf-layout-dialect.version>
2021
<!-- validation -->
2122
<javax.validation-version>1.1.0.Final</javax.validation-version>
2223
<hibernate-validator.version>5.3.3.Final</hibernate-validator.version>
2324
<org.hibernate-version>5.2.5.Final</org.hibernate-version>
2425

25-
<junit.version>4.12</junit.version>
26+
<junit.version>4.12</junit.version>
2627
<!-- Maven plugins -->
2728
<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version>
2829
<maven-war-plugin.version>2.6</maven-war-plugin.version>
@@ -78,6 +79,11 @@
7879
<artifactId>thymeleaf-layout-dialect</artifactId>
7980
<version>${thymeleaf-layout-dialect.version}</version>
8081
</dependency>
82+
<dependency>
83+
<groupId>org.thymeleaf.extras</groupId>
84+
<artifactId>thymeleaf-extras-java8time</artifactId>
85+
<version>${org.thymeleaf.extras-version}</version>
86+
</dependency>
8187
<!-- Logging -->
8288
<dependency>
8389
<groupId>org.slf4j</groupId>

spring-thymeleaf/src/main/java/com/baeldung/thymeleaf/config/WebMVCConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
1414
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
1515
import org.thymeleaf.TemplateEngine;
16+
import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
1617
import org.thymeleaf.spring4.SpringTemplateEngine;
1718
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
1819
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
@@ -74,6 +75,7 @@ public ViewResolver plainViewResolver() {
7475
private TemplateEngine templateEngine(ITemplateResolver templateResolver) {
7576
SpringTemplateEngine engine = new SpringTemplateEngine();
7677
engine.addDialect(new LayoutDialect(new GroupingStrategy()));
78+
engine.addDialect(new Java8TimeDialect());
7779
engine.setTemplateResolver(templateResolver);
7880
return engine;
7981
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.baeldung.thymeleaf.controller;
2+
3+
import java.time.Instant;
4+
import java.time.LocalDate;
5+
import java.time.LocalDateTime;
6+
import java.util.Date;
7+
8+
import org.springframework.stereotype.Controller;
9+
import org.springframework.ui.Model;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RequestMethod;
12+
13+
@Controller
14+
public class DatesController {
15+
16+
@RequestMapping(value = "/dates", method = RequestMethod.GET)
17+
public String getInfo(Model model) {
18+
model.addAttribute("standardDate", new Date());
19+
model.addAttribute("localDateTime", LocalDateTime.now());
20+
model.addAttribute("localDate", LocalDate.now());
21+
model.addAttribute("timestamp", Instant.now());
22+
return "dates.html";
23+
}
24+
25+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE html>
2+
<html xmlns="http://www.w3.org/1999/xhtml"
3+
xmlns:th="http://www.thymeleaf.org">
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>Baeldung - dates</title>
7+
</head>
8+
<body>
9+
<h1>Format ISO</h1>
10+
<p th:text="${#dates.formatISO(standardDate)}"></p>
11+
<p th:text="${#temporals.formatISO(localDateTime)}"></p>
12+
<p th:text="${#temporals.formatISO(localDate)}"></p>
13+
<p th:text="${#temporals.formatISO(timestamp)}"></p>
14+
15+
<h1>Format manually</h1>
16+
<p th:text="${#dates.format(standardDate, 'dd-MM-yyyy HH:mm')}"></p>
17+
<p th:text="${#temporals.format(localDateTime, 'dd-MM-yyyy HH:mm')}"></p>
18+
<p th:text="${#temporals.format(localDate, 'MM-yyyy')}"></p>
19+
20+
<h1>Show only which day of a week</h1>
21+
<p th:text="${#dates.day(standardDate)}"></p>
22+
<p th:text="${#temporals.day(localDateTime)}"></p>
23+
<p th:text="${#temporals.day(localDate)}"></p>
24+
25+
<h1>Show the name of the week day</h1>
26+
<p th:text="${#dates.dayOfWeekName(standardDate)}"></p>
27+
<p th:text="${#temporals.dayOfWeekName(localDateTime)}"></p>
28+
<p th:text="${#temporals.dayOfWeekName(localDate)}"></p>
29+
30+
<h1>Show the second of the day</h1>
31+
<p th:text="${#dates.second(standardDate)}"></p>
32+
<p th:text="${#temporals.second(localDateTime)}"></p>
33+
34+
</body>
35+
</html>

spring-thymeleaf/src/test/java/com/baeldung/thymeleaf/controller/ExpressionUtilityObjectsControllerIntegrationTest.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,29 +30,36 @@
3030
@WebAppConfiguration
3131
@ContextConfiguration(classes = { WebApp.class, WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class })
3232
public class ExpressionUtilityObjectsControllerIntegrationTest {
33-
33+
34+
@Autowired
35+
WebApplicationContext wac;
3436
@Autowired
35-
WebApplicationContext wac;
36-
@Autowired
37-
MockHttpSession session;
37+
MockHttpSession session;
3838

39-
private MockMvc mockMvc;
39+
private MockMvc mockMvc;
40+
41+
@Autowired
42+
private Filter springSecurityFilterChain;
4043

41-
@Autowired
42-
private Filter springSecurityFilterChain;
44+
protected RequestPostProcessor testUser() {
45+
return user("user1").password("user1Pass").roles("USER");
46+
}
4347

44-
protected RequestPostProcessor testUser() {
45-
return user("user1").password("user1Pass").roles("USER");
46-
}
48+
@Before
49+
public void setup() {
50+
mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilters(springSecurityFilterChain).build();
51+
}
4752

48-
@Before
49-
public void setup() {
50-
mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilters(springSecurityFilterChain).build();
51-
}
53+
@Test
54+
public void testGetObjects() throws Exception {
55+
mockMvc.perform(get("/objects").with(testUser()).with(csrf())).andExpect(status().isOk())
56+
.andExpect(view().name("objects.html"));
57+
}
5258

5359
@Test
54-
public void testGetDates() throws Exception{
55-
mockMvc.perform(get("/objects").with(testUser()).with(csrf())).andExpect(status().isOk()).andExpect(view().name("objects.html"));
60+
public void testDates() throws Exception {
61+
mockMvc.perform(get("/dates").with(testUser()).with(csrf())).andExpect(status().isOk())
62+
.andExpect(view().name("dates.html"));
5663
}
5764

5865
}

0 commit comments

Comments
 (0)