【问题标题】:Date to timestring conversion one hour wrong日期到时间字符串转换一小时错误
【发布时间】:2012-07-28 20:41:54
【问题描述】:

我有一个日期,例如 2000-01-01T10:00:00Z 。这代表商店的营业时间,因此这意味着商店在 10 点钟营业。其他信息没用,是随机日期。 我只需要将其表示为字符串:10:00。 对于这种转换,我使用了一个简单的方法:

public String dateToString(Date date){
    SimpleDateFormat ft =  new SimpleDateFormat ("HH:mm");
    String time= ft.format(date);
return time;
}

我认为这应该可行,大写 HH 表示 24 小时的时间。但是当我运行这段代码时,返回值为 11:00 ! 为什么会这样,如何预防?格式功能是否会查看我的时区并且日期中的设置是否错误(我认为我的手机设置是 mgt+1,因为我住在荷兰)?以及如何忽略这一点?

【问题讨论】:

  • Z 表示 GMT+0,所以是时区错误。
  • 我在伊朗遇到了同样的问题。当我在我的操作系统上禁用夏令时(通过使用不支持夏令时的 TimeZone)一切都变得正确!
  • @AmirPashazadeh 更改主机操作系统的默认时区并不是解决此问题的最佳方法。相反 (a) 使用 java.time 类,并且 (b) 始终在日期时间类的各种方法中指定可选的时区参数。

标签: java android string date time


【解决方案1】:

ok,找到了! Android 将日期转换为设备的时区。我不得不否决:

这行得通:

public String dateToString(Date date){
    SimpleDateFormat ft =  new SimpleDateFormat ("HH:mm");
    ft.setTimeZone(TimeZone.getTimeZone("UTC"));
    String time= ft.format(date);
return time;
}

【讨论】:

    【解决方案2】:

    2000-01-01T10:00:00Z 的值一点也不“无用”。这描述了时间线上的确切时刻,包括日期、时间和offset-from-UTC,在本例中为UTC

    ISO 8601

    该字符串格式由ISO 8601 标准定义。末尾的ZZulu 的缩写,表示UTC。

    Instant

    您可以将此字符串直接解析为InstantInstant 类代表UTC 时间线上的一个时刻,分辨率为nanoseconds。这意味着最多九 (9) 位小数。

    Instant instant = Instant.parse( "2000-01-01T10:00:00Z" );
    

    Instant 类只是 Java 中的基本构建块类。为了获得更大的灵活性,我们应该:

    • 为该时刻分配一个与 UTC 的偏移量 (ZoneOffset) 以获得 OffsetDateTime
    • 立即分配时区 (ZoneId) 以获取 ZonedDateTime

    有什么区别?时区是一个偏移量加上一组用于处理异常的规则,例如Daylight Saving Time (DST)

    OffsetDateTime

    因此,如果您确实想要以 UTC 形式显示的当前时间,则分配 UTC (ZoneOffset.UTC) 的偏移量以获取 OffsetDateTime,然后提取 LocalTime 对象。 LocalTime 表示没有日期和时区的时间。

    OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );
    LocalTime lt = odt.toLocalTime();  // 10:00:00
    

    ZonedDateTime

    如果您想通过另一个时区的镜头看到同一时刻,要查看该特定地区的wall-clock time,请指定ZoneId。例如,魁北克的同一时刻将比世界标准时间晚 5 小时。

    ZoneId z = ZoneId.of( "America/Montreal" );
    ZonedDateTime zdt = instant.atZone( z );  // 2000-01-01T05:00:00-05:00[America/Montreal]
    LocalTime lt = zdt.toLocalTime();  // 05:00:00
    

    关于java.time

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

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

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

    大部分 java.time 功能在ThreeTen-Backport 中向后移植到Java 6 和7,并进一步适应ThreeTenABP 中的Android(参见How to use…)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-30
      • 2018-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-06
      相关资源
      最近更新 更多