如何将 Joda Localdate 转换为 Joda DateTime?

Posted

技术标签:

【中文标题】如何将 Joda Localdate 转换为 Joda DateTime?【英文标题】:How to convert Joda Localdate to Joda DateTime? 【发布时间】:2011-06-07 02:11:20 【问题描述】:

我试图在执行更多计算之前简单地将 TimeZone 信息添加回 LocalDate。 LocalDate 来自使用 ObjectLab LocalDateCalculator 将天数添加到现有 DateTime 但该方法需要返回一个修改后的 ReadableInstant 以形成一个间隔,然后我可以检查它。

我正在尝试的代码相当于将 Joda LocalDate 转换为 Joda DateTime:

LocalDate contextLocalBusinessDate = calculator.getCurrentBusinessDate();
DateTime businessDateAsInContextLocation = new DateTime(contextLocalBusinessDate, contextTimeZone);

我得到的错误来自 Joda 的转换系统:

java.lang.IllegalArgumentException: No instant converter found for type: org.joda.time.LocalDate
        at org.joda.time.convert.ConverterManager.getInstantConverter(ConverterManager.java:165)
        at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:147)
        at org.joda.time.DateTime.<init>(DateTime.java:192)

我正在寻找解决此问题的方法,或者寻找一种解决方法,以产生具有完整时区信息的准确间隔。

【问题讨论】:

【参考方案1】:

LocalDate 上有多种方法可以做到这一点,包括:

LocalDate::toDateTimeAtCurrentTime() LocalDate::toDateTimeAtStartOfDay() LocalDate::toDateTime( LocalTime ) LocalDate::toDateTime( LocalTime , DateTimeZone )

您必须明确说明您希望生成的DateTime 对象中的时间组件是什么,这就是DateTime 的通用转换构造函数无法做到这一点的原因。

【讨论】:

正确。需要注意的一件事:toDateTimeAtStartOfDay 并不意味着“午夜”......某些时区实施夏令时更改以从午夜跳到凌晨 1 点。 您可能会像我一样得出结论,您选择哪种方法(都返回 DateTime,就像这里的那些)并不重要:使用 LocalDate 的事实应该暗示它是在该日期的特定时间没有任何意图进行编码,因此无论您在该日期的转换中给出的任何时间都与该日期的任何其他时间一样好。关键是给它一个时间是允许转换为 LocalDate 的原因,如果你只需要某种 DateTime . 请帮助 - 我在我的 LocalDate 对象上看不到任何这些方法。您的答案中的“::”符号是什么意思?【参考方案2】:

java.time

以下引用来自home page of Joda-Time的通知:

请注意,从 Java SE 8 开始,用户被要求迁移到 java.time (JSR-310) - JDK 的核心部分,它取代了这个项目。

使用现代日期时间 API java.time 的解决方案:

LocalDate 转换为ZonedDateTime 的常用方法是首先使用00:00 小时将其转换为LocalDateTime,使用LocalDate#atStartOfDay,然后与ZoneId 组合。 LocalDate#atStartOfDay 的替代品是 LocalDate#atTime(LocalTime.MIN)

请注意,LocalDate#atStartOfDay(ZoneId)atStartOfDay 的另一个变体。但是,它可能不会在 DST 转换当天返回带有 00:00 小时的 ZonedDateTime

您可以使用ZonedDateTime#toOffsetDateTimeZonedDateTime 转换为OffsetDateTime

演示:

import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main 
    public static void main(String[] args) 
        LocalDate today = LocalDate.now();
        // Note: Change the ZoneId as applicable e.g. ZoneId.of("Europe/London")

        ZonedDateTime zdt = today.atStartOfDay().atZone(ZoneId.systemDefault());
        System.out.println(zdt);

        OffsetDateTime odt = zdt.toOffsetDateTime();
        System.out.println(odt);
    

输出:

2021-07-11T00:00+01:00[Europe/London]
2021-07-11T00:00+01:00

ONLINE DEMO

Trail: Date Time 了解有关现代日期时间 API 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。

【讨论】:

以上是关于如何将 Joda Localdate 转换为 Joda DateTime?的主要内容,如果未能解决你的问题,请参考以下文章

将 LocalDate 转换为 LocalDateTime 或 java.sql.Timestamp

JODA 夏令时转换

Java Joda-Time ,将 LocalDate 分配给 Month 和 Year

为什么org.joda.time.LocalDate是没有时区的日期?

org.joda.time.localdate 获得某个月有多少天

使用 Java8 将年份字符串解析为 LocalDate