1

I have a code that converts String to Date in Java like this:

String value = "20220307150417";
DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
Date date = formatter.parse(value);
System.out.println(date.toString());

But the output is this: Mon Mar 07 15:04:17 EEST 2022

How can I change this to EET? So I want the response to be Mon Mar 07 15:04:17 EET 2022.

deHaar
  • 17,687
  • 10
  • 38
  • 51
elvis
  • 956
  • 9
  • 33
  • 56
  • 4
    Stop using `SimpleDateFormat`, switch to the more advanced `java.time` packages and its formatter. – Mark Rotteveel May 11 '23 at 09:54
  • Also, read https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/ so you know what a java.util.Date actually consists of. (In particular, see the "Common questions" at the bottom of the post.) – Jon Skeet May 11 '23 at 09:57
  • I need to use Date, or I can use LocalDateTime and then convert to Date. – elvis May 11 '23 at 10:00
  • 4
    Neither a `Date` nor a `LocalDateTime` can have a time zone (or time zone abbreviation). You are asking the impossible. – Ole V.V. May 11 '23 at 10:38
  • If I understood correctly, Libya (despite lying in Africa) uses Easter European Time all year (no summer time/DST). So `LocalDateTime.parse(value, DateTimeFormatter.ofPattern("uuuuMMddHHmmss", Locale.ROOT)) .atZone(ZoneId.of("Africa/Tripoli")) .format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG))` depending on locale yields `7 March 2022 at 15:04:17 EET`. Not sure if it’s what you need and want, though. – Ole V.V. May 11 '23 at 10:48

2 Answers2

3

You can parse your String to a LocalDateTime (only date and time of day, NO zone and NO offset from UTC / GMT).
If you apply a specific zone afterwards, you can build a ZonedDateTime, which can be formatted as desired.

A ZonedDateTime can be converted to an Instant, and that is an option for legacy compatibility, because there are Date.from(Instant) and Date.toInstant().

Here's an example with different outputs

public static void main(String[] args) {
    // example input
    String value = "20230607121201";
    // create a formatter for parsing the String
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuuMMddHHmmss");
    // parse the String to a 
    LocalDateTime localDateTime = LocalDateTime.parse(value, dtf);
    // create the desired zone id
    ZoneId zoneId = ZoneId.of("Europe/Kaliningrad");
    // compose the LocalDateTime and the ZoneId
    ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
    // create a formatter with the same format as Date.toString()
    DateTimeFormatter dtfOut = DateTimeFormatter.ofPattern(
                                "EEE MMM dd HH:mm:ss z uuuu",
                                Locale.ENGLISH);
    // get the Instant
    Instant instant = zonedDateTime.toInstant();
    // create a Date from the Instant
    Date date = Date.from(instant);
    // print the different representations
    System.out.println("ZonedDateTime.format(): " + zonedDateTime.format(dtfOut));
    System.out.println("Instant.toEpochMilli(): " + instant.toEpochMilli());
    System.out.println("Date.getTime():         " + date.getTime());
    System.out.println("Date.toString():        " + date);
}

Please note that Date.toString() takes the system locale and time zone into account, obviously not knowing about daylight saving time.

This took my Locale

Output

ZonedDateTime.format(): Wed Jun 07 12:12:01 EET 2023
Instant.toEpochMilli(): 1686132721000
Date.getTime():         1686132721000
Date.toString():        Wed Jun 07 12:12:01 CEST 2023

Please note that both, Instant.toEpochMilli() and Date.getTime(), have the same value of epoch millis!


Why ZoneId.of("Europe/Kaliningrad")?

Because the requirement seems to be to always use EET. That means you have to choose a zone id that

  • is in / uses EET
  • does not apply daylight saving time
deHaar
  • 17,687
  • 10
  • 38
  • 51
  • 1
    Thank you for explanation. I see that it’s working properly, but for some values it shows EEST. For ex if you try with 20230607121201, the response is Wed Jun 07 12:12:01 EEST 2023. What can I do to work for all values? – elvis May 11 '23 at 14:09
  • Hi! You will need a zone id that (1.) uses EET and (2.) does not apply DST, so change the code to using `ZoneId zoneId = ZoneId.of("Europe/Kaliningrad");`. Romania seems to apply DST, but the Russian exclave does not. – deHaar May 11 '23 at 14:18
0

Both SimpleDateFormat and Date classes are outdated (pun intended). That model of representing dates is badly flawed and even before java came up with a replacement there were other libraries that provided better solutions. However, By now you must use java.time package. In your case look up the classes DateTimeFormatter and ZonedDateTime. Read about the package java.time as well.

Also you might find this relevant: I once had a project where I had to parse a string that may fit any possible format to Date without knowing the format. So, I came up with idea that I stored all supported formats in a property file and tried to parse the String with all those formats one by one until success or until all formats failed. Interesting to note that in this case the order of listing formats may be important as well since date like 02-03-2022 may be parsed as March 2d or Feb 3d depending on US or European style. In any case I wrote an article about this idea which may be relevant here: Java 8 java.time package: parsing any string to date

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36