首先,我想说清楚它不是夏令时问题。
其次,在努力之后,它似乎与SimpleDateFormat中使用的语言环境有关。
第三,似乎只发生在PST / PDT时区。 UTC还可以。
这是测试代码。
使用US和ENGLISH语言环境来解析相同的日期。
try {
Date date = new Date();
SimpleDateFormat US_format = new SimpleDateFormat("MMM d HH:mm:ss z", Locale.US);
SimpleDateFormat EN_format = new SimpleDateFormat("MMM d HH:mm:ss z", Locale.ENGLISH);
US_format.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); //Set PST Timezone
String US_str = US_format.format(date);
Log.i("DEBUG", "US_str: " + US_str);
Log.i("DEBUG", "US_str: " + US_format.format(US_format.parse(US_str)));
EN_format.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); //Set PST Timezone
String EN_str = EN_format.format(date);
Log.i("DEBUG", "EN_str: " + EN_str);
Log.i("DEBUG", "EN_str: " + EN_format.format(EN_format.parse(EN_str)));
} catch (ParseException e) {
Log.i("DEBUG", "Parsing Error");
}
结果是
02-26 19:42:42.863 I / DEBUG:US_str:Feb 26 19:42:42 PST
02-26 19:42:42.865 I / DEBUG:US_str:2月26日 18:42:42 PST
02-26 19:42:42.865 I / DEBUG:EN_str:Feb 26 19:42:42 PST
02-26 19:42:42.866 I / DEBUG:EN_str:Feb 26 19:42:42 PST
这是一个错误吗? 为什么Locate.US会有一小时的差异?
====================================
更新: 它似乎只发生在Android 5.0设备上。 其他环境似乎还可以。
在Android问题跟踪器上发布了一个错误。 (问题158265)
答案 0 :(得分:0)
我认为错误可能来自Logger。它与语言环境无关。
Date date = new Date();
SimpleDateFormat US_format = new SimpleDateFormat("MMM d HH:mm:ss z", Locale.US);
SimpleDateFormat EN_format = new SimpleDateFormat("MMM d HH:mm:ss z", Locale.ENGLISH);
String US_str = US_format.format(date);
System.out.println( "US_str: " + US_str);
System.out.println( "US_str: " + US_format.format(US_format.parse(US_str)));
String EN_str = EN_format.format(date);
System.out.println( "EN_str: " + EN_str);
System.out.println( "EN_str: " + EN_format.format(EN_format.parse(EN_str)));
这是在我的电脑中获得的输出:
US_str:2月27日12:18:26 IST
US_str:2月27日12:18:26 IST
EN_str:2月27日12:18:26 IST
EN_str:2月27日12:18:26 IST
希望这有助于你。
答案 1 :(得分:0)
来自Android问题问题158265。
Google工程师回复了以下答案。
Nexus 5似乎无法更新RTC时钟硬件。当用户(或OS)更改时钟时,它不会永久保存到设备硬件。下次设备重新启动时,它会从RTC硬件读取值并将其设置为系统时钟。就我而言,我试过的两台设备将RTC设置为1971年。
系统时钟(用户看到的内容)最初是从RTC设置的,但是是独立的。如果用户已将设备设置为从网络源同步系统时钟,则在设备完成引导时,将正确设置系统时钟。如果没有回写它的能力,RTC仍然是错误的。
不幸的是,用于解析PST等区域信息的信息在zygote进程的引导期间被缓存,而时钟仍然是错误的。在我的例子中,它正在查看1971年的时区名称,但之后使用偏移信息。这意味着我们错误地选择Dawson_Creek作为PST的代理,但今天Dawson_Creek 的偏移实际上是MST / MDT的偏移量。
查看某些区域设置而不是其他区域设置问题的原因是,zygote缓存在启动后最多包含3个条目:
1)Locale.ROOT 2)Locale.US 3)
使用ENGLISH(en)被识别为与US(en_US)不同的区域设置 所以它不使用引导期间缓存的数据,因此当前 (正确)使用系统时钟时间。
简而言之,此问题仅发生在具有 BAD RTC硬件的Android设备上。
zygote进程在启动序列开始时使用 BAD 时间生成时区缓存。所以使用默认的Locale.US解析时区是错误的。
使用与默认值不同的Locale进行解析的结果是正确的,因为它生成的时区数据的时间已经过校正/与网络时间同步。
要避免此问题,只需使用默认值以外的语言环境来解析时区。