Java 使用 Joda 将 UTC 日期转换为本地日期

标签 java jodatime utc localtime

此代码可以正常工作,但我想使用 Joda-Time

public static Date dateFromUTC(Date date){
        return new Date(date.getTime() + Calendar.getInstance().getTimeZone().getOffset(date.getTime()));
    }

我尝试了这个,但它不起作用 - 这有什么问题?

public static Date dateFromUTC(Date date){
        return new DateTime(date).withZone(DateTimeZone.getDefault()).toDate();
    }

最佳答案

tl;博士

使用java.time类来代替。

Instant.now()        // Capture current moment in UTC. Always in UTC, by definition.

…还有…

ZonedDateTime.now()  // Capture current moment as seen through the wall-clock time of the people in the region of the time zone used by default in this JVM.

详细信息

正如其他人所说,您误解了这些类中涉及的概念。 java.util.Date 表示 UTC 中的某个时刻,始终采用 UTC,绝不会采用其他时区。所以问题中看到的代码是没有意义的。你太辛苦了!

java.time

Joda-Time 项目现已位于 maintenance mode 中,团队建议迁移到 java.time 类。 Joda-Time 和 java.time 之间的许多概念都很相似,因为这两个项目都是由同一个人 Stephen Colebourne 领导的。

当您准备好迁移时,请使用 Instant 代替 java.util.Date

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

instant.toString(): 2018-01-23T12:34:56.123456789Z

使用 ZonedDateTime 来代替 java.util.Calendar 来表示通过特定区域(时区)的挂钟时间看到的时刻。

大陆/地区的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的( !)。

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;  // Same moment, same point on the timeline, different wall-clock time.

作为快捷方式,如果您只需要分区时间,可以跳过即时

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Capture the current moment as seen by people in a certain time zone.

您可以通过提取 Instant 对象从那里获取 UTC。

Instant instant = zdt.toInstant() ;  // Same moment, same point on the timeline, but viewed with the wall-clock time of UTC.

实际上,在 java.util.Date 深处分配了一个时区,但与我们这里的讨论无关。令人困惑?是的。避免旧的 Date/Calendar 和相关的遗留日期时间类造成可怕困惑的众多原因之一。


关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于 maintenance mode 中,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle Tutorial 。并在 Stack Overflow 上搜索许多示例和解释。规范是 JSR 310

您可以直接与数据库交换java.time对象。使用与 JDBC driver 或更高版本兼容的 JDBC 4.2。不需要字符串,不需要 java.sql.* 类。

从哪里获取java.time类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是 java.time future 可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 IntervalYearWeekYearQuartermore

关于Java 使用 Joda 将 UTC 日期转换为本地日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49774053/

相关文章:

java - Joda-Time、夏令时更改和日期时间解析

perl - 如何转换 yyyy-mm-dd hh :mm:ss into UTC in Perl?

java - 系统时区 ID

java - 如何让 Servlet Filter 处理嵌入式 Jetty 中的欢迎文件?

java - 使用 Spring 以非 root 用户身份在端口 80 上启动 bootRun 进程

Java 8 : How to parse expiration date of debit card?

c++ - 有没有办法在 c++ 的 uint64_t 中获取日期的 utc 纳秒

java - 执行 findAll() 时 Spring boot 和 couchbase 中出现 InvalidDataAccessResourceUsageException

javascript - 如何向 GET 请求发送一个巨大的参数列表

java - joda new DateTime(int,int,int,int,int,int)的问题