Search code examples
javatimezoneconverterszoneddatetimestring-to-datetime

Create an Instance of ZonedDateTime from String with same time as String [Java]


I want to create an instance of ZonedDateTime from String. I want to make "2021-03-18 8:00:00" turn into "2021-03-18 8:00:00 EST". I don't want an unexpected variable to interfere by converting 8:00:00 to a different time from what is shown. i.e from 8:00:00 to 17:00:00.

The code that I used to try to convert it was:

    SimpleDateFormat estForm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    estForm.setTimeZone(TimeZone.getTimeZone("EST"));
    String start = "2021-03-18 08:00:00";

    Date estDT = estForm.parse(start);

    final ZoneId zoneEST = ZoneId.of("US/Eastern");

    ZonedDateTime zoneEst = ZonedDateTime.ofInstant(estDT.toInstant(), zoneEST);

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    System.out.println(zoneEST);
    System.out.println(zoneEst);

Here is the last output I got from this:

US/Eastern
2021-03-18T09:00-04:00[US/Eastern]

Solution

  • Well, you could simply do:

    "2021-03-18 08:00:00" + " EST"
    

    If you want to treat the input as a logical date-time value, parse as a LocalDateTime. This type is appropriate because your input lacks indicator of time zone or offset-from-UTC.

    Then call atZone to place that date-with-time into the context of a time zone. EST is not a time zone. Such 2-4 pseudo-zones represent only a general idea of whether Daylight Saving Time (DST) is effect, and even that is just a general idea for an area, not precise. Also not standardized, and not even unique.

    I will guess that you want New York time.

    LocalDateTime
    .parse( 
        "2021-03-18 08:00:00".replace( " " , "T" ) 
    )                                                // Returns a `LocalDateTime` object.
    .atZone(
        ZoneId.of( "America/New_York" ) 
    )                                                // Returns a `ZonedDateTime` object.
    

    Generally best to let DateTimeFormatter automatically localize while generating text, via the `ofLocalized… methods. But if you insist on your specific method, define a formatting pattern.

    DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss z" ) ;
    String output = zdt.format( f ) ;
    

    Pull that code together.

            ZonedDateTime zdt = 
                LocalDateTime
                .parse( "2021-03-18 08:00:00".replace( " " , "T" ) )
                .atZone(
                    ZoneId.of( "America/New_York" ) 
                )
            ;
    
            DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss z" ) ;
            String output = zdt.format( f ) ;
    

    See this code run live at IdeOne.com.

    2021-03-18 08:00:00 EDT

    As we can see in that output, your desired EST is incorrect, as New York time switched off DST to standard time a few days before this date-time.