从毫秒返回 1970 年 1 月日期时损失了一个小时
我有以下代码,它需要一个毫秒字符串(将来自 RSS feed,因此将是一个字符串,下面的示例是一个快速测试程序)并将这些毫秒转换为 Date 对象。
public static void main(String[] args) {
String ms = "1302805253";
SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(Long.parseLong(ms));
try {
String dateFormat = dateFormatter.format(calendar.getTime());
System.out.println("Date Format = " + dateFormat);
Date dateParse = dateFormatter.parse(dateFormatter.format(calendar.getTime()));
System.out.println("Date Parse = " + dateParse);
} catch (ParseException e) {
// TODO: handle exception
}
}
Output:
Date Format = Fri, 16 Jan 1970 02:53:25 GMT
Date Parse = Fri Jan 16 03:53:25 GMT 1970
正如您所看到的,在日历对象的格式化和结果字符串的解析之间,损失了一个小时。此外,输出的格式也发生了变化。谁能帮助我解释为什么会发生这种情况以及如何解决它?我希望日期对象的格式与“日期格式”输出的格式相同。
I have the following code that takes a String of milliseconds (will be from an RSS feed so will be a String, the example below is a quick test program) and converts those millis into a Date object.
public static void main(String[] args) {
String ms = "1302805253";
SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(Long.parseLong(ms));
try {
String dateFormat = dateFormatter.format(calendar.getTime());
System.out.println("Date Format = " + dateFormat);
Date dateParse = dateFormatter.parse(dateFormatter.format(calendar.getTime()));
System.out.println("Date Parse = " + dateParse);
} catch (ParseException e) {
// TODO: handle exception
}
}
Output:
Date Format = Fri, 16 Jan 1970 02:53:25 GMT
Date Parse = Fri Jan 16 03:53:25 GMT 1970
As you can see, between the formatting of the calendar object and parsing of the resulting String, an hour is being lost. Also, the formatting of the output has changed. Can anyone help me as to why this is happening, and how to get around it? I want the Date object to be the same format as the "Date Format" output.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信这种情况的发生是因为英国在 1970 年实际上并没有使用 GMT,而 Java 在这方面存在一个错误......它将格式化 1970 年的日期,就好像英国使用 GMT,但没有实际改变偏移量。简单示例:
结果:
请注意,它声称现在是格林尼治标准时间凌晨 1 点...这是不正确的。当时是欧洲/伦敦时间凌晨1点,但欧洲/伦敦不遵守格林尼治标准时间。
Joda Time 正确地打印出了 BST - 但 Joda Time 不喜欢解析带有时区缩写的值。但是,您可以让它使用时区偏移来代替:
I believe it's happening because the UK didn't actually use GMT in 1970, and Java has a bug around that... it will format a date in 1970 as if the UK were using GMT, but without actually changing the offset. Simple example:
Result:
Note that it claims it's 1am GMT... which is incorrect. It was 1am in Europe/London time, but Europe/London wasn't observing GMT.
Joda Time gets this right in that it prints out BST - but Joda Time doesn't like parsing values with time zone abbreviations. However, you can get it to use time zone offets instead:
乔恩·斯基特的回答是正确的。
java.time
让我们通过 java.time 运行相同的输入来查看结果。
指定正确的时区名称。切勿使用 3-4 个字母的缩写,例如
BST
、EST
或IST
,因为它们不是真正的时区,不是标准化的,也不是甚至是独一无二的(!)。因此我们使用Europe/London
。即时
类代表 UTC 中时间轴上的时刻,分辨率为 纳秒。应用时区来生成
ZonedDateTime
对象。转储到控制台。我们确实看到欧洲/伦敦时间当时比 UTC 早一个小时。因此,一天中的时间是
02
小时,而不是01
小时。两者都代表时间线上相同的同时时刻,只是通过两个不同的挂钟时间的镜头查看。整秒
顺便说一句,我怀疑您的输入字符串代表自 1970 UTC 纪元以来的 整 秒,而不是 毫秒。将其解释为秒,我们得到 2011 年的日期,即该问题发布的月份。
关于 java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了旧的麻烦的日期时间类,例如 java.util.Date、.Calendar 和 & 。
java.text.SimpleDateFormat
。Joda-Time 项目,现已在 维护模式,建议迁移到 java.time。
要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。
许多 java.time 功能都向后移植到 Java 6 和 Java 6。 ThreeTen-Backport 中的 7 并进一步适应 Android 在 ThreeTenABP。
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。
The Answer by Jon Skeet is correct.
java.time
Let’s run the same input through java.time to see the results.
Specify a proper time zone name. Never use the 3-4 letter abbreviation such as
BST
,EST
, orIST
as they are not true time zones, not standardized, and not even unique(!). So we useEurope/London
.The
Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds.Apply a time zone to produce a
ZonedDateTime
object.Dump to console. We see indeed that
Europe/London
time is an hour ahead of UTC at that moment. So the time-of-day is02
hours rather than01
hours. Both represent the same simultaneous moment on the timeline, just viewed through the lenses of two different wall-clock times.Whole seconds
By the way, I suspect your input string represents whole seconds since epoch of 1970 UTC rather than milliseconds. Interpreted that as seconds we get a date in 2011, in the month this Question posted.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as
java.util.Date
,.Calendar
, &java.text.SimpleDateFormat
.The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time.