[英]SimpleDateFormat timezone bug on Android
我一直试图在我的应用程序中隔离一个错误。 我成功地制作了以下“谜语”:
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实现。
我的问题是:
s2
指向适当的时间点,但s1
却没有。 Android的SimpleDateFormat实现似乎存在一个错误。 对问题1的回答:请参阅BalusC的答案:
SimpleDateFormat#parse
#parse后]可能需要恢复先前由setTimeZone调用设置的任何TimeZone值以进行进一步操作。 对问题2的回答:请参阅wrygiel的答案(我自己)。
在DateFormat#parse()
javadoc中提到了这一点:
根据给定的解析位置解析日期/时间字符串。 例如,时间文本
"07/10/96 4:5 PM, PDT"
将被解析为等同于Date(837039900000L)
。默认情况下,解析是宽松的:如果输入不是此对象的格式方法使用的形式,但仍可以解析为日期,则解析成功。 客户可以通过调用
setLenient(false)
坚持严格遵守格式。此解析操作使用
calendar
生成Date
。 因此,calendar's
日期时间字段和TimeZone
值可能已被覆盖,具体取决于子类实现。 先前通过调用setTimeZone
设置的任何TimeZone
值可能需要恢复以进行进一步操作。
注意最后一段。 遗憾的是,它没有解释何时会发生这种情况。 要解决您的特定问题,您需要在格式化操作之前显式设置所需的时区。
至于SimpleDateFormat
本身的可变性,这已为人所知多年。 您永远不应该创建它并将其实例指定为静态或类变量,而应始终作为方法(threadlocal)变量。
这是由于Android 2.1(API 7)中的错误造成的。 似乎Android程序员在他们的Android 2.1实现中错过了一些未记录的Java行为 (它被归类为不可修复的bug本身!)。
你的问题引起了我的兴趣,所以我继续编写你的代码。 结果? 正如所料......
2011-12-31T18:00:00+0100
2011-12-31T18:00:00+0100
这两个值是相同的,你使用一些并发? 也许变量在f2.format(d)
之前的另一个线程上被更改。
我尝试通过运行相同的程序来比较s1和s2。 他们和我一样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.