我有日期 2023-04-03 并想将其转换为具有范围(一天的开始和结束)的 UTC 时间
2023-04-03T00:00:00 -> 2023-04-02T18:30:00z
2023-04-03T24:00:00 -> 2023-04-03T18:30:00z
输入:2023-04-03
需要这个输出:2023-04-02T06:30:00z, 2023-04-03T18:30:00z
我试过 LocalDate 和 SimpleDateFormatter,但他们没有转换成这种方式。
LocalDateTime ldt = LocalDate.parse("2023-04-03").atStartOfDay();
ZonedDateTime zdt = ldt.atZone(ZoneId.of("UTC"));
Instant instant = zdt.toInstant();
System.out.println(":inst: " + instant.toString());
以上代码的输出:
您好:2016-06-12T00:00
:inst: 2016-06-12T00:00:00Z
我试过 LocalDate 和 SimpleDateFormatter,但他们没有转换成这种方式。
java.util
日期时间 API 及其相应的解析/格式化类型,SimpleDateFormat
已过时且容易出错。 2014 年 3 月,现代日期时间 API 作为 Java 8 标准库 的一部分发布,它取代了遗留的日期时间 API,从那时起强烈建议切换到 java.time
,现代日期-时间 API.
您想要的输出(一天的开始和结束)是UTC,因此您需要将日期时间从您的时区转换为UTC。一旦你在你的时区有一天的开始和结束,你可以使用
ZonedDateTime#withZoneSameInstant
将它们转换为UTC。
演示:
class Main {
public static void main(String[] args) {
ZoneId zoneIndia = ZoneId.of("Asia/Kolkata");
LocalDate date = LocalDate.parse("2023-04-03");
System.out.println(date.atStartOfDay(zoneIndia)
.withZoneSameInstant(ZoneOffset.UTC));
System.out.println(date.atStartOfDay(zoneIndia).with(LocalTime.MAX)
.withZoneSameInstant(ZoneOffset.UTC));
// Or get the exlusive upper range (half-open interval for the day)
System.out.println(date.plusDays(1).atStartOfDay(zoneIndia)
.withZoneSameInstant(ZoneOffset.UTC));
}
}
输出:
2023-04-02T18:30Z
2023-04-03T18:29:59.999999999Z
2023-04-03T18:30Z
了解更多关于现代日期时间 API
长话短说:
LocalDate localDate = LocalDate.parse("2023-04-03");
ZonedDateTime startOfDay = localDate.atStartOfDay().atZone(ZoneOffset.systemDefault());
ZonedDateTime endOfDay = localDate.plusDays(1).atStartOfDay().atZone(ZoneOffset.systemDefault());
System.out.println(startOfDay.toInstant() + ", " + endOfDay.toInstant());
解释:
有了这条线
ZonedDateTime zdt = ldt.atZone(ZoneId.of("UTC"));
您配置在 Zone UTC 的 LocalDateTime 中创建的时间。
我假设你(或你的系统)不在UTC时间所以你需要在你的
ZonedDateTime
定义ZoneId
像这样:
ZonedDateTime startOfDay = localDate.atStartOfDay().atZone(ZoneOffset.systemDefault());
如果你想定义你的
ZoneID
不是从你的系统,你可以做这样的事情(例如 IST):
ZonedDateTime startOfDay = localDate.atStartOfDay().atZone(ZoneId.of(ZoneId.SHORT_IDS.get("IST")));
LocaDateTime
无需涉及
LocalDateTime
。该类不能代表时间轴上的一个点。它在这里的用法只会让人感到困惑。
LocalDate // Represent a date-only value. No time of day. No time zone or offset.
.parse( "2023-04-03" ) // Parse text in standard ISO 8601 format. Returns a `LocalDate` object.
.atStartOfDay( // Let java.time determine the first moment of the day. While the day always starts at 00:00 in UTC, that is not always the case in some time zones on some dates.
ZoneOffset.UTC // A constant, representing an offset of zero hours-minutes-seconds.
) // Returns a `ZonedDateTime`.
.toInstant() // Adjusts to an offset from UTC of zero hours-minutes by converting to `Instant`.
.toString() // Generate text in standard ISO 8601 format.