我一直在尝试隔离我的应用程序中的错误。我成功地产生了以下“谜语”:
SimpleDateFormat f1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
SimpleDateFormat f2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date d = f1.parse("2012-01-01T00:00:00+0700");
String s1 = f1.format(d); // 2011-12-31T18:00:00+0700
String s2 = f2.format(d); // 2011-12-31T18:00:00+0100
当我在 Android API 7 上运行这段代码时,我在评论中得到了值(是的,真的)。此行为取决于特定的 Java 实现。
我的问题是:
- 为什么 s1 不等于 s2?
- 更重要的是,为什么 s1 不正确?虽然
s2
指向正确的时间点,但s1
却没有。 Android 的 SimpleDateFormat 实现中似乎存在错误。
问题 1 的答案:请参阅 BalusC 的答案:
- [使用
SimpleDateFormat#parse
] 之前通过调用 setTimeZone 设置的任何 TimeZone 值可能需要恢复以供进一步操作。
问题 2 的答案:请参阅 wrygiel(我自己)的回答。
- 这是由于 Android 2.1 (API 7) 中的错误所致。
最佳答案
DateFormat#parse()
的 javadoc 中提到了这一点:
Parse a date/time string according to the given parse position. For example, a time text
"07/10/96 4:5 PM, PDT"
will be parsed into a Date that is equivalent toDate(837039900000L)
.By default, parsing is lenient: If the input is not in the form used by this object's format method but can still be parsed as a date, then the parse succeeds. Clients may insist on strict adherence to the format by calling
setLenient(false)
.This parsing operation uses the
calendar
to produce aDate
. As a result, thecalendar's
date-time fields and theTimeZone
value may have been overwritten, depending on subclass implementations. AnyTimeZone
value that has previously been set by a call tosetTimeZone
may need to be restored for further operations.
注意最后一段。不幸的是,它没有解释何时这将发生。要解决您的特定问题,您需要在格式化操作之前明确设置所需的时区。
至于 SimpleDateFormat
本身的可变性,这是众所周知的多年。您永远不应该将它的实例创建和分配为静态或类变量,而应始终作为方法(线程局部)变量。
关于java - Android 上的 SimpleDateFormat 时区错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10624752/