tl;dr
You said:
My end goal is to compare these historical dates to the current time and get a time difference between them.
record History( String dt , int offset , boolean dst ) { }
Instant now = Instant.now();
List.of(
new History( "2022-07-15 13:32:00" , 5 , false ) ,
new History( "2022-01-15 13:32:00" , 5 , true ) ,
new History( "2022-07-15 13:32:00" , 7 , false )
)
.forEach(
history -> System.out.println(
Duration.between(
LocalDateTime
.parse(
history.dt().replace( " " , "T" )
)
.atOffset(
ZoneOffset.ofHours( history.offset() )
)
.toInstant() ,
now
)
)
);
PT17H4M40.423919S
PT4361H4M40.423919S
PT19H4M40.423919S
OffsetDateTime
The other two Answers by Mark Rotteveel and by Adam Hughes are both basically correct. But they, like the Question, use ZonedDateTime rather than the more appropriate class, OffsetDateTime. And they do not address the specific parsing needs asked in the Question. And apparently the input data is already in objects, so I will represent that as records.
public record History( String dt , int offset , boolean dst ) { }
Populate some data.
List < History > historyList =
List.of(
new History( "2022-07-15 13:32:00" , 5 , false ) ,
new History( "2022-01-15 13:32:00" , 5 , true ) ,
new History( "2022-07-15 13:32:00" , 7 , false )
);
We need to produce a java.time.OffsetDateTime object for each of those inputs. We can add a method to our record to perform that work.
To parse the given inputs, we can either define a DateTimeFormatter with a formatting pattern to match, or we can do string manipulation to bring the inputs into compliance with the ISO 8601 standard format used by default in OffsetDateTime.parse. I choose the latter. We simply need to replace the SPACE in the middle with a T.
As Rotteveel mentioned in his Answer, the boolean for whether Daylight Saving Time (DST) is in effect or not is irrelevant. We ignore that member field in our History record.
public record History( String dt , int offset , boolean dst )
{
OffsetDateTime toOffsetDateTime ( )
{
LocalDateTime ldt = LocalDateTime.parse( this.dt.replace( " " , "T" ) );
ZoneOffset o = ZoneOffset.ofHours( this.offset );
OffsetDateTime odt = ldt.atOffset( o );
return odt;
}
}
Capture the current moment.
Instant now = Instant.now() ;
Your goal is to determine elapsed time. Use Duration for that. We can add another method to History record for that purpose.
package work.basil.example.history;
import java.time.*;
public record History( String dt , int offset , boolean dst )
{
OffsetDateTime toOffsetDateTime ( )
{
LocalDateTime ldt = LocalDateTime.parse( this.dt.replace( " " , "T" ) );
ZoneOffset o = ZoneOffset.ofHours( this.offset );
OffsetDateTime odt = ldt.atOffset( o );
return odt;
}
Duration elapsed ( final Instant instant )
{
Duration d = Duration.between( this.toOffsetDateTime().toInstant() , instant );
return d;
}
}
Loop the inputs to report their elapsed time.
Instant now = Instant.now();
for ( History history : historyList )
{
String message = history.elapsed( now ).toString() + " from " + history.toString() + " to " + now.toString();
System.out.println( message );
}
When run.
PT16H27M40.119075S from History[dt=2022-07-15 13:32:00, offset=5, dst=false] to 2022-07-16T00:59:40.119075Z
PT4360H27M40.119075S from History[dt=2022-01-15 13:32:00, offset=5, dst=true] to 2022-07-16T00:59:40.119075Z
PT18H27M40.119075S from History[dt=2022-07-15 13:32:00, offset=7, dst=false] to 2022-07-16T00:59:40.119075Z