此代码可以正常工作,但我想使用 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/Montreal
、Africa/Casablanca
或Pacific/Auckland
。切勿使用 3-4 个字母的缩写,例如 EST
或 IST
,因为它们不是真正的时区,不是标准化的,甚至不是唯一的( !)。
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.Date
、 Calendar
和 SimpleDateFormat
。
Joda-Time 项目现在位于 maintenance mode 中,建议迁移到 java.time 类。
要了解更多信息,请参阅 Oracle Tutorial 。并在 Stack Overflow 上搜索许多示例和解释。规范是 JSR 310 。
您可以直接与数据库交换java.time对象。使用与 JDBC driver 或更高版本兼容的 JDBC 4.2。不需要字符串,不需要 java.sql.*
类。
从哪里获取java.time类?
- Java SE 8 、 Java SE 9 、 Java SE 10 及更高版本
- 内置。
- 是标准 Java API 的一部分,具有捆绑实现。
- Java 9 添加了一些小功能和修复。
- Java SE 6 和 Java SE 7
- 大部分 java.time 功能都在 ThreeTen-Backport 中向后移植到 Java 6 和 7。
- Android
- 更高版本的 Android 捆绑了 java.time 类的实现。
- 对于早期的 Android (<26),ThreeTenABP 项目采用 ThreeTen-Backport(如上所述)。请参阅 How to use ThreeTenABP…。
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是 java.time future 可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 Interval
、 YearWeek
、 YearQuarter
和 more 。
关于Java 使用 Joda 将 UTC 日期转换为本地日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49774053/