我遇到Jodatime和Android的奇怪行为。我想解析字符串:
2014-05-19T18:13:00.000+02:00
转换为DateTime,并将年、月、小时转换为int。我首先在IntelliJ Studio上做了一些测试,我做了这样的事情:
String date = "2014-05-19T18:13:00.000+02:00";
DateTime dateTime = new DateTime(date);
System.out.println(dateTime.toString());
System.out.println(dateTime.getYear());
System.out.println(dateTime.getMonthOfYear());
System.out.println(dateTime.getDayOfMonth());
System.out.println(dateTime.getHourOfDay());
System.out.println(dateTime.getMinuteOfHour());
System.out.println(dateTime.getMillis());
给了我正确的答案:
2014-05-19T18:13:00.000+02:00
2014
5
19
18
13
1400515980000
现在,当我将IDE更改为Android Studio时,并做同样的操作:
String dateT = "2014-05-19T18:13:00.000+02:00";
DateTime dateTime = new DateTime(dateT);
Lo.g(dateTime.getHourOfDay() + "");
Lo.g(dateTime.toString());
我的结果是:
16
2014-05-19T16:13:00.000Z
由于某些原因,Android Studio/Android上的DateTime没有考虑时区+2:00。
我找不到解决办法。在Joda中也没有简单的方法"addTimeZone"。
如何显示正确的时间与DataTime?我尝试了LocalDateTime,构造DateTime与DateTimeZone.getDefault()(这给了我UTF…)
既然您说您在两个平台上使用相同的Joda-Time版本,并且考虑到Joda-Time有自己独立于系统时区数据的时区存储库这一事实,那么您观察到不同行为的原因可能只有一种解释:显式或隐式的不同输入。让我们进入细节:
你会说,显然在相同的输入字符串下有相同的输入:
" 2014 - 05 - 19 t18:13:00.000 + 02:00"
所以我们有相同的(显式的)输入。但是等等,还有另一件事:隐式默认设置也可以被视为一种抽象的输入方式。使用构造函数DateTime(Object)
。这个构造函数首先委托给类BaseDateTime
的超构造函数,您可以在源代码中看到。
public DateTime(Object instant) {
super(instant, (Chronology) null);
}
这个超级构造函数的javadoc说:
"从表示日期时间的对象构造一个实例,使用指定的年表。如果时间顺序为空,则使用默认时区。
可识别的对象类型在ConverterManager和包括ReadableInstant,字符串,日历和日期。"
最后我们看到Joda-Time使用默认时区。这是我通过研究源代码和文档看到的唯一可能的不同行为。所有其他条件都是相同的:相同的库版本,相同的显式字符串输入和相同的测试场景。
结论:在你的平台上有不同的默认时区。请注意,您在两个平台上获得的是相同的瞬间,但是,由于 更新:我已经用这段代码测试了区域覆盖行为: 因此默认时区优先于字符串输入中的任何偏移量。如果您想使用解析后的偏移量,那么请查看使用DateTimeFormatter及其方法DateTime
-object内部的不同时区/偏移设置,因此使用不同的本地时间戳和偏移量表示。String date = "2014-05-19T19:13:00.000+03:00"; // same instant as yours (just with offset +03)
DateTime dateTime = new DateTime(date);
System.out.println(dateTime.toString());
// output: 2014-05-19T18:13:00.000+02:00 (in my default timezone Europe/Berlin)
withOffsetParsed()
。