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

问题描述 投票:103回答:7

我正在使用JodaTime 1.6.2。

我有一个LocalDate,我需要转换为(Joda)LocalDateTime,或java.sqlTimestamp用于ormapping。

原因是我已经想出如何在LocalDateTimejava.sql.Timestamp之间进行转换:

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

所以,如果我可以在LocalDateLocalDateTime之间转换,那么我可以继续转换为java.sql.Timestamp。感谢任何正确方向的推动!

java timestamp jodatime
7个回答
240
投票

Jodatime

要将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());

Jwatime

要将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);

52
投票

使用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!


11
投票

tl;dr

Joda-Time项目处于维护模式,现在由java.time类取代。

  • 只需使用java.time.Instant类。
  • 不需要: LocalDateTime java.sql.Timestamp 字符串

捕获UTC中的当前时刻。

Instant.now()  

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

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

要从数据库中检索该时刻:

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

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

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

LocalDateTime is the wrong class

其他答案是正确的,但他们没有指出LocalDateTime是你的目的错误的类。

在java.time和Joda-Time中,LocalDateTime故意缺少任何时区概念或从UTC偏移。因此,它不代表片刻,也不是时间轴上的一个点。 LocalDateTime代表了大约26-27小时范围内潜在时刻的粗略概念。

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

使用ZonedDateTime来表示特定时区的时刻。例如,从任何特定区域开始的圣诞节,例如Pacific/AucklandAmerica/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 is the wrong class

java.sql.Timestamp是现在遗留下来的麻烦的旧日期时间类的一部分,完全由java.time类取代。这个类用来代表UTC的一个时刻,分辨率为nanoseconds。这个目的现在与java.time.Instant一起提供。

JDBC 4.2与getObject / setObject

JDBC 4.2及更高版本开始,您的JDBC driver可以通过调用以下命令直接与数据库交换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.

About java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.DateCalendarSimpleDateFormat

现在在Joda-Timemaintenance mode项目建议迁移到java.time班。

要了解更多信息,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规格是JSR 310

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

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。你可能会在这里找到一些有用的类,如IntervalYearWeekYearQuartermore


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

2
投票

由于Joda越来越褪色,有人可能想在Java 8中将LocaltDate转换为LocalDateTime。在Java 8 LocalDateTime中,它将提供一种方法来使用LocalDateTimeLocalDate创建LocalTime实例。检查here.

public static LocalDateTime(LocalDate date,LocalTime time)

样本会是,

    // 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);

1
投票

asStartOfDay()对象上的函数调用java.time.LocalDate返回一个java.time.LocalDateTime对象


0
投票

Java8 +

import java.time.Instant;
Instant.now().getEpochSecond(); //timestamp in seconds format (int)
Instant.now().toEpochMilli(); // timestamp in milliseconds format (long)
© www.soinside.com 2019 - 2024. All rights reserved.