Java DateFormat parse()不尊重时区

Max*_*val 14 java format parsing date

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();
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

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

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

为什么当我解析格式()得到的日期时,它不尊重时区?

Jon*_*eet 23

你打印调用的结果Date.toString(),它总是使用默认的时区.基本上,Date.toString()除了调试之外,你不应该使用任何其他东西.

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

如果再次使用格式化程序格式化日期,则应该提供与以前相同的答案.

顺便说一句,我建议使用Joda Time而不是Date/ Calendar如果你在Java 中做了大量的日期/时间工作; 这是一个很大更好的API.


小智 7

DateFormat.parse()不是查询(返回值并且不会更改系统状态的东西).这是一个具有更新内部Calendar对象的副作用的命令.打完电话后parse(),你要么通过访问访问时区DateFormatCalendar或调用DateFormat.getTimeZone().除非您想丢弃原始时区并使用本地时间,否则请不要使用返回的Dateparse().而是在解析后使用日历对象.格式方法也是如此.如果要格式化日期,请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());
Run Code Online (Sandbox Code Playgroud)

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