【问题标题】:Current time not getting converted into MST timezone当前时间未转换为 MST 时区
【发布时间】:2016-08-12 09:11:13
【问题描述】:

我正在尝试使用以下代码在 MST 中转换当前时间

DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
TimeZone toTimeZone = TimeZone.getTimeZone("MST");
sdf.setTimeZone(toTimeZone);
Date date = new Date();
String strDate = sdf.format(date.getTime());

strDate 显示正确的 MST 时间,但解析后给出的日期时间错误。

Date currentDate = sdf.parse(strDate);

我想要日期格式的当前 MST 时间而不是字符串。

【问题讨论】:

标签: java date time timezone


【解决方案1】:

java.util.Date 对象没有时区的概念。

  • 无法为日期设置时区
  • 无法更改 Date 对象的时区
  • 使用 new Date() 默认构造函数创建的 Date 对象将使用系统默认时区中的当前时间进行初始化

您所做的只是为 formatting 部分添加时区信息...setTimeZone 不会转换任何内容。

【讨论】:

    【解决方案2】:

    tl;博士

    ZonedDateTime zdt = LocalDateTime.parse( input , DateTimeFormatter.forPattern( "dd/MM/uuuu hh:mm:ss" ) ).atZone( ZoneId.of( "America/Denver" ) );
    

    避免使用旧的日期时间类

    您正在使用旧的过时麻烦的遗留日期时间类。

    java.time

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

    现在在maintenance modeJoda-Time 项目也建议迁移到 java.time。

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

    大部分 java.time 功能在ThreeTen-Backport 中向后移植到 Java 6 和 7,并在 ThreeTenABP 中进一步适应 Android。

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。

    LocalDateTime

    您的输入字符串缺少offset-from-UTCtime zone 的任何指示。所以我们必须解析为LocalDateTimeLocalDateTime 没有偏移或时区,所以它确实代表时间轴上的时刻。就像说“圣诞节从 12 月 25 日午夜开始”一样,只有当您将其应用于地球上某个特定时区时,它才有意义(仅成为时间线上的一个点)。

    String input = …
    DateTimeFormatter f = DateTimeFormatter.forPattern( "dd/MM/uuuu hh:mm:ss" );
    LocalDateTime ldt = LocalDateTime.parse( input , f );
    

    ZonedDateTime

    如果您知道上下文并且可以假设预期的偏移量或时区,您可以分别创建一个OffsetDateTimeZonedDateTime

    使用proper time zone names,命名格式为continent/regionMST 可能是指美国落基山脉大部分地区使用的America/Denver 时区,或者加拿大部分地区使用的America/Edmonton

    切勿使用 3-4 个字母的缩写,例如 MST。这些缩写不是真正的时区,没有标准化,甚至不是唯一的(!)。

    ZoneId zoneId = ZoneId.of( "America/Denver" ) ; 
    ZonedDateTime zdt = ldt.atZone( zoneId ) ;
    

    转换

    我建议避免使用臭名昭著的麻烦 java.util.Date 类。但如果你必须这样做,你可以convert to/from java.time types。要与其他代码或库互操作,请使用添加到旧类的新方法进行转换。在这种情况下,使用从OffsetDateTimeZonedDatetime 中提取的Instant 对象并传递给java.util.Date.from

    Instant 类代表 UTC 时间线上的时刻,分辨率为 nanoseconds

    java.util.Date utilDate = java.util.Date.from( zdt.toInstant() ) ;
    

    换个方向,使用添加到旧类的另一个新方法,java.util.Instant::toInstant

    Instant instant = utilDate.toInstant();
    ZonedDateTime zdt = instant.atZone( zoneId ) ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-25
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      相关资源
      最近更新 更多