edw*_*yte 29 java date jodatime
我想解析一个使用特定时区创建的日期,将其转换为格式并返回.转换有效,但时区偏移始终设置为+0000,并根据需要添加/减去时差.如何使其格式化并保持偏移正确?
我期待这个:2012-11-30T12:08:56.23 + 07:00
但得到这个:2012-11-30T05:08:56.23 + 00:00
执行:
public static final String ISO_8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSZZ";
public static String formatDateToISO8601Standard(Date date) {
DateTime dateTime = new DateTime(date);
DateTimeFormatter df = DateTimeFormat.forPattern(ISO_8601_DATE_FORMAT);
return dateTime.toString(df);
}
Run Code Online (Sandbox Code Playgroud)
测试类:
private static final String DATE_WITH_TIMEZONE = "30 11 2012 12:08:56.235 +0700";
private static final String EXPECTED_DATE_WITH_TIMEZONE = "2012-11-30T12:08:56.23+07:00";
@Test public void testFormattingDateWithSpecificTimezone() throws Exception {
String result = JodaDateUtil.formatDateToISO8601Standard(createDate(DATE_WITH_TIMEZONE));
assertEquals("The date was not converted correctly", EXPECTED_DATE_WITH_TIMEZONE, result); }
private Date createDate(String dateToParse) throws ParseException {
DateTimeFormatter df = DateTimeFormat.forPattern("dd MM yyyy HH:mm:ss.SSS Z");
DateTime temp = df.parseDateTime(dateToParse);
Date date = temp.toDate();
return date; }
Run Code Online (Sandbox Code Playgroud)
Dar*_* X. 40
基本上,一旦解析了[在createDate()方法中的日期字符串],就会丢失原始区域.Joda-Time允许您使用任何区域格式化日期,但您需要保留原始区域.
在createDate()方法中,DateTimeFormatter "df"可以返回字符串上的区域.您需要使用withOffsetParsed()方法.然后,当你有DateTime时,调用getZone().如果您将此区域保存在某处或以某种方式将其传递给格式化例程,则可以通过创建DateTimeFormatter"withZone"并在该格式中指定该区域作为所需区域来使用它.
作为演示,这里是一个方法中的一些示例代码.希望它能帮助您按照希望的方式更改代码.
public static void testDate()
{
DateTimeFormatter df = DateTimeFormat.forPattern("dd MM yyyy HH:mm:ss.SSS Z");
DateTime temp = df.withOffsetParsed().parseDateTime("30 11 2012 12:08:56.235 +0700");
DateTimeZone theZone = temp.getZone();
Date date = temp.toDate();
DateTime dateTime = new DateTime(date);
DateTimeFormatter df2 = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSZZ");
DateTimeFormatter df3 = df2.withZone(theZone);
System.out.println(dateTime.toString(df2));
System.out.println(dateTime.toString(df3));
}
Run Code Online (Sandbox Code Playgroud)
OffsetDateTime.parse (
"30 11 2012 12:08:56.235 +0700" ,
DateTimeFormatter.ofPattern ( "dd MM uuuu HH:mm:ss.SSS X" , Locale.US )
).toString()
Run Code Online (Sandbox Code Playgroud)
2012-11-30T12:08:56.235 + 07:00
接受的答案是正确的。一旦转换为java.util.Date对象,就会丢失时区信息。由于java.util.Date::toString在生成String时会混淆地应用当前的默认时区,因此使情况变得复杂。
避免使用这些旧的日期时间类,例如java.util.Date。它们设计不当,令人困惑且麻烦。现在已被遗留,由java.time项目取代。现在,java.time类取代了Joda-Time项目。
将输入字符串解析为一个OffsetDateTime对象,因为它包含一个距UTC的偏移量,但是缺少时区。调用DateTimeFormatter.ofPattern以指定与您的输入字符串匹配的自定义格式。将该格式化程序对象传递给OffsetDateTime.parse。
String input = "30 11 2012 12:08:56.235 +0700" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "dd MM uuuu HH:mm:ss.SSS X" , Locale.US );
OffsetDateTime odt = OffsetDateTime.parse ( input , f );
Run Code Online (Sandbox Code Playgroud)
odt:toString():2012-11-30T12:08:56.235 + 07:00
要在UTC中查看同一时刻,请提取一个Instant。该Instant级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。
Instant instant = odt.toInstant();
Run Code Online (Sandbox Code Playgroud)
Instant.toString():2012-11-30T05:08:56.235Z
您可以应用要在其上查看同一时刻,时间轴上同一点的任何时区。
ZonedDateTime zdtKolkata = odt.toInstant ().atZone ( ZoneId.of ( "Asia/Kolkata" ) );
Run Code Online (Sandbox Code Playgroud)
zdtKolkata.toString():2012-11-30T10:38:56.235 + 05:30 [亚洲/加尔各答]
根本不需要混入旧的日期时间类。坚持使用java.time。如果必须使用一些尚未更新为java.time类型的旧代码,请查找添加到旧类中的新方法以将其转换为java.time。
相当于java.util.Date是Instant,两者均为计数纪元以来1970-01-01T00:00:00Z在UTC。但是要当心数据丢失,因为java.time类支持纳秒级分辨率,但是旧类限于毫秒级。
java.util.Date utilDate = java.util.Date.from( instant );
Run Code Online (Sandbox Code Playgroud)
该java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.Date,.Calendar,和java.text.SimpleDateFormat。
现在处于维护模式的Joda-Time项目建议迁移到java.time。
要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
在哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如Interval,YearWeek,YearQuarter,和更多。
| 归档时间: |
|
| 查看次数: |
39263 次 |
| 最近记录: |