关于日期格式:Java和Windows区域设置

Java and Windows Regional Settings

对不起,如果这是重新发布。我找不到合适的答案。

请忽略最佳做法并使用已弃用的api。

我想将以下日期"Mon May 19 02:16:52 EDT 2003"格式化为"MM / dd / yyyy HH:mm:ss"。同样,我只想更改输出格式,这是从我在EST的笔记本电脑上执行的。

我的Windows区域设置是:

当前时区:东部夏令时

时区:(格林威治标准时间-05:00)东部时间(美国和加拿大)

自动调整时钟以进行夏令时更改:已选中

这个java代码做到了:

1
2
3
Date aDate = new Date("Mon May 19 02:16:52 EDT 2003");
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
System.out.println("Formatted Date:" + sdf.format(aDate));

输出是

1
Formatted Date: 05/19/2003 02:16:52

现在我将Windows设置更改为以下(仅取消选中DST设置)

当前时区:东部夏令时

时区:(格林威治标准时间-05:00)东部时间(美国和加拿大)

自动调整时钟以进行夏令时更改:已选中

输出是:

1
Formatted Date: 05/19/2003 01:16:52

问题:

  • 为什么输出会减少一个小时?
  • 即使在格式化时,java是否使用Windows DST设置?我虽然java为各种时区的DST设置时间维护自己的数据。

  • 创建日期时,Java将在内部将值存储为GMT。将日期格式化为字符串时,Java将使用您的计算机时区将日期转换为您的本地时区,这就是您获得不同结果的原因。例如,如果我在我的计算机上运行以下代码(使用时区CEST):

    1
    2
    3
    System.out.println(new Date("Mon May 19 02:16:52 UTC 2003"));
    System.out.println(new Date("Mon May 19 02:16:52 EDT 2003"));
    System.out.println(new Date("Mon May 19 02:16:52 PST 2003"));

    我得到以下结果:

    1
    2
    3
    Mon May 19 04:16:52 CEST 2003
    Mon May 19 08:16:52 CEST 2003
    Mon May 19 12:16:52 CEST 2003

    如果您想要更可预测的结果,您可能无法在输入中提供时区(例如,只要输入和输出在同一时区执行它保持不变)或使用更可靠的方法,您可以指定哪个时区到使用:

    1
    2
    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("EDT"));

    在内部,日期以长值存储,该值表示超过某个时期的毫秒数。当您点击机器上的夏令时时,您更改了时区。所以Java使用相同的时间编号和不同的时区,这就是为什么你拥有你拥有的东西


    因为夏天的时间比正常时间快一个小时。将您的日历设置为1月,您将看到没有区别。


    这是因为默认情况下,SimpleDateFormat会在系统时区中打印日期。要检查它,请将时区输出添加到格式:"MM / dd / yyyy HH:mm:ss z"因此,您将看到它实际打印该值的时区。

    如果要控制,在要为格式化值的时区中,请使用DateFormat.setTimeZone(TimeZone z)方法。