【问题标题】:Java: Convert MST to ESTJava:将 MST 转换为 EST
【发布时间】:2014-06-10 10:01:34
【问题描述】:

我一直在尝试转换从纪元到今天的时间,并以东部标准时间显示。这是远程机器上的输出(它是远程托管的):

Date now = new Date(System.currentTimeMillis());
System.out.println(now.toString());
// Thu Apr 24 14:36:11 MST 2014

不知道MST 是什么,但我想在 EST 中获取自纪元以来的当前毫秒数,并在 EST 中显示结果。

无论我做什么,我都无法让夏令时工作(目前是 EST 时区的夏令时);我要么以 PST、GMT 或 UTC 结束,当我得到“EST”时,要么是某个随机值,要么是落后 1 小时或落后 3 小时。

我希望使用此 DateFormat 格式化输出:

DateFormat EXPIRE_FORMAT = new SimpleDateFormat("MMM dd, yyyy h:mm a z");

【问题讨论】:

  • 你现在在哪里?此外,SimpleDateFormat 有一个 setTimeZone 方法。
  • 我来自澳大利亚墨尔本,拥有东部标准时间 (EST) 这三个字母代码不是唯一的。
  • 从技术上讲,现在 EST 不适用,而是 EDT(东部夏令时间)。您可能只是指“东部时间”(标准时间或日光时间,具体取决于适用的时间)。您只需要应用一个时区。您可以使用"America/New_York",或者如果您愿意,可以使用"America/Toronto""America/Montreal"
  • @PeterLawrey - 这就是"America/Cayman" 存在不同区域的原因。 The TZDB 非常擅长了解这些事情。 :) 另见herehere
  • @PeterLawrey - 另外,感谢您提及缩写问题。 Time zone abbreviations 是高度模糊和重叠的——但有些人似乎认为它们是唯一的键。 :)

标签: java datetime timezone date-format


【解决方案1】:

只需使用DateFormat#setTimeZone(TimeZone)设置您希望显示时间的时区

Date now = new Date(System.currentTimeMillis());
DateFormat EXPIRE_FORMAT = new SimpleDateFormat("MMM dd, yyyy h:mm a z");
EXPIRE_FORMAT.setTimeZone(TimeZone.getTimeZone("America/Montreal")); // or whatever relevant TimeZone id 
System.out.println(EXPIRE_FORMAT.format(now));

AFAIK,there is no EST currently. It's all EDT in Spring.

以上印刷品

Apr 24, 2014 5:53 PM EDT

【讨论】:

  • 请避免像"US/Eastern"这样的向后兼容区域。示例应该更喜欢 "America/New_York" 这样的规范区域。谢谢。
  • @MattJohnson 我来自蒙特利尔 :)。你能解释一下为什么会有问题吗?
  • 啊,here's 一个解释。
  • 是的,该链接中的原因是有效的。特别是,TZDB 将向后兼容性链接移至"backward" fileUS/* 区域最初是为了符合 POSIX 标准而创建的。此外,纽约、蒙特利尔和多伦多在过去的历史中也存在细微差异。将它们全部归为“东方”并不是很准确。
【解决方案2】:

cmets 和answer by Sotirios Delimanolis 是正确的。

避免使用 3 或 4 个字母的时区代码

您应该避免使用 3 或 4 个字母的时区代码,因为它们既不标准化也不唯一。请改用proper time zone names,通常是大陆+城市

避免 j.u.Date

Java 捆绑的 java.util.Date 和 .Calendar 和 SimpleDateFormat 类是出了名的麻烦。使用带有更新时区数据库的体面的日期时间库。对于 Java,这意味着 Joda-Time 或 Java 8 中的新 java.time 包(受 Joda-Time 启发)。

避免自纪元以来的毫秒数

我建议您避免使用自 epoch 以来的毫秒数。由于数字在人类阅读时毫无意义,因此会很快变得混乱。让日期时间库为您管理毫秒。

指定时区

通常最好指定所需/预期的时区。如果省略时区,所有主要的日期时间库(java.util.Date、Joda-Time、java.time)都会应用 JVM 的默认时区。

Joda-Time 示例

Joda-Time 2.3 中的示例代码。

DateTimeZone timeZoneToronto = DateTimeZone.forID( "America/Toronto" );
DateTime dateTimeToronto = new DateTime( timeZoneToronto ); // Current moment.
DateTime dateTimeUTC = dateTimeToronto.withZone( DateTimeZone.UTC );
DateTime dateTimeParis = dateTimeToronto.withZone( DateTimeZone.forID( "Europe/Paris" ) );

如果您真的想要自纪元以来的毫秒数,请调用 getMillis 方法。在上面的示例代码中,所有三个 DateTime 对象的毫秒数都相同。

long millis = dateTimeToronto.getMillis();

如果您需要 java.util.Date 与其他类一起使用...

java.util.Date date = dateTimeToronto.toDate();

虽然 Joda-Time 使用 ISO 8601 标准格式作为其默认值,但您可以指定其他格式来生成字符串。

DateTimeFormatter formatter = DateTimeFormat.forPattern( "MMM dd, yyyy h:mm a z" );
String output = formatter.print( dateTimeToronto );

【讨论】:

    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 2012-06-06
    • 2011-07-26
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多