Java DateFormat parse()不尊重时区
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(); }
结果如下:
2011-09-24 14:10:51 -0400
9月24日星期六20:10:51 CEST 2011
为什么当我解析格式()得到的日期时,它不尊重时区?
您正在打印调用Date.toString()
的结果,该结果始终使用默认时区。 基本上,除了调试之外,不应该使用Date.toString()
。
不要忘记Date
没有时区 – 它代表一个时刻,以Unix时代(1970年1月1日午夜)为单位的毫秒数来衡量。
如果您再次使用格式化程序格式化日期,则应该提供与以前相同的答案。
顺便说一句 ,如果您在Java中进行大量的日期/时间工作,我建议使用Joda Time而不是Date
/ Calendar
; 它是一个更好的API。
DateFormat.parse()
不是一个查询(返回值并且不会改变系统状态的东西)。 这是一个具有更新内部Calendar
对象的副作用的命令。 在调用parse()
您必须通过访问DateFormat
的Calendar
或调用DateFormat.getTimeZone()
来访问时区。 除非您想丢弃原始时区并使用本地时间,否则请不要使用parse()
返回的Date
值。 而是在解析后使用日历对象。 格式方法也是如此。 如果要格式化日期,请在调用format()
之前将带有时区信息的日历传递到DateFormat
对象。 以下是如何将一种格式转换为另一种格式,保留原始时区:
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());
它很麻烦但是必要,因为parse()
不返回保留时区的值,而format()
不接受定义时区的值( Date
类)。
DateFormat是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化和分析日期或时间。 日期/时间格式化子类(如SimpleDateFormat)允许格式化(即日期 – >文本),解析(文本 – >日期)和规范化。 日期表示为Date对象或自1970年1月1日00:00:00 GMT以来的毫秒数 。
根据规范 ,它返回EPOCH时间