0

I have a string that represents time duration of 54:34:41 i.e. 54 hours, 34 minutes, 41 seconds.

I would like to extract the 54 hours and subtract it from the current system time.

However when I run below I get java.time.format.DateTimeParseException: Text '54:34:41' could not be parsed: Invalid value for HourOfDay (valid values 0 - 23): 54

How can I extract 54 hours and subtract from current time?

private val formatterForTime: DateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss") val timeDuration = formatterForTime.parse("54:34:41") val currentTime = LocalDateTime.now() val newTime = currentTime.minusHours(timeDuration.get(ChronoField.HOUR_OF_DAY).toLong()) 
3
  • 1
    I cannot imagine a scenario where calling LocalDateTime.now is the right thing to do. That type lacks the context of a time zone or offset from UTC. So it cannot represent a moment, a specific point on the timeline. Commented Jun 4, 2022 at 7:53
  • Don’t you want to subtract the 34 minutes 41 seconds too? Related: Java: How to convert a string (HH:MM:SS) to a duration? Commented Jun 4, 2022 at 19:42
  • 1
    @OleV.V. correct, the answer below can be applied to minutes and second too. I use the same split function and instead pull index [1] (minute) and [2] (seconds), then use zdt.minusMinutes and zdt.minusSeconds respectively Commented Jun 4, 2022 at 20:22

1 Answer 1

2

tl;dr

ZonedDateTime .now( ZoneId.of( "Asia/Tokyo" ) ) .minusHours( Integer.parseInt( "54:34:41".split( ":" )[0] ) ) 

Details

Parse hours

Get the number of hours.

int hours = Integer.parseInt( "54:34:41".split( ":" )[0] ) ; 

ISO 8601

Your input text for a span-of-time does not comply with the ISO 8601 standard for date-time values. The java.time classes by default use the standard formats when parsing/generating text.

If instead of 54:34:41 you had PT54H34M41S, then we could use:

int hours = Duration.parse( "PT54H34M41S" ).toHours() ; 

I recommend you stick with the standard format rather than the ambiguous clock-time format.

Capture current moment

Capture the current moment as seen in a particular time zone.

ZoneId z = ZoneId.of( "Africa/Casablanca" ) ; ZonedDateTime zdt = ZonedDateTime.now( z ) ; 

Subtract hours

Subtract your hours.

ZonedDateTime earlier = zdt.minusHours( hours ) ) 
Sign up to request clarification or add additional context in comments.

3 Comments

thanks Basil. Is there any way to get the Locale ZonedDateTime from the phone/OS? Also, i am surprised there is not a more idiomatic way of parsing date with formatters/built in libraries. this solves my problem so have marked as correct answer.
@mairs8 ZoneId.systemDefault() returns the JVM’s current default time zone. Locale has nothing to do with tracking time.
@mairs8 As for idiomatic, your input text for a span-of-time not attached to the time zone does not comply with the ISO 8601 standard for date-time values used by default in the java.time classes. If instead of 54:34:41 you had PT54H34M41S, then we could use Duration.parse( "PT54H34M41S" ).toHours(). I recommend you use the standard format rather than the ambiguous clock-time format.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.