如何在java中获取所需日期的日期对象?

时间:2018-12-13 17:58:04

标签: java date

我有一个日期对象,

Date d = new Date();

,它将返回当前日期和时间。但我需要将此日期对象分配为所需的日期。例如:从当前日期开始一周后,不使用Java中的Calendar类。反正有吗有一个类似的构造函数,

Date d = new Date(millis); 

将给出从1970年1月1日起的毫秒值。因此,从当前日期起一周后,有什么方法可以知道这个毫。例如,一个星期就是一个星期,也可以是一个月或两个月。

2 个答案:

答案 0 :(得分:1)

tl; dr

java.util.Date                   // The terrible awful nasty old class that you should never use. Represents a moment in UTC, with a resolution of milliseconds.
.from(                           // Convert from modern class to legacy class.
    Instant                      // Represent a moment in UTC, with a resolution of nanoseconds.
    .now()                       // Capture the current moment in UTC.
    .plus(                       // Add some span-of-time.
        Duration.ofDays( 7 )     // Generic chunks of 24-hours, without regard for the calendar.
    )                            // Returns another `Instant` object, per immutable objects pattern.
)                                // Returns a legacy `java.util.Date` object.

java.time

现代方法使用 java.time 类。

请勿使用java.util.Date。那是一门可怕的课,有很多缺陷。多年前由 java.time 类(特别是Instant)取代。您可以使用添加到旧类中的新方法来回转换。

Instant instant = myJavaUtilDate.toInstant() ;
  

从当前日期开始一周后

定义一个“星期”。您是要添加七个日历日期吗?如果是这样,在结果日期上想要什么时间?如果不是,您是说要添加一系列七个全天候24小时工作?

7 * 24小时

如果您打算增加7个通用的24小时工作日,请将InstantDuration一起使用。Duration是秒的计数加上以毫微秒为单位的秒。

也许这就是您在问题中“不带Calendar class”. That class would apply a time zone, while a java.util.Date`的神秘提及的意思,是在UTC中。

Duration sevenChunksOf24Hours = Duration.ofDays( 7 ) ;  // *NOT* calendar days.
Instant now = Instant.now() ;                           // Capture current moment in UTC.
Instant later = now.plus( d ) ;                         // Add the duration to the `Instant` thereby generating another `Instant`.

七个日历日

添加日期表示在日历上使用日期。时区对于确定日期至关重要。在任何给定时刻,日期都会在全球范围内变化。例如,Paris France午夜之后的几分钟是新的一天,而Montréal Québec仍然是“昨天”。

如果未指定时区,则JVM隐式应用其当前的默认时区。该默认值可能在运行时(!)期间change at any moment,因此您的结果可能会有所不同。最好将desired/expected time zone明确指定为参数。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用2-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

添加7个日历天。

LocalDate weekLater = today.plusWeeks( 1 ) ;

要花点时间,我们需要指定一个时间和一个时区。如果您想要一天的第一时刻,请 java.time 确定该时刻。永远不要以00:00作为一天的开始。诸如夏令时(DST)之类的异常可能意味着该日期从另一个时间(如01:00)开始。

ZonedDateTime zdt = weekLater.atStartOfDay( z ) ;

如果要在UTC的挂钟时间看到相同的值,请提取Instant。根据定义,Instant始终采用UTC。

Instant instant = zdt.toInstant() ;
  

举例来说,一周就是一个星期,也可以是一个月或两个月。

在这种情况下,不要硬编码对LocalDate::plusWeeks的呼叫,而是传递Period(以年,周,月,日为单位的计数)并呼叫LocalDate::plusPeriod使用日历天,而不是不是 24小时通用天。日历中的天数可以是任意长度,例如23、23.5、25小时,都与Period不相关。

Period p = Period.ofMonths( 2 ) ;
LocalDate later = today.plus( p ) ;                // Pass a `Period` for an number of years-weeks-months-days. A `Period` uses calendar-days, *not* generic 24-hour periods of time.
ZonedDateTime zdt = weekLater.atStartOfDay( z ) ;
Instant instant = zdt.toInstant() ;

如果您需要java.util.Date与尚未更新为 java.time 的旧代码进行互操作,请进行转换。

java.util.Date d = java.util.Date.from( instant ) ;

关于 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

答案 1 :(得分:0)

根据您的问题

  

但是我需要为此日期对象分配所需的日期   那么有什么方法可以从   当前的日期。例如,一个星期就可以,也可以是一个星期或一个星期   一个月或两个月。

我假设您想提供一个日期并检查它是否在其他日期之前或之后。您可以使用以下Java 8计时包来实现它:

LocalDateTime ldt = LocalDateTime.of(2018,12,13,20,0,0,0);

System.out.println(ldt.plusDays(5).isAfter(LocalDateTime.now()));

输出为:true

您可以将LocalDateTime.now()本身与另一个localDateTime进行比较,也可以设置确切的日期并使用plusDays() plusMonths()方法添加日/月/小时等。

或者您可以使用LocalDateTime将Date与现在的Date date = new Date(); LocalDateTime ld = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); System.out.println(ld.isAfter(ld.plusDays(5))); 进行比较,如下所示:

false

输出为:(