mangstadt / biweekly

biweekly is an iCalendar library written in Java.
BSD 2-Clause "Simplified" License
323 stars 44 forks source link

Daylight savings start time data loss #3

Closed mangstadt closed 8 years ago

mangstadt commented 11 years ago

It appears that some data loss can occur when parsing daylight savings start times. For example:

:::java
//daylight savings start time for Paris, France:
//March 31, 2013 at 02:00
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Paris"));
DateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
Date date = df.parse("20130331T020000");
System.out.println(df.format(date));
//expected: "20130331T020000"
//actual: "20130331T030000"
```~~

In the example above, "20130331T020000" should be printed, but "20130331T030000" is printed instead.

It looks like the data loss occurs when the default timezone of the local computer is the same as the timezone being parsed.

iCalendar example:

```~~
:::text
BEGIN:VCALENDAR
BEGIN:VTIMEZONE
TZID:Europe/Paris
BEGIN:DAYLIGHT
DTSTART:20130331T020000
...
END:DAYLIGHT
END:VTIMEZONE
END:VCALENDAR
```~~

If the local computer's timezone is "Europe/Paris", then it will appear as if the `DTSTART` property in the example above is set to "20130331T030000".  However, its true value is "20130331T020000".

Discussion: https://sourceforge.net/p/biweekly/discussion/help-and-support/thread/cb55fc2a/

**Workaround:**

Use the attached marshaller and property classes to get the raw string value of all DTSTART properties:

```~~
:::java
String str = 
"BEGIN:VCALENDAR\r\n" +
"BEGIN:VTIMEZONE\r\n" +
"BEGIN:DAYLIGHT\r\n" +
"DTSTART:20130331T020000\r\n" +
"END:DAYLIGHT\r\n" +
"END:VTIMEZONE\r\n" +
"END:VCALENDAR\r\n";

ICalendar ical = Biweekly.parse(str).register(new DateStartRawMarshaller()).first();
DateStartRaw prop = ical.getTimezones().get(0).getDaylightSavingsTime().get(0).getProperty(DateStartRaw.class);
System.out.println(prop.getValueRaw());
```~~

Reported by: mangstadt

Original Ticket: [biweekly/tickets/3](https://sourceforge.net/p/biweekly/tickets/3)
mangstadt commented 11 years ago

Diff:


--- old
+++ new
@@ -34,3 +34,23 @@
 If the local computer's timezone is "Europe/Paris", then it will appear as if the `DTSTART` property in the example above is set to "20130331T030000".  However, its true value is "20130331T020000".

 Discussion: https://sourceforge.net/p/biweekly/discussion/help-and-support/thread/cb55fc2a/
+
+**Workaround:**
+
+Use the attached marshaller and property classes to get the raw string value of all DTSTART properties:
+
+~~~~~~
+:::java
+String str = 
+"BEGIN:VCALENDAR\r\n" +
+"BEGIN:VTIMEZONE\r\n" +
+"BEGIN:DAYLIGHT\r\n" +
+"DTSTART:20130331T020000\r\n" +
+"END:DAYLIGHT\r\n" +
+"END:VTIMEZONE\r\n" +
+"END:VCALENDAR\r\n";
+
+ICalendar ical = Biweekly.parse(str).register(new DateStartRawMarshaller()).first();
+DateStartRaw prop = ical.getTimezones().get(0).getDaylightSavingsTime().get(0).getProperty(DateStartRaw.class);
+System.out.println(prop.getValueRaw());
+~~~~~~

Original comment by: mangstadt

mangstadt commented 11 years ago

Original comment by: mangstadt

mangstadt commented 11 years ago

Fixed in r202.

Original comment by: mangstadt