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 |
现在我将Windows设置更改为以下(仅取消选中DST设置)
当前时区:东部夏令时
时区:(格林威治标准时间-05:00)东部时间(美国和加拿大)
自动调整时钟以进行夏令时更改:已选中
输出是:
1 |
问题:
创建日期时,Java将在内部将值存储为GMT。将日期格式化为字符串时,Java将使用您的计算机时区将日期转换为您的本地时区,这就是您获得不同结果的原因。例如,如果我在我的计算机上运行以下代码(使用时区CEST):
1 2 3 |
我得到以下结果:
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)方法。