Menu

Dates in UTC ?

2013-10-08
2014-08-06
  • Caruyer Perrine

    Caruyer Perrine - 2013-10-08

    Hello Michael,
    How are you ?
    I'm back for a new question !

    One of the most difficult things according to me in iCal is.... Date & TimeZone !!
    To standardize dates in my code, I would like to convert dates in UTC format, do you know a simple way to do that ?

    For example, when I have this iCal :

    BEGIN:VCALENDAR
    ...
    BEGIN:VTIMEZONE
    TZID:Romance Standard Time
    BEGIN:STANDARD
    DTSTART:16010101T030000
    TZOFFSETFROM:+0200
    TZOFFSETTO:+0100
    RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
    END:STANDARD
    BEGIN:DAYLIGHT
    DTSTART:16010101T020000
    TZOFFSETFROM:+0100
    TZOFFSETTO:+0200
    RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
    END:DAYLIGHT
    END:VTIMEZONE

    BEGIN:VEVENT
    ...
    DTSTART;TZID=Romance Standard Time:20131012T100000
    DTEND;TZID=Romance Standard Time:20131012T103000
    ...
    END:VEVENT
    END:VCALENDAR

    How can I get UTC time ??
    If there's no easy way, why not adding a getter on DateStart object (and other date objects) to get UTC value ?

    Thank you in advance !

     
  • Michael Angstadt

    Hi Caruyer! I'm fine how are you? :)

    In the example you gave, biweekly will assume that the DTSTART and DTEND properties are in your local time (i.e. the JVM's default timezone). This is because biweekly is unable to "parse" the timezone information out of a VTIMEZONE component and apply it to a date-time property value. For example, if you live in New York City, it will think that the value of DTSTART ("20131012T100000") is in New York time, even though the TZID parameter says that it's in "Romance Standard Time".

    However, biweekly does recognize Olson timezone IDs (for example, "TZID=Europe/Paris"). In this case, it will properly parse the date-time value according to that timezone (provided the timezone is recognized by Java). A list of Olson IDs can be found here.


    So, getting back to your question "How can I get UTC time?". Internally, all Java "Date" objects store their timestamp value in UTC time. So, when you want to display the timestamp, it's just a matter of choosing which timezone you want to format it as.

    To print out a date according to UTC time, simply call the "DateFormat.setTimeZone()" method and then print out the date:

    :::java
    VEvent event = ...
    Date start = event.getDateStart().getValue();
    
    TimeZone utc = TimeZone.getTimeZone("UTC");
    DateFormat df = new SimpleDateFormat("...");
    df.setTimeZone(utc);
    System.out.println(df.format(start));
    

    However, remember what I said above. Since biweekly doesn't recognize VTIMEZONE components, it will assume that the date-time value is in your local time, not in "Romance Standard Time".

    Is that at all clear? o_O

     

    Last edit: Michael Angstadt 2013-10-08
  • Caruyer Perrine

    Caruyer Perrine - 2013-10-09

    Hello, I'm fine too, thanks ! :)

    I think I understood, but I'm really embarrassed with this :(
    I really need to convert my date in UTC time, with this timeZone...
    So, I'll have to get the timeZone, then calculate the offset between this date and UTC time...
    But I don't know how to do this, do you have some key for me ??
    I'm sorry if I ask you too much, I have not many time to do this and help is welcome :D

    Thanks a lot for your answer !

    (But I think that in a future version it would be interesting to directly retrieve the date in utc, if possible: D)

     
  • Michael Angstadt

    This code should work for your situation:

    :::java
    
    VEvent event = ...
    DateStart dateStart = event.getDateStart();
    Date start = dateStart.getValue();
    
    if ("Romance Standard Time".equalsIgnoreCase(dateStart.getTimezoneId())){
      //convert from local time to CET time
      //"CET" is the same as "Romance Standard Time"
      start = convertToTimeZone(start, "CET");
    }
    
    //convert to UTC time
    String utc = utcDate(start);
    System.out.println(utc);
    
    public static Date convertToTimeZone(Date date, String timezoneId){
      TimeZone tz = TimeZone.getTimeZone(timezoneId);
      int tzOffset = tz.getOffset(date.getTime());
      int localOffset = TimeZone.getDefault().getOffset(date.getTime());
    
      Calendar c = Calendar.getInstance();
      c.setTime(date);
      c.add(Calendar.MILLISECOND, localOffset - tzOffset);
      return c.getTime();
    }
    
    public static String utcDate(Date date){
      DateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss Z");
      df.setTimeZone(TimeZone.getTimeZone("UTC"));
      return df.format(date);
    }
    

    biweekly currently does not support the VTIMEZONE component, which is why it is complicated. :(

     
  • Caruyer Perrine

    Caruyer Perrine - 2013-10-10

    Hello,
    thanks a lot for paying attention to my question.
    This proposal will be valid for the "Romance Standard Time" case, but I have ton consider that there could be anything else...
    You say biweekly currently does not support the VTIMEZONE, but you don't exclude to add this functionality in the future ?

    Just for information, to convert from a timezone to another, we have yo be careful about daylights ;)

     
  • Michael Angstadt

    It may be possible to add support for VTIMEZONE. I need to look into it.

    If an Olson timezone ID is used (for example, "Europe/Paris"), then Java takes daylight savings time into account automatically. But when you use timezones like "CET", then you probably have to handle daylight savings time yourself.

     
  • Caruyer Perrine

    Caruyer Perrine - 2014-07-28

    Hello,

    I'm back again with timezones .... :(

    I'm always annoyed when I have a TZID that references a VTIMEZONE.
    I would not depend on the timezone of my JVM in this particular case. Why not consider in these cases that the DSTART is UTC?

    Currently, I wrote a method to convert the date from the jvm timezone to utc, but how can I recognize a date that has been parsed in the tz on the jvm?
    You said "However, biweekly Does Recognize Olson timezone", but how can I know in Java if a String is an olson timezone?

    TimeZone.getTimeZone(" .... id ....") returns GMT when its doesn't know an id....

    Do you have some ideas to help me ?

    Thanks in advance :)

     
  • Michael Angstadt

    Hi Perrine. Sorry for the late response, I have been busy at work. >.<

    When you parse a date property with biweekly, it does the following (pseudo code):

    :::text
    if (property.value is in UTC){ //if the date string ends in "Z"
      //parse date string as a UTC date
    } else {
      tzid = property.parameters.get("TZID")
      if (tzid param exists AND tzid.contains("/")){
        timezone = java.util.TimeZone.getTimeZone(tzid);
        if (timezone != GMT){
          //Java recognizes the timezone
          //so, parse date string using "tzid" timezone
        } else {
          //parse date string using default timezone
        }
      } else {
        //parse date string using default timezone
      }
    }
    

    So, in order to tell if biweekly already converted the date to its TZID timezone, do this:

    :::java
    String tzid = property.getParameter("TZID");
    TimeZone gmt = TimeZone.getTimeZone("GMT");
    if (tzid.contains("/") && !TimeZone.getTimeZone(tzid).equals(gmt)){
      //then, biweekly already converted the date value into the TZID timezone
    }
    

    Does that make sense? o.O

     
  • Caruyer Perrine

    Caruyer Perrine - 2014-08-06

    Hello,
    Thanks for your answer and don't be sorry, but I'm sad to learn that you were busy at work because I used to think you were in holidays ;)
    Your pseudo code is clear and I understood how to know if changes have been done on the date, thanks ! ;)
    So, I wrote a method to convert from default jvm timezone to utc timezone, because I consider that my jvm timezone is not representative for users all over the world ^^

     

Anonymous
Anonymous

Add attachments
Cancel