我正在使用JodaTime 1.6.2。
我有一个LocalDate
,我需要转换为(乔达(LocalDateTime
或用于或映射的java.sqlTimestamp
。
这样做的原因是我已经弄清楚了如何在LocalDateTime
和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
.感谢您在正确方向上的任何推动!
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());
<小时 />爪哇时间
要将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);
使用 Java 8 时间 API 的最佳方式:
LocalDateTime ldt = timeStamp.toLocalDateTime();
Timestamp ts = Timestamp.valueOf(ldt);
要与模型 (https://weblogs.java.net/blog/montanajava/archive/2014/06/17/using-java-8-datetime-classes-jpa( 一起放入的 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!
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.
要从datbase检索该时刻:
myResultSet.getObject( … , Instant.class ) // Instantiates a `Instant`
将挂钟时间调整为特定时区的时间。
instant.atZone( z ) // Instantiates a `ZonedDateTime`
LocalDateTime
是错误的类
其他答案是正确的,但它们没有指出LocalDateTime
是错误的类。
在java.time和Joda-Time中,LocalDateTime
故意缺乏时区或UTC偏移量的任何概念。因此,它不代表一个时刻,也不是时间轴上的一个点。LocalDateTime
表示对大约 26-27 小时内潜在时刻的粗略想法。
当区域/偏移量未知(情况不佳(或区域偏移量不确定时,请使用LocalDateTime
。例如,"圣诞节从 2018 年 12 月 25 日的第一刻开始"将表示为LocalDateTime
。
使用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
/setObject
的 JDBC 4.2
从 JDBC 4.2 及更高版本开始,JDBC 驱动程序可以通过调用以下命令直接与数据库交换 java.time 对象:
-
PreparedStatement::setObject
-
ResultSet::getObject
例如:
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 教程。并搜索堆栈溢出以获取许多示例和解释。规范为 JSR 310。
您可以直接与数据库交换java.time对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要java.sql.*
类。
从哪里获得java.time类?
- Java SE
- 8、Java SE 9 及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9添加了一些小功能和修复。
Java SE - 6 和 Java SE 7
- 许多java.time功能在ThreeTen-Backport中向后移植到Java 6和7。
- 人造人
- java.time 类的 Android 捆绑包实现的更高版本。
- 对于早期的Android(<26(,ThreeTenABP项目适应了ThreeTen-Backport(如上所述(。请参阅如何使用ThreeTenABP...。
ThreeTen-Extra项目通过额外的类扩展了java.time。这个项目是未来可能添加到java.time的试验场。你可以在这里找到一些有用的类,如Interval
、YearWeek
、YearQuarter
等。
java.time.LocalDate
对象上的函数调用asStartOfDay()
返回一个java.time.LocalDateTime
对象
根据您的时区,您可能会损失几分钟(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);
由于Joda正在褪色,有人可能想在Java 8中将LocaltDate
转换为LocalDateTime
。在Java 8 LocalDateTime
中,它将提供一种使用LocalDate
和LocalTime
创建LocalDateTime
实例的方法。查看此处。
public static LocalDateTime of(LocalDate date, 当地时间(
示例将是,
// 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);
Java8 +
import java.time.Instant;
Instant.now().getEpochSecond(); //timestamp in seconds format (int)
Instant.now().toEpochMilli(); // timestamp in milliseconds format (long)