将 java.util.Date 转换为 datastax 的 LocalDate

convert java.util.Date to datastax's LocalDate

我正在尝试将 yyyy-MM-dd 字符串格式的日期转换为 datastax 的 LocalDate。我正在使用以下代码来做到这一点。

private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");

public static LocalDate getDate(String date) throws ParseException {
    Date d = DATE_FORMAT.parse(date);
    return LocalDate.fromMillisSinceEpoch(d.getTime());
}

当我测试这个方法时,我没有得到预期的结果。

public static void main(String[] args) throws ParseException {
    System.out.println(getDate("2017-11-22"));
}
// Actual Output:
2017-11-21
// Excpected Output:
2017-11-22

这里有什么我遗漏的吗?

我的第一个猜测是,由于您约会的时区,有些混乱。要检查这一点,只需打印结果的小时和分钟。如果它是这样的,我不会感到惊讶 2017-11-21 23:00

你可以通过确保日期不会因为 'little time-zone difference'.

而改变来简单地修复它

为确保您的日期相差几个小时不会弄乱您可以执行此操作的日期(仅当您对日期的时间部分不感兴趣时​​ )

替换:

return LocalDate.fromMillisSinceEpoch(d.getTime())

通过(添加 12 小时以确保几个小时 +/- 不会更改日期)

return LocalDate.fromMillisSinceEpoch(d.getTime()+1000*60*60*12)

类似于:

public static LocalDate convertDate(final String date) {
    String[] arr = date.split("-");
    if (arr.length != 3)
        return null;
    return LocalDate.fromYearMonthDay(Integer.parseInt(arr[0]),
            Integer.parseInt(arr[1]),
            Integer.parseInt(arr[2]));
}

TL;DR

public static LocalDate getDate(String date) {
    java.time.LocalDate jtld = java.time.LocalDate.parse(date);
    return LocalDate.fromYearMonthDay(jtld.getYear(), jtld.getMonthValue(), jtld.getDayOfMonth());
}

java.time

您使用的 Java 日期和时间 class,DateSimpleDateFormat,早已过时且设计不佳,尤其是后者已被证明麻烦。此外,java.time,现代 Java 日期和时间 API,提供了一个 class 也称为 LocalDate,它比过时的 [=12] 更符合您的需要=] class。 java.time.LocalDate 是没有时间的日期。所以使用它完全消除了导致你的问题的时区问题。您的字符串 2017-11-22 采用 ISO 8601 格式,LocalDate 将其解析为默认格式,即没有任何明确的格式化程序,这也使您的任务更容易。

你的代码出了什么问题?

您的 SimpleDateFormat 实例默认使用 JVM 的时区设置(可能是 Asia/Kolkata 时间),因此将您的日期字符串解析为相当于 Wed Nov 22 2017 00:00:00 GMT+0530 (IST),这又与 2017 年 11 月 21 日在 18:30 UTC 的同一时间点。 LocalDate.fromMillisSinceEpoch() 的文档说:“如果给定的数字不对应于整数天数,它将向 0 舍入。”换句话说,它四舍五入到 2017-11-21。

如果你真的执着于守旧SimpleDateFormat,祝你好运(抱歉,你可能需要)。如果是这样,给它分配一个UTC时区,它会解析成UTC日期,无论JVM的时区设置如何,你现有的方法都可以工作。

private static final SimpleDateFormat DATE_FORMAT = buildOldfashionedDateFormatInstance();

private static SimpleDateFormat buildOldfashionedDateFormatInstance() {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    dateFormat.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
    return dateFormat;
}

链接