danilo
danilo

Reputation: 844

Java LocalDateTime remove the milliseconds from UTC timezone

I am trying to truncate milliseconds from a UTC time zone.

I have the code below where I am able to remove milliseconds but I still get the Z at the end.

OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC );
OffsetDateTime eventDateTime=now.minus(4, ChronoUnit.MINUTES);

System.out.println("====Event date Time before truncate===");
System.out.println(eventDateTime);
      
System.out.println("====Event date Time after truncate===");
System.out.println(eventDateTime.truncatedTo(ChronoUnit.SECONDS));

This outputs the following:

====Event date Time before truncate===

2021-03-09T20:46:24.081Z

====Event date Time after truncate===

2021-03-09T20:46:24Z

Upvotes: 1

Views: 4019

Answers (3)

Basil Bourque
Basil Bourque

Reputation: 340098

tl;dr

To represent a moment in UTC, use Instant class rather than LocalDateTime or OffsetDateTime.

Instant
    .now()                        // Returns a `Instant` representing the current moment including a fractional second.
    .truncatedTo( 
        ChronoUnit.SECONDS        // Granularity of what you want chopped off. In this case, we lop off any fractional second.
    )                             // Returns another `Instant` object. Per immutable objects, a new object is instantiated rather than altering ("mutating") the original.
    .minus(                       // Go backwards on the timeline.
        Duration.ofMinutes( 4 )   // Amount of time to go backwards.
    )                             // Returns another `Instant` object. 
    .toString()                   // Generate text in standard ISO 8601 format, with `Z` on the end meaning an offset of zero hours-minutes-seconds from the UTC temporal prime meridian.                  

Zulu time

The Z at the end represents vital information: the date-time represents a moment as seen with an offset from UTC of zero hours-minutes-seconds. This letter is defined as part of the standard formats in ISO 8601. The letter is pronounced “Zulu” per aviation/military tradition.

If you do not care about offset or time zone in your problem domain, then you are using the wrong type.

The types Instant, OffsetDateTime, and ZonedDateTime all represent a moment, a specific point on the timeline. All three involve an offset or time zone.

LocalDateTime

If you want only a date with time-of-day but lacking the context of an offset/zone, then use LocalDateTime. No Z will appear in text representing the value of a LocalDateTime because no offset is involved.

Just be aware that a LocalDateTime object is inherently ambiguous, and does not represent a moment. In other words, calling LocalDateTime.now is almost never the right thing to do. But if you insist:

LocalDateTime ldt = LocalDateTime.now( ZoneOffset.UTC ) ;

Upvotes: 5

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79580

There can be two ways:

  1. Preferred way: Use DateTimeFormatter
  2. Use OffsetDateTime#toLocalDateTime: The problem with this approach is that the output string is automatically truncated to minutes if the seconds part is zero.

Demo:

import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtfWithoutSecFraction = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss");
        DateTimeFormatter dtfWithSecFraction = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSSSS");
        OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);

        OffsetDateTime eventDateTime = now.minusMinutes(4);

        System.out.println("====Event date Time before truncate===");
        System.out.println(eventDateTime);
        System.out.println(eventDateTime.toLocalDateTime());
        System.out.println(dtfWithSecFraction.format(eventDateTime));

        System.out.println("====Event date Time after truncate===");
        System.out.println(eventDateTime.truncatedTo(ChronoUnit.SECONDS));
        System.out.println(eventDateTime.truncatedTo(ChronoUnit.SECONDS).toLocalDateTime());
        System.out.println(dtfWithoutSecFraction.format(eventDateTime.truncatedTo(ChronoUnit.SECONDS)));
    }
}

Output:

====Event date Time before truncate===
2021-03-09T21:17:17.589016Z
2021-03-09T21:17:17.589016
2021-03-09T21:17:17.589016
====Event date Time after truncate===
2021-03-09T21:17:17Z
2021-03-09T21:17:17
2021-03-09T21:17:17

Note that Z stands for Zulu which specifies date-time in UTC (i.e. a timezone offset of +00:00 hours).

The following table gives you an overview of java.time types:

enter image description here

As you can see, OffsetDateTime, ZonedDateTime etc. carry timezone information and you can get just the date-time part using the techniques mentioned in the solution above.

Learn more about the modern date-time API from Trail: Date Time.

Upvotes: 2

f1sh
f1sh

Reputation: 11942

The Z is the timezone information. You can convert the OffsetDateTime instance to a LocalDateTime like this:

eventDateTime.truncatedTo(ChronoUnit.SECONDS).toLocalDateTime()

Upvotes: 3

Related Questions