I've the date in format: YYYY-MM-DD
Output format required is: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
And I want to get the date in ISO format as Start time of the day(starts from 12:00AM) and end time of the day(ends on 11:59PM) in America/Chicago timezone.
For eg. For the date: 2020-06-08 (June 8) the converted final output is like:
Start time of the day as Date: 2020-06-08T05:00:00.000Z
End time of the day as Date: 2020-06-09T04:59:59.999Z
Please help me here if anybody has any clue for the same.
I suggest using java.time, the modern Java date and time API, for such date and time math.
ZoneId zone = ZoneId.of("America/Chicago");
String dateString = "2020-06-08";
LocalDate date = LocalDate.parse(dateString);
Instant startOfDay = date.atStartOfDay(zone).toInstant();
Instant endOfDay = date.plusDays(1).atStartOfDay(zone).toInstant();
System.out.println("The day is from " + startOfDay + " (inclusive) to " + endOfDay + " (exclusive)");
Output is:
The day is from 2020-06-08T05:00:00Z (inclusive) to 2020-06-09T05:00:00Z (exclusive)
In order not to exclude the last millisecond of the day we need to count the day as lasting up to the first moment of the next day exclusive. If you do insist on subtracting a millisecond or just a nanosecond, it’s up to you to do so, of course. For example:
Instant endOfDay = date.plusDays(1).atStartOfDay(zone).minusNanos(1).toInstant();
The day is from 2020-06-08T05:00:00Z (inclusive) to 2020-06-09T04:59:59.999999999Z (inclusive and 1 nano more)
Edit: How to get milliseconds printed in the output? You most probably don’t need that. The format you are asking for is ISO 8601 (see the link at the bottom), the international standard. In ISO 8601 the fraction of second is optional, and leaving it out implies 0. So any API requiring ISO 8601 should accept the above. Only if not, the correct solution is to use a formatter. In this case we need to convert the time to UTC explicitly:
ZoneId zone = ZoneId.of("America/Chicago");
DateTimeFormatter formatterWithMillis = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX");
String dateString = "2020-06-08";
LocalDate date = LocalDate.parse(dateString);
OffsetDateTime startOfDay = date.atStartOfDay(zone)
.toOffsetDateTime()
.withOffsetSameInstant(ZoneOffset.UTC);
OffsetDateTime endOfDay = date.plusDays(1)
.atStartOfDay(zone)
.toOffsetDateTime()
.withOffsetSameInstant(ZoneOffset.UTC);
String startString = startOfDay.format(formatterWithMillis);
String endString = endOfDay.format(formatterWithMillis);
System.out.println("The day is from " + startString + " (inclusive) to " + endString + " (exclusive)");
The day is from 2020-06-08T05:00:00.000Z (inclusive) to 2020-06-09T05:00:00.000Z (exclusive)
Or after subtracting a nanosecond from the end time as before:
OffsetDateTime endOfDay = date.plusDays(1)
.atStartOfDay(zone)
.minusNanos(1)
.toOffsetDateTime()
.withOffsetSameInstant(ZoneOffset.UTC);
The day is from 2020-06-08T05:00:00.000Z (inclusive) to 2020-06-09T04:59:59.999Z (inclusive and 1 nano more)
(Since the time is truncated to whole milliseconds the 1 nano more
doesn’t really make sense, but I don’t think that’s the point here.)
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
org.threeten.bp
with subpackages.But don't we have any other option apart from switching to ThreeTenBP Library?
If you insisted, I suppose that a way through using Calendar
, Date
and SimpleDateFormat
could be found. Those classes are poorly designed and long outdated, so with what I know and don’t know I would prefer ThreeTenABP.
java.time
was first described.java.time
to Java 6 and 7 (ThreeTen for JSR-310).