Home > Blockchain >  Generate new date based on start date and period in Java
Generate new date based on start date and period in Java

Time:04-01

So I have:

Date startDate which is Sun Mar 27 17:32:01 EEST 2022

and

String period which is PT240H

And I need to generate a new date based on those 2 values. I need to add that 240H period to the startDate. The 240H meaning 10 days which I need to add to startDate and I will eventually need to have a new date which should be Wed Apr 6 17:32.01 EEST 2022.

PS. I am new to Java, hopefully I don't ask stupid things.

CodePudding user response:

tl;dr

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

Details

Putting together those posted Comments…

You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310. Avoid using Date, Calendar, and such.

If handed a java.util.Date object, immediately convert to its replacement class, java.time.Instant. Use new conversion methods added to the old classes.

Instant instant = myJavaUtilDate.toInstant() ;

Parse your input string in standard ISO 8601 format as a Duration object.

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

Add to our Instant to produce a second Instant, per immutable objects.

Instant later = instant.plus( d ) ;

You said:

The 240H meaning 10 days

Incorrect, 240 hours is not necessarily 10 days. Adding a value of 240 hours may or may not result in a moment ten days later, if you adjust into a time zone. Some dates in some time zones vary in length, running 23, 23.5, 25, or other numbers of hours long.

And be aware that both java.util.Date and Instant represent a moment as seen in UTC, that is, with an offset of zero hours-minutes-seconds. Unfortunately, the Date#toString method dynamically applies the JVM’s current default time zone while generating its text — giving a false illusion. This confusing behavior is one of the many design flows in the legacy date-time classes.

If you must interoperate with old code not yet updated to java.time, you can convert back to Date. But I strongly recommend moving away from these legacy classes ASAP.

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

Example code

FYI, EEST is not a time zone. Such 2-4 letter pseudo-zones indicate whether Daylight Saving Time (DST) is in effect, and hint at possible time zones. These should be used only for presentation to the user, never in your business logic, data storage, nor data exchange.

Real time zones are named in format of Continent/Region such as Africa/Casablanca and Asia/Tokyo.

The pseudo-zone EEST implies many different time zones. In this example code I use the real time zone "Europe/Bucharest". I am guessing that is your zone, given your user profile.

First we need to recreate your moment reported by Date#toString as ‘Sun Mar 27 17:32:01 EEST 2022’.

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

Convert from legacy class to modern.

Instant instant = startingPoint.toInstant();

Add your desired 240 hours. Adjust into a time zone to obtain a ZonedDateTime, so we can better see its true meaning.

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

Dump to console.

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

When run.

-------|  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]
  • Related