Reputation: 844
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
Reputation: 340098
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.
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
Reputation: 79580
There can be two ways:
DateTimeFormatter
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:
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
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