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


126

我正在使用JodaTime 1.6.2。

我有一个LocalDate需要转换为(Joda)LocalDateTime或java.sqlTimestampfor ormapping的。

原因是我想出了如何在a LocalDateTime和a 之间进行转换java.sql.Timestamp:

LocalDateTime ldt = new LocalDateTime();
DateTimeFormatter dtf = DateTimeFormatter.forPattern("yyyy-MM-dd HH:mm:ss");
Timestamp ts = Timestamp.valueOf(ldt.toString(dtf));

因此,如果我可以在LocalDate和之间进行转换LocalDateTime,则可以继续转换为java.sql.Timestamp。感谢您朝着正确的方向前进!


仅供参考,Joda-Time项目现在处于维护模式,团队建议迁移到java.time类。请参见Oracle教程。而且,java.sql.Timestamp该类现在是旧式的,由java.time类(尤其是)取代了Instant。
— 罗勒·布尔克

Answers:


269

乔达时间

要将JodaTime转换org.joda.time.LocalDate为java.sql.Timestamp,只需执行

Timestamp timestamp = new Timestamp(localDate.toDateTimeAtStartOfDay().getMillis());

要将JodaTime转换org.joda.time.LocalDateTime为java.sql.Timestamp,只需执行

Timestamp timestamp = new Timestamp(localDateTime.toDateTime().getMillis());

Java时间

要将Java8转换java.time.LocalDate为java.sql.Timestamp,只需执行

Timestamp timestamp = Timestamp.valueOf(localDate.atStartOfDay());

要将Java8转换java.time.LocalDateTime为java.sql.Timestamp,只需执行

Timestamp timestamp = Timestamp.valueOf(localDateTime);

转换为时请当心LocalDateTime,DateTime因为并非所有LocalDateTimes都有效DateTime。资料来源:joda-time.sourceforge.net/faq.html#illegalinstant,并且正好遇到了这个问题。
— Christophe De Troyer

由于valueOf()接受字符串,导致参数出现编译错误。
— 爱国

@Patriotic:只有在您实际上不使用Java SE 1.8或更高版本时,才会发生这种情况。如答案中所示,并在指向Javadoc的链接中提供了答案(上述答案中的蓝色文本实际上是链接,您可以单击它们以深入到Javadoc中),该Timestamp#valueOf()方法接受,因为Java SE 1.8也是a LocalDateTime。
— BalusC

60

使用Java 8时间API的最佳方法:

  LocalDateTime ldt = timeStamp.toLocalDateTime();
  Timestamp ts = Timestamp.valueOf(ldt);

用于与模型一起插入的JPA(https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa):

@Converter(autoApply = true)
public class LocalDateTimeConverter implements AttributeConverter<LocalDateTime, Timestamp> {
    @Override
    public Timestamp convertToDatabaseColumn(LocalDateTime ldt) {
        return Timestamp.valueOf(ldt);
    }

    @Override
    public LocalDateTime convertToEntityAttribute(Timestamp ts) {
        return ts.toLocalDateTime();
    }
}

因此,现在是相对时区独立时间。此外,很容易做到:

  LocalDate ld = ldt.toLocalDate();
  LocalTime lt = ldt.toLocalTime();

格式:

 DateTimeFormatter DATE_TME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
 String str = ldt.format(DATE_TME_FORMATTER);
 ldt = LocalDateTime.parse(str, DATE_TME_FORMATTER);

更新:postgres 9.4.1208,HSQLDB 2.4.0等无需任何对话即可理解Java 8 Time API!


17

tl; dr

该乔达时间项目处于维护模式,现在取代java.time类。

  • 只需使用java.time.Instant类。
  • 无需:
    • LocalDateTime
    • java.sql.Timestamp
    • 弦乐

在UTC中捕获当前时刻。

Instant.now()  

将该时刻存储在数据库中:

myPreparedStatement.setObject( … , Instant.now() )  // Writes an `Instant` to database.

要从datbase检索该时刻:

myResultSet.getObject( … , Instant.class )  // Instantiates a `Instant`

将壁钟时间调整为特定时区的时间。

instant.atZone( z )  // Instantiates a `ZonedDateTime`

LocalDateTime 是错误的班级

其他答案是正确的,但他们未能指出这LocalDateTime是您目的不正确的课程。

在java.time和Joda-Time中,LocalDateTime故意缺乏时区或UTC偏移量的任何概念。因此,它并不能代表一个时刻,是不是在时间轴上的一个点。A LocalDateTime代表关于大约26-27小时范围内潜在时刻的粗略想法。

使用LocalDateTime的既可以当偏移区域/未知(不是一个好的情况),或者当区域偏移是不确定的。例如,“圣诞节始于2018年12月25日的第一刻”将表示为LocalDateTime。

使用a ZonedDateTime代表特定时区中的时刻。例如,圣诞节始于任何特定区域,例如Pacific/Auckland或America/Montreal将以一个ZonedDateTime对象表示。

暂时在UTC中使用Instant。

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

应用时区。时间轴上的相同时刻,相同点,但使用不同的挂钟时间查看。

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;  // Same moment, different wall-clock time.

因此,如果我可以在LocalDate和LocalDateTime之间进行转换,

不,错误的策略。如果您有一个仅日期的值,并且想要一个日期时间值,则必须指定一个时间。该日期可能在该日期对于特定区域无效-在这种情况下,ZonedDateTime班级会根据需要自动调整该时间。

LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.of( 14 , 0 ) ;  // 14:00 = 2 PM.
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

如果您希望将一天的第一时刻作为时刻,请让java.time确定该时刻。不要以为一天从00:00:00开始。诸如夏令时(DST)之类的异常表示一天可能在另一个时间(例如01:00:00)开始。

ZonedDateTime zdt = ld.atStartOfDay( z ) ;

java.sql.Timestamp 是错误的班级

这java.sql.Timestamp是麻烦的旧日期时间类的一部分,而现在这些日期时间类已被遗留,完全由java.time类取代。该类用于表示UTC中具有纳秒分辨率的时刻。现在已达到该目的java.time.Instant。

带有getObject/的JDBC 4.2setObject

从JDBC 4.2及更高版本开始,您的JDBC驱动程序可以通过调用以下命令直接与数据库交换java.time对象:

例如:

myPreparedStatement.setObject( … , instant ) ;

……和……

Instant instant = myResultSet.getObject( … , Instant.class ) ;

转换旧的⬌现代

如果必须使用尚未更新为java.time的旧代码进行接口,请使用添加到旧类中的新方法来回转换。

Instant instant = myJavaSqlTimestamp.toInstant() ;  // Going from legacy class to modern class.

…和…

java.sql.Timestamp myJavaSqlTimestamp = java.sql.Timestamp.from( instant ) ;  // Going from modern class to legacy class.

关于java.time

该java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat。

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*

在哪里获取java.time类?

该ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如Interval,YearWeek,YearQuarter,和更多。


5

根据您的时区,您可能会丢失几分钟(1650-01-01 00:00:00变成1649-12-31 23:52:58)

使用以下代码来避免这种情况

new Timestamp(localDateTime.getYear() - 1900, localDateTime.getMonthOfYear() - 1, localDateTime.getDayOfMonth(), localDateTime.getHourOfDay(), localDateTime.getMinuteOfHour(), localDateTime.getSecondOfMinute(), fractional);

3

由于乔达是越来越淡了,有人可能要转换LocaltDate到LocalDateTimeJava中8在Java 8 LocalDateTime它将给一个方法来创建一个LocalDateTime使用实例LocalDate和LocalTime。在这里检查。

公共静态LocalDateTime((LocalDate日期,LocalTime时间)

样本是

    // just to create a sample LocalDate
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
    LocalDate ld = LocalDate.parse("20180306", dtf);

    // convert ld into a LocalDateTime
    // We need to specify the LocalTime component here as well, it can be any accepted value
    LocalDateTime ldt = LocalDateTime.of(ld, LocalTime.of(0,0)); // 2018-03-06T00:00

仅供参考,可以使用下面的纪元秒,

    ZoneId zoneId = ZoneId.systemDefault();
    long epoch = ldt.atZone(zoneId).toEpochSecond(); 

    // If you only care about UTC
    long epochUTC = ldt.toEpochSecond(ZoneOffset.UTC);

LocalDateTime这里根本不需要使用。该类故意缺少时区或UTC偏移的任何概念。因此,这里没有任何用处。而是:LocalDate.parse( “20180306” , DateTimeFormatter.BASIC_ISO_DATE ).atStartOfDay( ZoneId.of( “Africa/Tunis” ).toEpochSecond()不要假设一天从00:00开始,并非总是如此。
— 罗勒·布尔克

您是说Whay的意思是,不要假设一天从00.00开始
— 黄金

1
诸如夏令时(DST)之类的异常表示一天在某些地方的某些日期可能会在另一时间开始,例如01:00:00。因此,而不是假设,让java.time通过调用java.time.LocalDate.atStartOfDayget 来确定第一时刻ZonedDateTime。请参阅我的答案中的示例。正如我所评论的那样,LocalDateTime该类在所有这些方面都是无用的且适得其反。
— 罗勒·布尔克

因此LocalDateTime必须使用ZoneId?
— 黄金

我想你已经错过了我所有的观点。在此页面上重读我的答案。搜索堆栈溢出可从更多示例和讨论中了解更多信息。但我会说这里的最后一次:LocalDateTime是不是在手拨出这里的问题。一个LocalDateTime不会不表示一个时刻。尽管名称乍一看可能暗示其他名称,但A 与任何特定的地区LocalDateTime或时区都没有关系 –了解有关此类的意图和细节的更多信息。该LocalDateTime班也服务于一个目的,但不是在这个问题上看到的目的。
— 罗勒·布尔克


0

Java8 +

import java.time.Instant;
Instant.now().getEpochSecond(); //timestamp in seconds format (int)
Instant.now().toEpochMilli(); // timestamp in milliseconds format (long)

有用,但似乎并未真正回答问题。
— Ole VV

感谢您提供的代码,但与该问题无关。
— refaelio
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.