当前位置: 首页 > 知识库问答 >
问题:

Thymeleaf时区和时区日期

长孙宜
2023-03-14

我有一个使用百里香叶作为视图层的Spring Boot Web应用程序,我需要显示一些特定时区的日期(CET = UTC 1/UTC 2)。

服务器设置为UTC,所有日期都以UTC格式作为datetime存储在我的数据库中,这很好。

现在我想在我的超文本标记语言页面上显示这个日期,不是UTC格式,而是使用胸膜时序的CET,但它似乎不起作用。

date对象是一个Java Instant。

从 DB 检索到的日期是 (例如) 2021-02-17T16:18:21Z,显示如下:

<div th:text="${#temporals.format(user.lastAccess, 'dd/MM/yyyy HH:mm')}"></div>
=> 17/02/2021 16:18

但是我想展示一下:

17/02/2021 17:18

所以我使用了:

<div th:text="${#temporals.format(user.lastAccess, 'dd/MM/yyyy HH:mm', new java.util.Locale('it', 'IT'))}"></div>

但日期始终显示为UTC

17/02/2021 16:18

百里香的< code>Java8TimeDialect已正确配置。

我正在使用:

Spring Boot 2.2.4
Thymeleaf 3.0.11.RELEASE

我做错了什么?

谢谢。

共有3个答案

吕衡
2023-03-14

< code > temporal 是自动创建的。它采用系统默认时区。

public Temporals(final Locale locale) {
    this(locale, ZoneId.systemDefault());
}

创建过程并不是真正设计为可定制的,所以最好的方法似乎是更改系统默认的ZoneId。

对我来说,最好的方法是在Docker容器中设置预期的时区。在我的情况下,服务器上的日期已经正确。要将其传播到容器卷,可以使用:

-v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro
乐正晟
2023-03-14

您需要将时间戳转换为具有指定时区的日期时间。下面给出了一些方法

使用< code > zoned datetime # with zonesameinstant :

import java.time.ZoneId;
import java.time.ZonedDateTime;

class Main {
    public static void main(String[] args) {
        String timestamp = "2021-02-17T16:18:00.00Z";
        ZonedDateTime zdt = ZonedDateTime.parse(timestamp);
        ZonedDateTime zdtAtCet = zdt.withZoneSameInstant(ZoneId.of("Europe/Paris"));
        System.out.println(zdtAtCet);
    }
}

现在,您可以在代码中使用相应的OffsetDateTime对象,例如。

<div th:text="${#temporals.format(zdtAtCet, 'dd/MM/yyyy HH:mm')}"></div>

ZonedDateTime旨在自动调整由于夏令时而导致的与UTC的偏移量变化。

如果您要处理与 UTC 的固定偏移量,例如 UTC 01:00,您还可以使用偏移日期时间#与偏移量阈值初始例如

import java.time.OffsetDateTime;
import java.time.ZoneOffset;

class Main {
    public static void main(String[] args) {
        String timestamp = "2021-02-17T16:18:00.00Z";
        OffsetDateTime odt = OffsetDateTime.parse(timestamp);
        OffsetDateTime odtAtUtcPlus1 = odt.withOffsetSameInstant(ZoneOffset.of("+01:00"));
        OffsetDateTime odtAtUtcPlus2 = odt.withOffsetSameInstant(ZoneOffset.of("+02:00"));
        System.out.println(odtAtUtcPlus1);
        System.out.println(odtAtUtcPlus2);
    }
}

输出:

2021-02-17T17:18+01:00
2021-02-17T18:18+02:00

您还可以使用即时#atZone即时#在Offset分别执行上面提到的第一个和第二个解决方案,例如:

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

class Main {
    public static void main(String[] args) {
        String timestamp = "2021-02-17T16:18:00.00Z";
        Instant instant = Instant.parse(timestamp);
        OffsetDateTime odtAtUtcPlus1 = instant.atOffset(ZoneOffset.of("+01:00"));
        ZonedDateTime zdtAtCet = instant.atZone(ZoneId.of("Europe/Paris"));
        System.out.println(odtAtUtcPlus1);
        System.out.println(zdtAtCet);
    }
}

输出:

2021-02-17T17:18+01:00
2021-02-17T17:18+01:00[Europe/Paris]

从跟踪:日期时间中了解有关现代日期时间 API 的更多信息。

公西浩
2023-03-14

没有Thymeleaf时间函数可以为您执行时区转换。

需要为Instant值指定一个时区,而不是区域设置(Java区域设置不会以这种方式操作时区)。

你可以在Java中做你需要做的事情:

Instant myInstant = Instant.parse("2021-02-17T16:18:00.00Z");
ZonedDateTime myZDT = myInstant.atZone(ZoneId.of("CET"));

现在,您可以使用以下百里叶片段:

<div th:text="${#temporals.format(myZDT, 'dd/MM/yyyy HH:mm')}"></div>

这将在div中生成以下内容:

17/02/2021 17:18

现在,时间显示为17:18,而不是16:18

更新:请务必阅读OleV.V的评论。关于已弃用的缩写,包括注释:

不推荐使用三个字母的时区缩写,而且常常模棱两可,因此不要使用ZoneId.of(“CET”)。使用类似欧洲/维也纳或欧洲/San_Marino的时区ID,因此采用地区/城市格式。

因此,以下问题可能有用:

java.time?的官方区域名称列表在哪里?

以及相关的代码片段:

Set<String> zoneIds = ZoneId.getAvailableZoneIds();
for (String zone : zoneIds) {
    System.out.println(zone);
}
 类似资料:
  • 然后将变量持久化到MySQL表列中。 然而,虽然通过调试,我看到对象显示在正确的时区GMT+1,但在数据库上持久化时,它是一个GMT时区,所以要追溯一个小时。 使用函数返回一个GMT+1日期。 连接字符串为,没有任何参数。 编辑:找到这段代码

  • 问题内容: 这是我的约会日期“ 15-05-2014 00:00:00” 如何将IST转换为UTC即(到14-05-2014 18:30:00) 基于时区到UTC时区。 我的代码是 如果用户从任何区域输入相同的日期,则将获得UTC时间(例如:从澳大利亚,然后从15-05-2014 00:00:00到14-05-2014 16:00:00) 请任何建议。 问题答案: 您不能将日期值“转换为”其他时区

  • > 如何将IST转换为UTC,即(至2014年5月14日18:30:00) 我的代码是 > 如果用户从任何区域输入相同的日期,则将获得UTC时间(例如:从澳大利亚输入,然后是2014年5月15日00:00:00至2014年5月14日16:00:00) 请提出任何建议。

  • 我正在开发一个处理日期的spring boot应用程序。当我提交一个具有< code>startDateTime和< code>endDateTime的约会对象(两者都属于< code>java.util.Date类型)时,我会发送如下格式: 当数据持久化在数据库中时,它具有正确的时区,当我尝试检索我的数据时,当我调试时,它们似乎是正确的,但是,一旦它们被Jackson序列化,我就会有一个输出,其

  • 我有一个本地日期时间的字符串表示和一个Java时区。 我正在尝试以 MM/dd/yyyy HH:mm:ssZ 格式获取输出,但我无法弄清楚如何使用正确的日期时间和时区创建日历或 JodaTime 对象。如何将时区转换为可以通过简单日期格式“Z”或“z”解析的值? 和 返回 这是 。 是创建日历或Joda日期时间并通过解析字符串“08/14/2014 15:00:00”来设置各个年/月/日/小时/分

  • 问题内容: 我需要一个具有日期和年份指定值的jsDate对象。我希望给我Date对象2000作为价值,但如果我的电脑的时间设定到芝加哥时区,我得到,和布宜诺斯艾利斯:。 有没有一种方法可以创建Date对象,并返回我们在构造函数中设置的日期,无论在用户计算机上设置了什么时区? 更新:我需要在另一个库中使用此Date对象(该库调用其方法,因此使用UTC getter并没有真正的帮助。 问题答案: 在J