Search code examples
javadatetimeutc

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


I'm trying to convert 09:00 UTC into the local equivalent like this:

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

Output

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

However, instead of manually entering the the year, month and day I want to grab the current year, month, day from the local machine but still keep the hour/minutes at 09:00.this part of the code needs to work like this

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

Was thinking of doing this but it seems like alot of code:

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

Thank You!


Solution

  • tl;dr

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

    The 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.

    The line of code above depends implicitly on the JVM’s current default time zone. Better to specify explicitly.

    Details

    By the way, do not mix legacy date-time classes with java.time classes. Avoid the legacy classes entirely. So this:

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

    …should be:

    ZoneId localZoneId = ZoneId.systemDefault() ;
    

    Also, “local” in java.time means “not zoned”, or the zone/offset is unknown or unspecified. So your variable name localZoneId is confusing. Should be something like this:

    ZoneId zoneId = ZoneId.systemDefault() ;
    

    You said:

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

    Determining the current date requires a time zone. For any given moment, the date varies around the globe by time zone.

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

    You said:

    but still keep the hour/minutes at 09:00

    A ZonedDateTime represents a date and a time-of-day, in the context of a time zone. You can specify each of those three parts in the factory method ZonedDateTime.of.

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