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
Java DateFormat parse() doesn't respect the timezone
提问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 Date
doesn'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
/Calendar
if 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 Calendar
object. After calling parse()
you have to access the timezone either by accessing the DateFormat
's Calendar
or calling DateFormat.getTimeZone()
. Unless you want to throw away the original timezone and use local time, do not use the returned Date
value 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 DateFormat
object 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 Date
class).
这很混乱但很有必要,因为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 时间