根据 Java 中的开始日期和期间生成新日期

Generate new date based on start date and period in Java

所以我有:

Date startDateSun Mar 27 17:32:01 EEST 2022

String periodPT240H

我需要根据这两个值生成一个新日期。我需要将 240H 时间段添加到 startDate。 240H 表示我需要添加到 startDate 的 10 天,我最终需要一个新日期,该日期应该是 Wed Apr 6 17:32.01 EEST 2022.

PS。我是 Java 的新手,希望我不要问愚蠢的问题。

tl;博士

java.util.Date.from( 
    myJavaUtilDate
    .toInstant()
    .plus( Duration.parse( "PT240H" ) ) 
)

详情

将发布的评论放在一起……

您使用的是多年前被现代 java.time classes 取代的可怕 date-time classes 定义在 JSR 310 中。避免使用 DateCalendar 等。

如果递给一个 java.util.Date 对象,立即转换为它的替换 class、java.time.Instant。使用添加到旧 classes 的新转换方法。

Instant instant = myJavaUtilDate.toInstant() ;

将标准 ISO 8601 格式的输入字符串解析为 Duration 对象。

Duration d = Duration.parse( "PT240H" ) ;

添加到我们的 Instant 以产生第二个 Instant,根据 immutable objects

Instant later = instant.plus( d ) ;

你说:

The 240H meaning 10 days

不正确,240 小时不一定是 10 天。如果您调整到一个时区,则添加 240 小时的值可能会或可能不会导致十天后的某个时刻。某些时区的某些日期长度不同,运行宁 23、23.5、25 或其他小时数。

请注意,java.util.DateInstant 都代表 UTC 中的时刻,即偏移量为零 hours-minutes-seconds。不幸的是,Date#toString 方法在生成文本时会动态应用 JVM 当前的默认时区——给人一种错觉。这种令人困惑的行为是遗留 date-time classes.

中的众多设计流程之一

如果您必须与尚未更新到 java.time 的旧代码进行互操作,您可以转换回 Date。但我强烈建议尽快摆脱这些遗留问题 classes。

java.util.Date date = Date.from( someInstant ) ; 

示例代码

仅供参考,EEST 不是 时区。这样的 2-4 个字母 pseudo-zones 表示夏令时 (DST) 是否生效,并暗示可能的时区。这些应该仅用于向用户展示,绝不能用于您的业务逻辑、数据存储或数据交换。

Real time zonesContinent/Region的格式命名,例如Africa/CasablancaAsia/Tokyo.

pseudo-zone EEST 表示许多不同的时区。在此示例代码中,我使用实时时区 "Europe/Bucharest"。根据您的用户资料,我猜那是您的区域。

首先,我们需要将 Date#toString 报告的时刻重新创建为“2022 年 3 月 27 日星期日 17:32:01 EEST”。

// Recreate original conditions.
LocalDate ld = LocalDate.of( 2022 , Month.MARCH , 27 );  // Sun Mar 27 17:32:01 EEST 2022
LocalTime lt = LocalTime.of( 17 , 32 , 1 );
ZoneId z = ZoneId.of( "Europe/Bucharest" );
TimeZone.setDefault( TimeZone.getTimeZone( z ) );
ZonedDateTime zdtStarting = ZonedDateTime.of( ld , lt , z );
Instant then = zdtStarting.toInstant();
java.util.Date startingPoint = Date.from( then );

从传统 class 转换为现代。

Instant instant = startingPoint.toInstant();

添加您想要的 240 小时。调整成一个时区得到一个ZonedDateTime,这样我们才能更好的看出它的真正含义。

Duration duration = Duration.parse( "PT240H" );
Instant later = instant.plus( duration );
Date endingPoint = Date.from( later );
ZonedDateTime zdtLater = later.atZone( z );

转储到控制台。

System.out.println( "-------|  Start  |--------------------" );
System.out.println( "zdtStarting = " + zdtStarting );
System.out.println( "startingPoint = " + startingPoint );
System.out.println( "instant = " + instant );
System.out.println( "-------|  End  |--------------------" );
System.out.println( "later = " + later );
System.out.println( "endingPoint = " + endingPoint );
System.out.println( "zdtLater = " + zdtLater );

当运行.

-------|  Start  |--------------------
zdtStarting = 2022-03-27T17:32:01+03:00[Europe/Bucharest]
startingPoint = Sun Mar 27 17:32:01 EEST 2022
instant = 2022-03-27T14:32:01Z
-------|  End  |--------------------
later = 2022-04-06T14:32:01Z
endingPoint = Wed Apr 06 17:32:01 EEST 2022
zdtLater = 2022-04-06T17:32:01+03:00[Europe/Bucharest]