使用本地 year/month/day 并指定 hours/minutes JAVA 将 UTC 时间转换为本地时间

Convert UTC time to local time while using the local year/month/day and specifying the hours/minutes JAVA

我正在尝试将 09:00 UTC 转换为本地等效时间,如下所示:

    ZoneId localZoneId = ZoneId.of(TimeZone.getDefault().getID());
    DateTimeFormatter formatt = DateTimeFormatter.ofPattern("HH:mm").withZone(localZoneId);
    ZonedDateTime test = ZonedDateTime.of( 2020 , 4 , 25 , 9 , 0 , 0 , 0 , ZoneId.of("UTC"));
        String test2 = formatt.format(test);
        System.out.println(test);
        System.out.println(test2);

输出

2020-04-25T09:00Z[UTC]
02:00

但是,我不想手动输入年月日,而是想从本地计算机获取当前年月日,但仍将 hour/minutes 保留在 09:00。部分代码需要像这样工作

    ZonedDateTime test = ZonedDateTime.of( currentYear, currentMonth , currentDay, 9 , 0 , 0 , 0 , ZoneId.of("UTC"));

正在考虑这样做,但似乎有很多代码:

        ZonedDateTime dateparse= ZonedDateTime.now();
        ZoneId localZoneId = ZoneId.of(TimeZone.getDefault().getID());
        DateTimeFormatter formatFullLocal = DateTimeFormatter.ofPattern("HH:mm").withZone(localZoneId);


        DateTimeFormatter year = DateTimeFormatter.ofPattern("yy");
        String localMachineYearString= year.format(dateparse);
        int localMachineYearInt = Integer.parseInt(localMachineYearString);


        DateTimeFormatter month= DateTimeFormatter.ofPattern("M");
        String localMachineMonthString= month.format(dateparse);
        int localMachineMonthInt= Integer.parseInt(localMachineMonthString);


        DateTimeFormatter day= DateTimeFormatter.ofPattern("dd");
        String localMachineDayString= day.format(dateparse);
        int localMachineDayInt= Integer.parseInt(localMachineDayString);


        ZonedDateTime test =ZonedDateTime
                .of(localMachineYearInt, localMachineMonthInt , localMachineDayInt , 9 , 0 , 0 , 0 , ZoneId.of("UTC"));

谢谢!

tl;博士

ZonedDateTime.now().with( LocalTime.of( 9 , 0 ) )

LocalTime object, when passed to the with method, acts as a TemporalAdjuster, to move to a different date-time value. That value is delivered in a fresh new object rather than altering the original, as immutable objects

上面的代码行隐式依赖于 JVM 当前的默认时区。最好明确指定。

详情

顺便说一下,不要将遗留日期时间 类 与 java.time 类 混用。完全避免遗留 类。所以这个:

ZoneId localZoneId = ZoneId.of(TimeZone.getDefault().getID());

……应该是:

ZoneId localZoneId = ZoneId.systemDefault() ;

此外,java.time中的“本地”表示“未分区”,或者 zone/offset 未知或未指定。所以你的变量名 localZoneId 很混乱。应该是这样的:

ZoneId zoneId = ZoneId.systemDefault() ;

你说:

I want to grab the current year, month, day from the local machine

确定当前日期需要时区。对于任何给定时刻,全球各地的日期因时区而异。

ZoneId z = ZoneId.systemDefault() ;
LocalDate today = LocalDate.now( z ) ;

你说:

but still keep the hour/minutes at 09:00

A ZonedDateTime 在时区上下文中表示日期和时间。您可以在工厂方法中指定这三个部分中的每一个 ZonedDateTime.of.

LocalTime lt = LocalTime.of( 9 , 0 ) ;
ZonedDateTime zdt = ZonedDateTime.of( today , lt , z ) ;  // Pass date, time, zone.