将秒数作为日期字符串的一部分进行解析

时间:2016-10-18 10:48:17

标签: java datetime datetime-format java-time datetime-parsing

我需要解析一个具有以下格式的日期字符串: 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());
    }
}

3 个答案:

答案 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);