如果未定义HH:mm:ss,如何将ZonedDateTime默认创建为午夜?

时间:2017-05-18 01:37:59

标签: java datetime java-8

这是我想要做的事情:

public ZonedDateTime getZdt(String myDate, String format) {
    return  ZonedDateTime.parse(
                myDate,   
                DateTimeFormatter.ofPattern(format)
                    .withZone(ZoneId.systemDefault())
            );
}

getZdt("17-05-2017 00:10:59", "dd-MM-yyyy HH:mm:ss") //works fine
getZdt("17-05-2017", "dd-MM-yyyy") //DateTimeParseException (...Unable to obtain LocalTime from TemporalAccessor:) 

我想做的事情非常简单。我如何让它工作?

3 个答案:

答案 0 :(得分:2)

一种可能性是将您的方法更改为以下内容:

public ZonedDateTime getZdt(String myDate, String format) {
    try {
        return ZonedDateTime.parse(myDate, DateTimeFormatter.ofPattern(format).withZone(ZoneId.systemDefault()));
    } catch (DateTimeException e) {
        return ZonedDateTime.parse(myDate + " 00:00:00", DateTimeFormatter.ofPattern(format + " HH:mm:ss").withZone(ZoneId.systemDefault()));
    }
}

这假设只有在DateTimeException不够时才会抛出format。但是,我认为在这种情况下让你拥有Exception会更好,但这样可行。

我想看看是否有其他人有更简单的方法来解决这个问题。

答案 1 :(得分:2)

我有三个建议。

首先,那必须是同一种方法吗?你能有两个吗?我假设你只有两种可能的格式;如果你有十个,我认为这是一个不同的故事。

/** gets a ZonedDateTime from a date string with no time information */
public ZonedDateTime getZdtFromDateString(String myDate, String format) {
    return LocalDate.parse(myDate, DateTimeFormatter.ofPattern(format))
            .atStartOfDay(ZoneId.systemDefault());
}

您当然可以省略format参数并使格式保持不变。

当然,您可以通过单一方法获得所需内容。我建议你的方法自己检测它,而不是将格式传递给方法。

一个选项是处理两种格式的自定义DateTimeFormatter

private static final DateTimeFormatter format = new DateTimeFormatterBuilder().appendPattern("dd-MM-uuuu")
        .optionalStart()
        .appendPattern(" HH:mm:ss")
        .optionalEnd()
        .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
        .toFormatter();

public ZonedDateTime getZdt(String myDate) {
    return LocalDateTime.parse(myDate, format).atZone(ZoneId.systemDefault());
}

最后,Jacob G.’s idea of trying both并不算太糟糕。这是我的版本:

public ZonedDateTime getZdt(String myDate, String format) {
    try {
        return LocalDateTime.parse(myDate, DateTimeFormatter.ofPattern(format))
                .atZone(ZoneId.systemDefault());
    } catch (DateTimeParseException dtpe) {
        return LocalDate.parse(myDate, DateTimeFormatter.ofPattern(format))
                .atStartOfDay(ZoneId.systemDefault());
    }
}

同样,人们可能更愿意省略format参数并使用两种常量格式。

答案 2 :(得分:1)

您需要先解析LocalDate,然后才能将其转换为ZonedDateTime

LocalDate.parse("17-05-2017", DateTimeFormatter.ofPattern("dd-MM-yyyy"))
        .atStartOfDay(ZoneId.systemDefault())