将 LocalDate 转换为 Timestamp 时获取前一天的 23:00

Getting 23:00 of the previous day when converting LocalDate to Timestamp

我最近从日历切换到 joda 时间 LocalDate 以避免我的项目中出现时区问题(我不需要那里的时区)。在某些时候,我需要从 LocalDate 获取时间戳:

  class DateTimeUtils{
   static Timestamp getDeadline(LocalDate localDate, int daysToAdd){
      localDate = localDate.plusDays(daysToAdd);
      System.out.println(localDate);//This prints 2017-06-02
      return new Timestamp(localDate.toDateTimeAtStartOfDay().getMillis());         
   }
  public static void main(String... args){
     LocalDate localDate= new LocalDate(2017,5,31);
     Timestamp timeStamp=getDeadline(localDate,2);
     System.out.println(timeStamp);//This prints 2017-06-01 23:00:00.0
  }
 }

不知为何,将localdate转换为timestamp后,结果回落到前一天的23:00。这是为什么?

您是否尝试过使用新的 Java 8 日期时间 API?它允许与像 java.sql.Timestamp 这样的遗留 类 轻松互操作。下面的代码给出了 JDK 8 java.time 类.

的预期结果
public class DateTimeUtils {
    static Timestamp getDeadline(LocalDate localDate, int daysToAdd) {
        localDate = localDate.plusDays(daysToAdd);
        return Timestamp.valueOf(localDate.atStartOfDay());
    }

    public static void main(String... args) {
        LocalDate localDate = LocalDate.of(2017, 5, 31);
        Timestamp timestamp = getDeadline(localDate, 2);
        System.out.println(timestamp);// This prints 2017-06-02 00:00:00.0
    }
}

时区很重要

to avoid timezone issues in my project

你不能忽视时区问题。一厢情愿的梦想。勇敢一点,不畏艰险,接受学习处理时区的挑战。你的编程工作会轻松很多。

在调用 toDateTimeAtStartOfDay 时,您选择省略时区参数,即 DateTimeZone 对象。因此,在运行时,JVM 当前的默认时区被隐式应用。

然后你转换成一个 java.sql.Timestamp(显然——你没有明确说明包),它总是在 UTC 中。

您没有提供您的运行时当前默认时区,所以我无法提供更准确的细节。

使用java.time

Joda-Time 项目现在处于维护模式,其团队建议迁移到 java.time 类。这两个项目都由同一个人 Stephen Colebourne 领导,因此他们共享相同的概念方法。很容易切换。

要获取今天的日期,请指定时区。对于任何给定时刻,日期在全球范围内因地区而异。

看看我们如何将区域传递给 atStartOfDay

ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z );
LocalDate twoDaysLater = today.plusDays( 2 ) ;
ZonedDateTime zdt = twoDaysLater.atStartOfDay( z ) ;
Instant instant = zdt.toInstant();  // Instant is always in UTC by definition. 

使用 JDBC 4.2 及更高版本,您可以直接使用 java.time 类型。调用 PreparedStatement.setObjectResultSet.getObject.


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time 类.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

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

在哪里获取java.time类?

  • Java SE 8, Java SE 9,及以后
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and Java SE 7
  • Android
    • Android java.time 类.
    • 捆绑实施的更高版本
    • 对于较早的 Android (<26),ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.