-1

I have below ZonedDateTime object:

ZonedDateTime z1 = ZonedDateTime.parse("2021-08-06T19:01:32.632+05:30[Asia/Calcutta]");

Need to return another ZonedDateTime object with value: 06-Aug-2021 19:01:32 IST

I can format it like below:

DateTimeFormatter df = DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm:ss zz");
 String s = z1.withZoneSameInstant(ZonedDateTime.now().getZone()).format(df);

but I need to return ZonedDateTime not String. How do I now convert it back to ZonedDateTime. If I parse again timezone shifts or time value is changed.

nanosoft
  • 2,913
  • 4
  • 41
  • 61
  • 1
    Could you clarify what you're actually trying to do? Ignore the string representation: you've got one `ZonedDateTime` value, and you want another one... but what should the difference between the two be? Why are you formatting at all? It's really unclear to me at the moment. – Jon Skeet Aug 09 '21 at 15:45
  • Isn't `"Asia/Kolkata"` resp. `"Asia/Calcutta"` the time zone considered `"IST"`? – deHaar Aug 09 '21 at 15:52
  • @JonSkeet I have one ZonedDateTime obj with value "2021-08-06T19:01:32.632+05:30[Asia/Calcutta]" and I need to write a method to convert it to another ZonedDateTime with new formatting 06-Aug-2021 19:01:32 IST so that the consuming method can print it this new ZonedDateTime object as it is. – nanosoft Aug 09 '21 at 15:56
  • Could you please explain which *IST* you mean? Is it *Indian Standard Time* or something else? Trying to resolve *IST* via `ZoneId.of("IST", ZoneId.SHORT_IDS)` gets you exactly the zone you want to convert **from**! – deHaar Aug 09 '21 at 15:56
  • @deHaar yes same IST - Indian Standard Time – nanosoft Aug 09 '21 at 15:58
  • Does this answer your question? [String to ZonedDateTime is changing format](https://stackoverflow.com/questions/50120213/string-to-zoneddatetime-is-changing-format) – Ole V.V. Aug 09 '21 at 17:05
  • 2
    @deHaar Not *the* time zone as in the only one. Irish Summer Time and Israel Standard Time are also abbreviated IST, and there are still more. – Ole V.V. Aug 09 '21 at 17:08
  • 3
    "I need to write a method to convert it to another ZonedDateTime with new formatting" - a ZonedDateTime doesn't have a format. What you're asking is a bit like saying "I've got an integer with a value of 16, and I want to convert it to a hex integer". You need to differentiate between the inherent value you're working with, and a formatted representation. – Jon Skeet Aug 09 '21 at 17:58

2 Answers2

4

ZonedDateTime holds no format, no text

but I need to return ZonedDateTime not String.

Short answer: It is not possible.

Explanation:

The standard Date-Time classes do not have any attribute to hold the formatting information. Even if some library or custom class promises to do so, it is breaking the Single Responsibility Principle. A Date-Time object is supposed to store the information about Date, Time, Timezone etc., not about the formatting. The only way to represent a Date-Time object in the desired format is by formatting it into a String using a Date-Time parsing/formatting type:

  • For the modern Date-Time API: java.time.format.DateTimeFormatter
  • For the legacy Date-Time API: java.text.SimpleDateFormat

The 3-letter abbreviation for the timezone ID:

The problem with the 3-letter abbreviation e.g. IST is that it can specify many timezones; therefore, you need to change it to the desired timezone ID as per the naming convention, Region/City. Given below is an excerpt from the documentation:

Three-letter time zone IDs

For compatibility with JDK 1.1.x, some other three-letter time zone IDs (such as "PST", "CTT", "AST") are also supported. However, their use is deprecated because the same abbreviation is often used for multiple time zones (for example, "CST" could be U.S. "Central Standard Time" and "China Standard Time"), and the Java platform can then only recognize one of them.

Demo:

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime z1 = ZonedDateTime.parse("2021-08-06T19:01:32.632+05:30[Asia/Calcutta]");
        DateTimeFormatter df = DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
        String s = z1.format(df);
        System.out.println(s);

        // Getting the original ZonedDateTime from the string
        s = s.replace("IST", "Asia/Calcutta");
        ZonedDateTime z2 = ZonedDateTime.parse(s, df);
        System.out.println(z2);
    }
}

Output:

06-Aug-2021 19:01:32 IST
2021-08-06T19:01:32+05:30[Asia/Calcutta]

ONLINE DEMO

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
2

Why not to just use overloaded version parse(CharSequence t, DateTimeFormatter f), as:

ZonedDateTime z1 = ZonedDateTime
        .parse("2021-08-06T19:01:32.632+05:30[Asia/Calcutta]", DateTimeFormatter.ISO_ZONED_DATE_TIME);

Or, if you instist you want to have two distinct objects:

String zdt = "2021-08-06T19:01:32.632+05:30[Asia/Calcutta]";

ZonedDateTime z1 = ZonedDateTime.parse(zdt);
ZonedDateTime z2 = ZonedDateTime.parse(zdt, DateTimeFormatter.ISO_ZONED_DATE_TIME);
Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
  • Results into error: Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-08-06T19:01:32.632+05:30[Asia/Calcutta]' could not be parsed at index 2 – nanosoft Aug 09 '21 at 16:06
  • @nanosoft that's because I've just copied your pattern.. which appears to be invalid. You have a year, in the object.. and you have a `dd` in the formatter. Could you specify how **exactly** you wish to format the object? – Giorgi Tsiklauri Aug 09 '21 at 16:11
  • I have one ZonedDateTime obj with value "2021-08-06T19:01:32.632+05:30[Asia/Calcutta]" and I need to write a method to convert it to another ZonedDateTime with new formatting 06-Aug-2021 19:01:32 IST so that the consuming method can print it this new ZonedDateTime object as it is. – nanosoft Aug 09 '21 at 16:17
  • 1
    @nanosoft oh... that completely changes your question and answers Jon's confusion.. update your question appropriately. You want to convert from one format to another. – Giorgi Tsiklauri Aug 09 '21 at 16:20