-1

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]
James Z
  • 12,209
  • 10
  • 24
  • 44
  • 1
    If you're using the new Java Time API, don't use the old API too. Get rid of any code using `SimpleDateFormat`. See if that fixes your problem. – Andreas Mar 17 '21 at 01:45
  • 1
    Daylight Savings Time started on 3/14, so a timestamp for 2021-03-18 would be `EDT`, not `EST`. The problem is that you're parsing with a forced `EST` time zone offset, so the resultant date is then converted to `EDT`, and hence changed the time by 1 hour. – Andreas Mar 17 '21 at 01:51

1 Answers1

2

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154