在Android SimpleDateFormat的时区的bug时区、Android、SimpleDateFormat、bug

2023-09-04 11:21:24 作者:劫数

我一直在试图找出的错误在我的应用程序。我成功地制造出了下面的谜:

I've been trying to isolate a bug in my application. I succeeded in producing the following "riddle":

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运行此code 7 (是的,真的)。此行为取决于特定的Java实现。

I get the values in comments when I run this code on Android API 7 (yes, really). This behavior depends on particular Java implementation.

我的问题是:

为什么S1不等于S2? 而更重要的是,为什么S1是不正确的?在 S2 点的时候, S1 没有。似乎是在Android的SimpleDateFormat的实现中的错误。

答复的译文:查看由BalusC答案:

ANSWER TO QUESTION 1: See the answer by BalusC:

的 [使用后的SimpleDateFormat#解析]要恢复的进一步行动的任何时区值有previously设置通过调用setTimeZone可能需要的 [After using SimpleDateFormat#parse] any TimeZone value that has previously been set by a call to setTimeZone may need to be restored for further operations.

答复的译文:查看由wrygiel(我自己)的答案

ANSWER TO QUESTION 2: See the answer by wrygiel (myself).

的这是由于(API 7)在Android 2.1系统中的错误。的

推荐答案

这是中提到的DateFormat#parse():

This is mentioned in javadoc of DateFormat#parse():

根据给定的分析位置解析一个日期/时间字符串。例如,一时间文本96年7月10日4:下午5点,PDT将被解析成一个日期,它等效于日期( 837039900000L)

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 to Date(837039900000L).

在默认情况下,解析是宽松:如果输入不在此对象使用的格式方法的形式,但仍然可以解析为一个日期,然后解析成功。客户可能坚持严格遵守格式致电setLenient(false).

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).

此分析操作使用calendar产生一个日期。其结果是,在日历日期 - 时间域和时区值可能已经被覆盖,这取决于子类实现。任何时区值有previously设置通过调用setTimeZone可能需要恢复为进一步的操作。

This parsing operation uses the calendar to produce a Date. As a result, the calendar's date-time fields and the TimeZone value may have been overwritten, depending on subclass implementations. Any TimeZone value that has previously been set by a call to setTimeZone may need to be restored for further operations.

请注意最后一段。遗憾的是它并不能解释的在的正是这一点会发生。为了你需要格式化操作之前明确设置所需的时区解决您的特定问题。

Note the last paragraph. It unfortunately doesn't explain when exactly this will occur. To fix your particular problem you need to explicitly set the desired timezone before the formatting operation.

至于的SimpleDateFormat 本身的可变性,这是相识多年。你不应该创建和分配它的一个实例为静态或类变量,但总是作为一种方法(ThreadLocal的)变量。

As to the mutability of SimpleDateFormat itself, this is known for years. You should never create and assign an instance of it as a static or class variable, but always as a method (threadlocal) variable.

 
精彩推荐