【问题标题】:Convert unix time/utc to a specific timezone将 unix time/utc 转换为特定时区
【发布时间】:2014-07-15 12:50:42
【问题描述】:

我有当前毫秒 utc/unix 时间,现在我想将其转换为特定时区的日期时间,例如美国东部标准时间 -5(纽约)。

我使用以下方法获取当前毫秒/unix 时间:

System.currentTimeMillis

现在我想将此长值转换为特定时区。

我如何使用 Joda time 做到这一点,因为我听说这是最好的库,但 API 对我来说似乎有点混乱。

【问题讨论】:

  • 一般情况下,您不会转换时间,而是将时间保留为 GMT+0,并在打印时使用本地时区。即只有当您将其转换为字符串时才会应用。
  • @PeterLawrey 我正在考虑将 unix 时间存储在数据库中,即自 1970 年以来的秒数。然后在 UI 级别将其转换为时区。这不是一个很好的方法吗?
  • 这就是通常的做法。虽然您可以存储毫秒数。
  • JSR 310 是旧 Java Calendar 和 JodaTime 的替代品,并内置于 Java 8。如果可以,请使用它。

标签: java jodatime


【解决方案1】:

您可以使用DateTime(long),后跟DateTime.withZone(DateTimeZone)。类似的东西

DateTime dt = new DateTime(millis).withZone(DateTimeZone.forID("Europe/Somewhere");

【讨论】:

  • 我想使用 Jodatime。
  • 这是来自 Joda 的 DateTime 类。你检查过超链接吗?
  • 对不起,我以为那是 java.util.Date,谢谢调查。
  • 仅供参考,Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。见Tutorial by Oracle
【解决方案2】:

我使用:System.currentTimeMillis

获取当前毫秒/unix 时间

不要这样做。

Instant.now() 方法取代了那个过时的方法。此外,Instant 能够实现更精细的粒度,最高可达纳秒级。目前,OpenJDK 中的实现以微秒为单位捕获当前时刻,比其他方法的毫秒更精细。

Instant instant = Instant.now() ;

instant.toString(): 2019-07-27T02:15:34.727766Z

现在我想将此长值转换为特定时区。

将您的时区指定为ZoneId。申请Instant 以获取ZonedDateTime

ZoneId z = ZoneId.of( "America/New_York" ) ;  // Or did you have another zone in mind, such as `America/Montreal` ?
ZonedDateTime zdt = instant.atZone( z );

或者,您可以跳过Instant。在传递ZoneId 时调用ZonedDateTime.now

ZonedDateTime zdt = ZonedDateTime.now( z ) ;

特定时区,例如美国东部标准时间 -5(纽约)。

EST 不是真正的时区。

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

我如何使用 Joda time 做到这一点,因为我听说这是最好的库,但 API 对我来说似乎有点混乱。

Joda-Time 项目现在由 JSR 310 定义的 Java 8 及更高版本中内置的 java.time 类继承。Android 26 及更高版本具有这些类也。

  • 大部分 java.time 功能在 ThreeTen-Backport 项目中向后移植到 Java 6 和 Java 7。
  • ThreeTenABP 中进一步适用于早期的Android (How to use ThreeTenABP…

您对写入数据库的评论。如果您的数据库具有正确的日期时间类型,请使用它们而不是存储长整数。

从 JDBC 4.2 开始,我们可以与数据库交换 java.time 对象。

我们在这里讨论的时刻应该存储在类似于 SQL 标准类型TIMESTAMP WITH TIME ZONEWITH不是WITHOUT!)的数据类型的列中。

奇怪的是,JDBC 规范只要求支持OffsetDateTime,而不是InstantZonedDateTime。所以,转换吧。

myPreparedStatement.setObject( … , zdt.toOffsetDateTime() ) ;

检索。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;    // Adjust to a time zone.
Instant instant = zdt.toInstant() ;                 // Adjust to UTC.

OffsetDateTimeZonedDateTime 有什么区别?

  • 与 UTC 的偏移量只是几个小时-分钟-秒。仅此而已。
  • 时区更多。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。

【讨论】:

    猜你喜欢
    • 2020-03-21
    • 2020-06-16
    • 2014-08-12
    • 2020-09-13
    • 2020-06-24
    • 2021-12-18
    • 2013-10-22
    • 2021-01-04
    • 1970-01-01
    相关资源
    最近更新 更多