-1

Code sample:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
System.out.println(dateFormat.getTimeZone());
System.out.println(dateFormat.parse(time));
//  dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));

I don't want to use the commented section.

Zone should be set based on IST that I am giving in the input string:

String time ="2018-04-06 16:13:00 IST";

Current machine zone is: America/New_York. How should I get zone changes to IST based on z?

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
String time ="2018-04-06 18:40:00 IST";
dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));

Above is running correctly but I don't want to set zone explicitly. It should be choosen based on IST I am giving in input time string.

connieY
  • 23
  • 4
Ankush Nakaskar
  • 121
  • 1
  • 2
  • 8
  • 2
    I recommend you avoid the `SimpleDateFormat` class. It is not only long outdated, it is also notoriously troublesome. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Apr 06 '18 at 12:11
  • https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html – Jan Larsen Apr 06 '18 at 12:11
  • Can you provide me sample – Ankush Nakaskar Apr 06 '18 at 12:11
  • IST is ambiguous, it may be Irish Summer Time, Israel Standard Time or India Standard Time. It’s recommended to avoid the three and four letter time zone abbreviations exactly for this reason. If you get one of those zones on your own computer, you risk getting a different one the day you run your code on a different computer. Would it be possible for you to get a date-time string without this ambiguity? For example with a UTC offset and/or a time zone in the *region/city* format, such as Asia/Tel_Aviv? – Ole V.V. Apr 06 '18 at 12:16
  • [Trying to parse a datetime in PDT to a ZonedDateTime representation](https://stackoverflow.com/questions/44743139/trying-to-parse-a-datetime-in-pdt-to-a-zoneddatetime-representation). There are probably more good questions and answers out there, just use your search engine. – Ole V.V. Apr 06 '18 at 12:25
  • I checked with that,but not getting exact answer – Ankush Nakaskar Apr 06 '18 at 12:28
  • 3
    @AnkushNakaskar, what does it mean "How should I get Zone changes to IST"? That is not a question I can give an answer to. please read [help/asking](https://stackoverflow.com/help/asking) and make your question into a [mcve]. – M. Prokhorov Apr 06 '18 at 12:36
  • I agree that the last bits are still missing. [The answer by user7605325](https://stackoverflow.com/a/44743594/5772882) shows you how to get a `ZonedDateTime z` from a string containing a three letter time zone abbreviation. Adapt the code to fit the format of your string. And then use `z.getZone()` to get the zone of the parsed `ZonedDateTime`. If you are still missing anything, you will need to explain better. – Ole V.V. Apr 06 '18 at 12:38
  • @OleV.V.If i do getzone,it return me the machine zone.Hence it is not converting to right time.If i set the timeZone specifically to IST then it get correct time.I dont want to set that explicitly ,It should be set to based on Z – Ankush Nakaskar Apr 06 '18 at 13:08
  • @OleV.V.Please check the updated question – Ankush Nakaskar Apr 06 '18 at 13:21
  • Thanks for the edit, it helped. I am still unsure what you mean by "zone changes to IST", though. Could you be more precise or clearer? – Ole V.V. Apr 06 '18 at 15:35

2 Answers2

2

"I don't want to set zone explicitly"

Sorry to disappoint you, but that's not possible with SimpleDateFormat. Timezone abbreviations like IST are ambiguous - as already said in the comments, IST is used in many places (AFAIK, in India, Ireland and Israel).

Some of those abbreviations might work sometimes, in specific cases, but usually in arbitrary and undocumented ways, and you can't really rely on that. Quoting the javadoc:

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.

Due to the ambiguous and non-standard characteristics of timezones abbreviations, the only way to solve it with SimpleDateFormat is to set a specific timezone on it.

"It should be set to based on Z"

I'm not really sure what this means, but anyway...

Z is the UTC designator. But if the input contains a timezone short-name such as IST, well, it means that it's not in UTC, so you can't parse it as if it was in UTC.

If you want to output the date with Z, then you need another formatter set to UTC:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
String time = "2018-04-06 18:40:00 IST";
dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
// parse the input
Date date = dateFormat.parse(time);

// output format, use UTC
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssX");
outputFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(outputFormat.format(date)); // 2018-04-06 13:10:00Z

Perhaps if you specify exactly the output you're getting (with actual values, some examples of outputs) and what's the expected output, we can help you more.

connieY
  • 23
  • 4
1
    DateTimeFormatter formatter 
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss z", Locale.ENGLISH);
    String time ="2018-04-06 16:13:00 IST";
    ZonedDateTime dateTime = ZonedDateTime.parse(time, formatter);
    System.out.println(dateTime.getZone());

On my Java 8 this printed

Asia/Jerusalem

So apparently IST was interpreted as Israel Standard Time. On other computers with other settings you will instead get for instance Europe/Dublin for Irish Summer Time or Asia/Kolkata for India Standard Time. In any case the time zone comes from the abbreviation matching the pattern letter (lowercase) z in the format pattern string, which I suppose was what you meant(?)

If you want to control the choice of time zone in the all too frequent case of ambiguity, you may build your formatter in this way (idea stolen from this answer):

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-dd HH:mm:ss ")
            .appendZoneText(TextStyle.SHORT,
                    Collections.singleton(ZoneId.of("Asia/Kolkata")))
            .toFormatter(Locale.ENGLISH);

Now the output is

Asia/Kolkata

I am using and recommending java.time over the long outdated and notoriously troublesome SimpleDateFormat class.

Link: Oracle tutorial: Date Time explaining how to use java.time.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161