将日期转换为 UTC 日期时间

问题描述 投票:0回答:3

我有日期 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

java datetime simpledateformat localtime
3个回答
2
投票

我试过 LocalDate 和 SimpleDateFormatter,但他们没有转换成这种方式。

停止使用容易出错的遗留日期时间 API

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

在线演示

Trail: Date Time.

了解更多关于现代日期时间 API

1
投票

长话短说:

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")));

1
投票

跳过
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. 
© www.soinside.com 2019 - 2024. All rights reserved.