问题
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.
Answer: http://m.uploadedit.com/bltc/1591511729781.txt
回答1:
java.time and ThreeTenABP
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.)
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
- In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
- On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from
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.
Links
- Oracle tutorial: Date Time explaining how to use java.time.
- Java Specification Request (JSR) 310, where
java.time
was first described. - ThreeTen Backport project, the backport of
java.time
to Java 6 and 7 (ThreeTen for JSR-310). - ThreeTenABP, Android edition of ThreeTen Backport
- Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
- Wikipedia article: ISO 8601
回答2:
Updated:
ZoneId zoneId = ZoneId.of("America/Chicago");
LocalDate localDate = LocalDate.parse("2020-06-08");
DateTimeFormatter newPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZone(zoneId);
Instant startOfDay = localDate.atStartOfDay(zoneId).toInstant();
Instant endOfDay = LocalDateTime.of(localDate, LocalTime.MAX).atZone(zoneId).toInstant().truncatedTo(ChronoUnit.MILLIS);
System.out.println(startOfDay);
System.out.println(endOfDay);
With what I have gone through, the fraction 000 will not come in this but yes one can be sure that if there are no fraction of milliseconds then it is 000. I was not able to figure out how to bring this while formatting. In case you find something then please add else, you can do it this by converting startDate to String and then appending the 000 to it.
Results
2020-06-08T05:00:00Z
2020-06-09T04:59:59.999Z
来源:https://stackoverflow.com/questions/62235600/how-to-get-start-time-and-end-time-of-a-day-in-another-timezone-in-android