我想将代码从Joda迁移到java. time。我使用DateTimeFormatter解析和格式化多个日期。问题在于DateTimeFormatter.format(...),返回的字符串是“2023-02- 08 T09:30:00.000+01:00+0100+01”,而不是2023-02- 08 T09:30:00.000+01:00
我写了一个测试来暴露我的问题。错误的测试是testFormatWithJava()
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
import org.junit.Before;
import org.junit.Test;
public class TestU {
private DateTimeFormatter dateTimeFormatter;
@Before
public void before() {
DateTimeFormatterBuilder dateTimeFormatterBuilder = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME) //
.optionalStart().appendPattern(".SSS").optionalEnd() //
.optionalStart().appendOffset("+HH:MM", "+00:00").optionalEnd() //
.optionalStart().appendOffset("+HHMM", "+0000").optionalEnd() //
.optionalStart().appendOffset("+HH", "Z").optionalEnd();
dateTimeFormatter = dateTimeFormatterBuilder.toFormatter();
}
@Test
public void testParseDateStringWithJoda() {
String dateString1 = "2023-02-08T09:30:00.787+0000";
String dateString2 = "2023-02-08t09:30:00.000+01:00";
String dateString3 = "2013-07-05t14:04:15+01:00";
org.joda.time.format.DateTimeFormatter formatter = ISODateTimeFormat.dateTime().withOffsetParsed();
org.joda.time.format.DateTimeFormatter formatterWithoutMs = ISODateTimeFormat.dateTimeNoMillis()
.withOffsetParsed();
DateTime dateTime1 = formatter.parseDateTime(dateString1);
DateTime dateTime2 = formatter.parseDateTime(dateString2);
DateTime dateTime3 = formatterWithoutMs.parseDateTime(dateString3);
assertEquals("Wed Feb 08 10:30:00 CET 2023", dateTime1.toDate().toString());
assertEquals("Wed Feb 08 09:30:00 CET 2023", dateTime2.toDate().toString());
assertEquals("Fri Jul 05 15:04:15 CEST 2013", dateTime3.toDate().toString());
}
@Test
public void testParseDateStringWithJava() {
String dateString1 = "2023-02-08T09:30:00.787+0000";
String dateString2 = "2023-02-08t09:30:00.000+01:00";
String dateString3 = "2013-07-05t14:04:15+01:00";
TemporalAccessor temporalAccessor1 = dateTimeFormatter.parse(dateString1);
TemporalAccessor temporalAccessor2 = dateTimeFormatter.parse(dateString2);
TemporalAccessor temporalAccessor3 = dateTimeFormatter.parse(dateString3);
assertEquals("Wed Feb 08 10:30:00 CET 2023", Date.from(Instant.from(temporalAccessor1)).toString());
assertEquals("Wed Feb 08 09:30:00 CET 2023", Date.from(Instant.from(temporalAccessor2)).toString());
assertEquals("Fri Jul 05 15:04:15 CEST 2013", Date.from(Instant.from(temporalAccessor3)).toString());
}
@Test
public void testFormatWithJoda() {
Date date = Date.from(LocalDateTime.of(2023, 02, 8, 9, 30).atZone(ZoneId.of("Europe/Paris")).toInstant());
org.joda.time.format.DateTimeFormatter formatter = ISODateTimeFormat.dateTime().withOffsetParsed();
DateTime dt = new DateTime(date);
assertEquals("2023-02-08T09:30:00.000+01:00", formatter.print(dt));
}
@Test
public void testFormatWithJava() {
Date date = Date.from(LocalDateTime.of(2023, 02, 8, 9, 30).atZone(ZoneId.of("Europe/Paris")).toInstant());
assertEquals("2023-02-08T09:30:00.000+01:00",
dateTimeFormatter.withZone(ZoneId.systemDefault()).format(date.toInstant()));
}
}
2条答案
按热度按时间k0pti3hp1#
您希望能够解析4种可能的格式,而不是4个连接的可选结尾。
应使用DateTimeFormatterBuilder #appendOptional将所需的4个变量添加到DateTimeFormatterBuilder中。
大概是这样的
sd2nnvve2#
可选部分适用于将字符串解析为DateTime示例,但不适用于格式化。格式化时,您应该创建一个或多个DateTimeFormatter,不包含任何可选部分,这些可选部分将反映您的日期格式设置标准。可选部分适用于解析字符串,其中字符串可能具有多种格式,并且您无法对其进行任何控制。我曾经写过一个特性,我尝试解析任何已知格式的字符串,所以我有一个属性文件,其中有几种格式,一个接一个,应该涵盖所有的可能性,我尝试解析传入的字符串,每一种格式,一个接一个,直到第一次成功,或直到我用完格式。把它放在文件中允许我添加和重新排列格式而不需要改变代码。我写了一篇关于它的文章,详细描述了这个想法。下面是文章:Java 8 java.time package: parsing any string to date