我需要解析一个具有以下格式的日期字符串:
yyyy-MM-dd TTTTT
。所有模式字母都是标准的DateTimeFormatter字母,但TTTTT
部分除外,它是秒的字段。
由于没有为这样的领域定义模式,我需要提出其他的东西。我的第一个想法是尝试将字段解析为毫日(A
),但是通过使用5 A
,我的字段被视为最不重要的人物......是的,不是我想要的。
我是否可以使用任何开箱即用的解决方案,或者我必须采用一些自定义解决方案(例如忽略TTTTT
字段,手动解析并使用LocalDateTime.plusSeconds()
结果日期)?
换句话说,如何通过以下测试用例?
public class DateTimeParserTest {
private static final String PATTERN = "yyyy-MM-dd TTTTT";
private static final DateTimeFormatter FORMATTER =
DateTimeFormatter.ofPattern(PATTERN);
@Test
public void testParseSecondsOfDay() throws Exception {
String input = "2016-01-01 86399";
LocalDateTime localDateTime = LocalDateTime.parse(input, FORMATTER);
assertEquals("2016-01-01T23:59:59", localDateTime.toString());
}
}
答案 0 :(得分:2)
基于您的更正(省略了潜在的矛盾部分" HH:mm"),Java-8解决方案将如下所示:
private static final DateTimeFormatter FORMATTER =
new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd ")
.appendValue(ChronoField.SECOND_OF_DAY, 5)
.toFormatter();
答案 1 :(得分:0)
private static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; //MODIFICATION HERE
private static final DateTimeFormatter FORMATTER =
DateTimeFormatter.ofPattern(PATTERN);
@Test
public void testParseSecondsOfDay() throws Exception {
String input = "2016-01-01 00:00:86399";
int lastIndexOf = input.lastIndexOf(':');
CharSequence parsable = input.subSequence(0,lastIndexOf)+":00";
CharSequence TTTTPart = input.subSequence(lastIndexOf+1, input.length());
LocalDateTime localDateTime = LocalDateTime.parse(parsable, FORMATTER);
Calendar calendar = Calendar.getInstance(); // gets a calendar using the default time zone and locale.
calendar.set(
localDateTime.getYear(),
localDateTime.getMonth().ordinal(),
localDateTime.getDayOfMonth(),
localDateTime.getHour(),
localDateTime.getMinute(),
0);
calendar.add(Calendar.SECOND, Integer.parseInt(TTTTPart.toString()));
StringBuilder toParse = new StringBuilder();
toParse.append(calendar.get(Calendar.YEAR) /* It gives 2016 but you what 2016, why */-1);
toParse.append("-").append(calendar.get(Calendar.MONTH) + 1 < 10 ? "0" : "")
.append(calendar.get(Calendar.MONTH)+1);
toParse.append("-").append(calendar.get(Calendar.DAY_OF_MONTH) < 10 ? "0" : "")
.append(calendar.get(Calendar.DAY_OF_MONTH));
toParse.append(" ").append(calendar.get(Calendar.HOUR_OF_DAY) < 10 ? "0" : "")
.append(calendar.get(Calendar.HOUR_OF_DAY));
toParse.append(":").append(calendar.get(Calendar.MINUTE) < 10 ? "0" : "")
.append(calendar.get(Calendar.MINUTE));
toParse.append(":").append(calendar.get(Calendar.SECOND) < 10 ? "0" : "")
.append(calendar.get(Calendar.SECOND));
localDateTime = LocalDateTime.parse(toParse, FORMATTER);
//Why 2015 and not 2016?
assertEquals("2015-01-01T23:59:59", localDateTime.toString());
}
它让我感到困惑的是2015年而不是2016年,请注意该解决方案将为您提供2015而不是2016年。
答案 2 :(得分:0)
我还在使用Joda而没有使用java8,但它会是
Chronology lenient = LenientChronology.getInstance(ISOChronology.getInstance());
DateTimeFormatter FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:sssss").withChronology(lenient);
DateTime dateTime = DateTime.parse("2016-01-01 00:00:86399", FORMATTER);
assertEquals("2016-01-01T23:59:59", dateTime.toLocalDateTime().toString());
也许您可以使用以下方式获得相同的行为:
DateTimeFormatter formatter =
DateTimeFormatter.ISO_LOCAL_DATE.withResolverStyle(ResolverStyle.LENIENT);