Java DateFormat parse() 不遵守时区

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7533290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:22:27  来源:igfitidea点击:

Java DateFormat parse() doesn't respect the timezone

javaparsingdateformat

提问by Maxime Laval

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));

try {
    System.out.println(df.format(cal.getTime()));
    System.out.println(df.parse(df.format(cal.getTime())));
} catch (ParseException e) {
    e.printStackTrace();
}

Here is the result:

结果如下:

2011-09-24 14:10:51 -0400

Sat Sep 24 20:10:51 CEST 2011

2011-09-24 14:10:51 -0400

2011 年 9 月 24 日星期六 20:10:51 CEST

Why when I parse a date I get from format() it doesn't respect the timezone?

为什么当我解析从 format() 得到的日期时,它不遵守时区?

回答by Jon Skeet

You're printing the result of calling Date.toString(), which alwaysuses the default time zone. Basically, you shouldn't use Date.toString()for anything other than debugging.

您正在打印调用的结果Date.toString(),它始终使用默认时区。基本上,您不应将其Date.toString()用于除调试以外的任何其他用途。

Don't forget that a Datedoesn't havea time zone - it represents an instant in time, measured as milliseconds since the Unix epoch (midnight on January 1st 1970 UTC).

不要忘记,一个Date具有时区-它代表着一个时刻,因为自Unix纪元(午夜1970年1月1日UTC)毫秒。

If you format the date using your formatter again, thatshould come up with the same answer as before.

如果您再次使用格式化程序格式化日期,则应该得出与以前相同的答案。

As an aside, I would recommend the use of Joda Timeinstead of Date/Calendarif you're doing any significant amount of date/time work in Java; it's a muchnicer API.

顺便说一句,如果您在 Java 中进行任何大量的日期/时间工作,我会建议使用Joda Time而不是Date/ Calendar;这是一个很大更好的API。

回答by Charlie Stear

DateFormat.parse()is NOT a query (something that returns a value and doesn't change the state of the system). It is a command which has the side-effect of updating an internal Calendarobject. After calling parse()you have to access the timezone either by accessing the DateFormat's Calendaror calling DateFormat.getTimeZone(). Unless you want to throw away the original timezone and use local time, do not use the returned Datevalue from parse(). Instead use the calendar object after parsing. And the same is true for the format method. If you are going to format a date, pass the calendar with the timezone info into the DateFormatobject before calling format(). Here is how you can convert one format to another format preserving the original timezone:

DateFormat.parse()不是查询(返回值并且不会改变系统状态的东西)。这是一个具有更新内部Calendar对象的副作用的命令。调用后,parse()您必须通过访问DateFormat'sCalendar或调用来访问时区DateFormat.getTimeZone()。除非你想扔掉原来的时区,并使用本地时间,不要使用返回Date的值parse()。而是在解析后使用日历对象。格式方法也是如此。如果您要格式化日期,请DateFormat在调用之前将带有时区信息的日历传递到对象中format()。以下是将一种格式转换为另一种保留原始时区的格式的方法:

    DateFormat originalDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
    DateFormat targetDateFormat = new SimpleDateFormat("EEE., MMM. dd, yyyy");

    originalDateFormat.parse(origDateString);
    targetDateFormat.setCalendar(originalDateFormat.getCalendar());
    return targetDateFormat.format(targetDateFormat.getCalendar().getTime());

It's messy but necessary since parse()doesn't return a value that preserves timezone and format()doesn't accept a value that defines a timezone (the Dateclass).

这很混乱但很有必要,因为parse()它不返回保留时区format()的值,也不接受定义时区(Date类)的值。

回答by Joe

DateFormat is an abstract class for date/time formatting subclasses which formats and parses dates or time in a language-independent manner. The date/time formatting subclass, such as SimpleDateFormat, allows for formatting (i.e., date -> text), parsing (text -> date), and normalization. The date is represented as a Date object or as the milliseconds since January 1, 1970, 00:00:00 GMT.

DateFormat 是日期/时间格式化子类的抽象类,它以独立于语言的方式格式化和解析日期或时间。日期/时间格式化子类,例如 SimpleDateFormat,允许格式化(即日期 -> 文本)、解析(文本 -> 日期)和规范化。日期表示为 Date 对象或自 1970 年 1 月 1 日 00:00:00 GMT 以来的毫秒数

From the spec, it return EPOCH time

根据规范,它返回 EPOCH 时间