【问题标题】:set timezone per request in spring在春季为每个请求设置时区
【发布时间】:2016-07-05 12:42:34
【问题描述】:

我在UTC 时区的数据库中有数据,客户端上有一些特定于时区的逻辑。

决定在用户​​的时区从服务器返回数据,所以有一个流程:

  1. 客户端通过javascript检测用户的时区
  2. 在自定义标头中发送(即"X-TIMEZONE"
  3. 服务器拦截请求(在Filter)并为其设置当前时区(每个请求)
  4. 服务器处理转换并将数据返回给他所在时区的用户

所以问题是设置请求范围的时区,它甚至可能吗?

我发现Timezone.setDefault() 通常会为应用程序设置时区。

谢谢。

【问题讨论】:

  • 将时区存储在请求范围的 Spring bean 中,并在必要时使用它(处理日期和时间时)。无法在 JVM 中设置请求范围的时区,因为 JVM 本身对范围一无所知。
  • 在 Java8 中有一个类 ZonedDateTime。您可以将 zone 传递给 dao 并在其中创建分区日期时间。
  • 实际上,TimeZone.setDefault 会影响在该 JVM 中运行的 所有应用程序 的所有线程。这样做只是作为最后的手段。而是传递一个表示所需时区的对象并在可选的时区参数中使用它。

标签: java spring date datetime


【解决方案1】:

希望我能正确理解您的问题。几周前我遇到了类似的问题,这是我的解决方案。我的代码托管在时间为 UTC 的地方,因此如果您的代码未托管在那里,您可以执行此操作 Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 以使其成为 UTC。我传入的可变时区正是我想要的目标时区。这基本上会根据您想要的时区添加或减去毫秒以将其转换为时间。时间的日历对象应该是你要找的时间。

Calendar time = Calendar.getInstance();
time.setTime(date);
TimeZone localTimeZone = TimeZone.getTimeZone(timezone);
int offSet = localTimeZone.getOffset(date.getTime());
time.set(Calendar.MILLISECOND, time.get(Calendar.MILLISECOND) + offSet);

在此链接中,您可以找到有效时区选项的列表。http://tutorials.jenkov.com/java-date-time/java-util-timezone.html

【讨论】:

  • 这是一个糟糕的方法。您不应该自己计算偏移量的调整。让日期时间类进行实际计算和调整。 Aldo,您正在使用已被 java.time 取代的旧的麻烦类。
【解决方案2】:

您可以尝试检测客户端的时区。但最终确定用户所需时区的唯一可靠方法是询问她/他。

TimeZone.setDefault 影响在该 JVM 中运行的所有应用程序的所有线程中的所有代码。这样做只是作为最后的手段。而是传递一个表示所需时区的对象,并在可选的时区参数中使用它。

Java 早期版本捆绑的麻烦的旧日期时间类已被 Java 8 及更高版本中内置的 java.time 类所取代。大部分功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7,并在 ThreeTenABP 中进一步适应 Android。

获取 UTC 中的当前时刻。

Instant instant = Instant.now();

应用时区以获得ZonedDateTime

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

要创建表示该值的字符串,请调用toString 或使用DateTimeFormatter。 Search Stack Overflow 有很多例子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-28
    • 1970-01-01
    相关资源
    最近更新 更多