How to set Z as timezone in SimpleDateFormat

前端 未结 2 437
独厮守ぢ
独厮守ぢ 2021-01-29 12:42

Code sample:

SimpleDateFormat dateFormat = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss z\");
System.out.println(dateFormat.getTimeZone());
System.out.println(dat         


        
相关标签:
2条回答
  • 2021-01-29 13:03

    "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.

    0 讨论(0)
  • 2021-01-29 13:20
        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.

    0 讨论(0)
提交回复
热议问题