1

I would want to take the time and time zone from user and create an entry. Used below calendar API to do this, it is working for few time zone and not working few time zones

calendar.setTime(eventFormEntryBean.getStartDate());
TimeZone timeZone = TimeZone.getTimeZone("Europe/Amsterdam");
calendar.setTimeZone(timeZone);

Working timezone(at the end +xx:xx)

  • Pacific/Palau 2019-11-27T20:51:09.000+09:00
  • IST - 2019-11-20T22:00:00.000+05:30
  • Europe/Amsterdam - 2019-11-28T12:49:24.000+01:00
  • America/Los_Angeles - 2019-11-20T21:32:49.000-08:00

Not working time zone:-

  • Africa/Dakar - 2019-11-21T05:30:45.000Z
  • London(Europe/London) - 2019-11-21T12:08:42.000Z

For the above London and Africa/Dakar time zones do not have any indicator to distinguish the time zone, it simply specify “.000Z” at the end. Is there any attribute that we need to set in order to get full time zone? what does that .000z means?

Anderson
  • 1,100
  • 2
  • 13
  • 17
  • 1
    Both of the "offending" time zones have 0 offset from GMT. So that seems to be work as desired. `Z` is basically just `+00:00`. Also, generally speaking there's no 1:1 relation between time zone offset (such as `+09:00`) and a time zone (such as `Pacific/Palau`). Many different time zones can have the same offset and the offset of a given time zone might change during the year (thanks to daylight savings time). – Joachim Sauer Nov 20 '19 at 12:43
  • The `Calendar` and `TimeZone` classes are both poorly designed and long outdated. I recommend that instead of using those you use java.time, the modern Java date and time API. You need `ZoneId` and `ZonedDateTime`. – Ole V.V. Nov 20 '19 at 17:30

2 Answers2

4

If you want to be able to write code that reflects the difference between offsets and time zones, leave java.util and switch to java.time (for Java 8+ and with a support library for Java 6 and 7).

Then you can do things like these:

public static void main(String[] args) {
    /*
     * the base of this example is a date time with an offset of +01:00
     * (which is present in several zones, not just in Europe/Amsterdam!)
     */
    String datetime = "2019-11-28T12:49:24.000+01:00";
    // parse it to an offset-aware object
    OffsetDateTime plusOneHourOffsetDateTime = OffsetDateTime.parse(datetime);
    // print it to be sure ;-)
    System.out.println(plusOneHourOffsetDateTime
            .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
    // convert it to a zone-aware date time object by providing the zone
    ZonedDateTime europeAmsterdamZonedDateTime = plusOneHourOffsetDateTime
            .atZoneSameInstant(ZoneId.of("Europe/Amsterdam"));
    // print it
    System.out.println(europeAmsterdamZonedDateTime
            .format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    // then take the same instant but use a different time zone
    ZonedDateTime utcZonedDateTime = plusOneHourOffsetDateTime
            .atZoneSameInstant(ZoneId.of("UTC"));
    // print that, it adds a Z (indicating an offset of 00:00) and the time zone
    // that was specified
    System.out.println(utcZonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    // take a totally different time zone and do it again
    ZonedDateTime pacificPalauZonedDateTime = plusOneHourOffsetDateTime
            .atZoneSameInstant(ZoneId.of("Pacific/Palau"));
    // print that one, too
    System.out.println(pacificPalauZonedDateTime
            .format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}

which outputs this

2019-11-28T12:49:24+01:00
2019-11-28T12:49:24+01:00[Europe/Amsterdam]
2019-11-28T11:49:24Z[UTC]
2019-11-28T20:49:24+09:00[Pacific/Palau]

EDIT

The reason for the DateTimeParseException mentioned in your comment is the date-time String, because it doesn't have a zone or an offset, which makes it unparseable by the default DateTimeFormatter used in OffsetDateTime.parse(String datetime).

If you have a String with date and time information but without a zone or an offset, you can parse it to a LocalDateTime first and create a ZonedDateTime from that:

public static void main(String[] args) {
    // date time String without zone or offset information
    String dateTimeString = "2019-11-30T19:35:06";
    // create a LocalDateTime from the String
    LocalDateTime ldt = LocalDateTime.parse(dateTimeString);
    // then create a ZonedDateTime from the LocalDateTime adding a zone
    ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault()); // system default here
    // and print it
    System.out.println(zdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}
deHaar
  • 17,687
  • 10
  • 38
  • 51
  • deHaar, I am getting DateTimeParseException. actually I want to format "2019-11-30T19:35:06" can you tell how do we parse this? – Anderson Nov 21 '19 at 14:10
  • Awesome deHaar, Many thanks. Can we pass date object in LocalDateTime class ? – Anderson Nov 21 '19 at 15:10
  • I just created standalone java class to test this behavior. In real time i get date object, i want to pass it to LocalDateTime class. Is there way to set ? – Anderson Nov 21 '19 at 15:14
  • @Anderson Yes, you can... See [this question](https://stackoverflow.com/questions/19431234/converting-between-java-time-localdatetime-and-java-util-date). – deHaar Nov 21 '19 at 15:21
  • Thank you for navigating me to correct place. Yes, converted to LocalDateTime but somehow the time got changed , here is how I called ZonedDateTime Zdate = dateObject.toInstant().atZone(ZoneId.of(“Europe/London”)); // The date I passed is Fri Nov 22 03:00:00 IST 2019 but the output time is 2019-11-21T21:30:00Z Any idea about it? – Anderson Nov 21 '19 at 15:55
  • There's a time zone in the input, it's IST... Try to parse that somehow directly – deHaar Nov 21 '19 at 15:59
  • This date object is coming from different component, we dont have a control to parse. Could you pls tell me Is there any other way to tackle this pls? – Anderson Nov 21 '19 at 16:02
  • @Anderson then simply receive the epoch millis from the `Date` and parse them to a `LocalDateTime`. You already know how to process from there... – deHaar Nov 21 '19 at 16:49
  • @Anderson Parse it like you did in the comment before your last and take UTC as time zone, then print the result and convert it to the zone you need. I think a `java.util.Date` only has a UTC timestamp resp. instant in millis, no zone or offset. – deHaar Nov 21 '19 at 18:33
  • Thank you deHaar for your suggestion. – Anderson Nov 22 '19 at 14:39
3

You misunderstood. Z means exactly the same as +00:00 and is the conventional and recommended way to write it in the ISO 8601 format that you are producing. So for all of your time zones you are getting the correct UTC offset (except possibly IST; that may stand for Irish summer time or Israel standard time, in which case your offset of +05:30 is wrong; don't rely on ambiguous three letter tome zone abbreviations).

The Calendar and TimeZone classes are both poorly designed and long outdated. I recommend that instead of using those you use java.time, the modern Java date and time API. You need ZoneId and ZonedDateTime. See the answer by deHaar.

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