我很难过。我必须承认,我可能找不到适合这个bug的地方。那说......
我们使用dd MMM YYY HH:mm:ss z
作为日期格式字符串。那个小写的z
应该返回该区域的三个字母缩写,如PST
或CET
。确实如此。到处都是生产。在生产中,我们获得了抵消,如-08:00
。我们通过WAR验证了我们到处都在使用joda 2.9.2。
我们使用dateTime.withZone(DateTimeZone.forID(timezone)).toString(dateFormat, locale)
,其中dateTime
是DateTime
,timezone
是String
(经证实是相同的实例,America/Los_Angeles
)。 dateFormat
,如上所述,dd MMM YYY HH:mm:ss z
和locale
被证实是跨越实例的en
。
我注意到这个SO question提出了一个想法,即语言环境信息正在丢失,只留下偏移量。尽管如此,无论我使用什么timezone
和locale
,我都无法重现。当然,我们不使用forOffsetHours
。
编辑:对于它的价值,我认为它不是语言环境,因为我可以使用.toString(dateFormat, locale)
中的语言环境的组合值,如new Locale("hasdf")
和日期格式。我可以获得这种确切的意外格式的唯一方法是,如果我使用大写的Z
代替小写的z
。
第二次编辑:哦,JVM到处都是一样的。
可能这与JVM中的区域设置数据有关(检查您的版本只是为了确保它们在所有环境中都是一样的)。
无论如何,有一种解决方法可以覆盖Joda用于时区名称的文本。你需要扩展org.joda.time.tz.DefaultNameProvider
:
public class MyNameProvider extends DefaultNameProvider {
@Override
public String getShortName(Locale locale, String id, String nameKey, boolean standardTime) {
if (Locale.ENGLISH.equals(locale) && "America/Los_Angeles".equals(id)) {
// return the correct name for Daylight Saving Time
return standardTime ? "PST" : "PDT";
}
return super.getShortName(locale, id, nameKey, standardTime);
}
}
然后你做:
DateTimeZone.setNameProvider(new MyNameProvider());
DateTime d = new DateTime().withZone(DateTimeZone.forID("America/Los_Angeles"));
System.out.println(d.toString("dd MMM YYY HH:mm:ss z", Locale.ENGLISH));
这将覆盖JVM正在使用的任何数据,并始终在英语语言环境中使用“PST”和“PDT”表示America / Los_Angeles。
我无法重现这个问题,但我认为Joda从JVM本身获取此信息。
您可以使用以下代码查看Joda正在使用的数据:
String[][] zoneStringsEn = DateTimeUtils.getDateFormatSymbols(Locale.ENGLISH).getZoneStrings();
for (String[] strings : zoneStringsEn) {
if (strings != null && strings.length >= 5 && "America/Los_Angeles".equals(strings[0])) {
System.out.println(strings[2]); // "PST" in my JVM
}
}
可能无法运行的环境具有不同的JVM版本。
我可以获得确切意外格式的唯一方法是使用大写Z代替小写z
嗯,那是因为一个大写的Z给你偏移量,如javadoc中所述:http://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html
区域:'Z'输出不带冒号的偏移量,'ZZ'输出带冒号的偏移量,'ZZZ'或更多输出区域ID。
小写的z为您提供区域名称:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
z time zone text Pacific Standard Time; PST
Z time zone offset/id zone -0800; -08:00; America/Los_Angeles
很有可能是一些类路径问题。
在我们的项目中,我们能够在类路径上重现这个问题,包括JodaTime 2.9.2和2.4。
我们不知道我们包括旧的2.4版本。它没有显示在依赖树中。最终,我们发现joda类在一些旧的胖JAR依赖项中实际上不再需要了。
请记住,类路径问题在环境之间可能是不确定的。