mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
ALF-11562 Support for building Java TZ objects from iCal timezones that use DST, with tests
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@32749 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -787,7 +787,7 @@ public class CalendarHelpersTest
|
|||||||
* Checks we correctly build the Timezone for somewhere
|
* Checks we correctly build the Timezone for somewhere
|
||||||
* that doesn't have DST (eg Brisbane)
|
* that doesn't have DST (eg Brisbane)
|
||||||
*/
|
*/
|
||||||
@Test public void simpleTimezoneNoDST()
|
@Test public void simpleTimeZoneNoDST()
|
||||||
{
|
{
|
||||||
SimpleTimeZone tz = CalendarTimezoneHelper.buildTimeZone(ICAL_TZ_BRISBANE);
|
SimpleTimeZone tz = CalendarTimezoneHelper.buildTimeZone(ICAL_TZ_BRISBANE);
|
||||||
|
|
||||||
@@ -803,6 +803,95 @@ public class CalendarHelpersTest
|
|||||||
assertEquals(10*60*60*1000, tz.getOffset(date(2011,11,1).getTime()));
|
assertEquals(10*60*60*1000, tz.getOffset(date(2011,11,1).getTime()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks we correctly build the Timezone for somewhere
|
||||||
|
* in the northern hemisphere with DST (eg London)
|
||||||
|
*/
|
||||||
|
@Test public void simpleTimeZoneNorthern()
|
||||||
|
{
|
||||||
|
SimpleTimeZone tz = CalendarTimezoneHelper.buildTimeZone(ICAL_TZ_LONDON);
|
||||||
|
|
||||||
|
assertNotNull(tz);
|
||||||
|
assertEquals("Europe/London", tz.getID());
|
||||||
|
|
||||||
|
// Does do DST
|
||||||
|
assertEquals(true, tz.useDaylightTime());
|
||||||
|
|
||||||
|
// In 2003, DST was 30th March - 26th October
|
||||||
|
assertEquals(0*60*60*1000, tz.getOffset(date(2003,3,1).getTime()));
|
||||||
|
assertEquals(1*60*60*1000, tz.getOffset(date(2003,3,31).getTime()));
|
||||||
|
assertEquals(1*60*60*1000, tz.getOffset(date(2003,9,1).getTime()));
|
||||||
|
assertEquals(1*60*60*1000, tz.getOffset(date(2003,10,25).getTime()));
|
||||||
|
assertEquals(0*60*60*1000, tz.getOffset(date(2003,11,1).getTime()));
|
||||||
|
|
||||||
|
// In 2007, DST was 25th March - 28th October
|
||||||
|
assertEquals(0*60*60*1000, tz.getOffset(date(2007,3,1).getTime()));
|
||||||
|
assertEquals(1*60*60*1000, tz.getOffset(date(2007,3,26).getTime()));
|
||||||
|
assertEquals(1*60*60*1000, tz.getOffset(date(2007,3,31).getTime()));
|
||||||
|
assertEquals(1*60*60*1000, tz.getOffset(date(2007,9,1).getTime()));
|
||||||
|
assertEquals(1*60*60*1000, tz.getOffset(date(2007,10,28).getTime()));
|
||||||
|
assertEquals(0*60*60*1000, tz.getOffset(date(2007,10,29).getTime()));
|
||||||
|
assertEquals(0*60*60*1000, tz.getOffset(date(2007,11,1).getTime()));
|
||||||
|
|
||||||
|
// In 2011, DST was 27th March - 30th October
|
||||||
|
assertEquals(0*60*60*1000, tz.getOffset(date(2011,3,1).getTime()));
|
||||||
|
assertEquals(1*60*60*1000, tz.getOffset(date(2011,3,31).getTime()));
|
||||||
|
assertEquals(1*60*60*1000, tz.getOffset(date(2011,9,1).getTime()));
|
||||||
|
assertEquals(1*60*60*1000, tz.getOffset(date(2011,10,25).getTime()));
|
||||||
|
assertEquals(0*60*60*1000, tz.getOffset(date(2011,11,1).getTime()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks we correctly build the Timezone for somewhere
|
||||||
|
* in the southern hemisphere with DST (eg Sydney)
|
||||||
|
* Note - Sydney is GMT+11 in December, GMT+10 in June
|
||||||
|
*/
|
||||||
|
@Test public void simpleTimeZoneSouthern()
|
||||||
|
{
|
||||||
|
SimpleTimeZone tz = CalendarTimezoneHelper.buildTimeZone(ICAL_TZ_SYDNEY);
|
||||||
|
|
||||||
|
assertNotNull(tz);
|
||||||
|
assertEquals("Canberra, Melbourne, Sydney", tz.getID());
|
||||||
|
|
||||||
|
// Does do DST
|
||||||
|
assertEquals(true, tz.useDaylightTime());
|
||||||
|
|
||||||
|
// Note - things changed in 2008!
|
||||||
|
// In 2002-2003, DST was 27th October 2002 - 30th March 2003
|
||||||
|
// In 2005-2006, DST was 30th October 2005 - 2nd April 2006
|
||||||
|
// In 2007-2008, DST was 28th October 2007 - 6th April 2008
|
||||||
|
|
||||||
|
// In 2008-2009, DST was 5th October 2008 - 5th April 2009
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2008,6,1).getTime()));
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2008,10,1).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2008,10,6).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2008,12,1).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2009,1,5).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2009,4,4).getTime()));
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2009,4,6).getTime()));
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2009,5,1).getTime()));
|
||||||
|
|
||||||
|
// In 2009-2010, DST was 4th October 2009 - 4th April 2010
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2009,6,1).getTime()));
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2009,10,1).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2009,10,6).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2009,12,1).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2010,1,5).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2010,4,3).getTime()));
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2010,4,5).getTime()));
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2010,5,1).getTime()));
|
||||||
|
|
||||||
|
// In 2010-2011, DST was 3rd Oct 2010 - 3rd April 2011
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2010,6,1).getTime()));
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2010,10,1).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2010,10,6).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2010,12,1).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2011,1,5).getTime()));
|
||||||
|
assertEquals(11*60*60*1000, tz.getOffset(date(2011,4,2).getTime()));
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2011,4,4).getTime()));
|
||||||
|
assertEquals(10*60*60*1000, tz.getOffset(date(2011,5,1).getTime()));
|
||||||
|
}
|
||||||
|
|
||||||
private static class RecurrenceHelper extends CalendarRecurrenceHelper
|
private static class RecurrenceHelper extends CalendarRecurrenceHelper
|
||||||
{
|
{
|
||||||
protected static void buildDailyRecurrences(Calendar currentDate, List<Date> dates,
|
protected static void buildDailyRecurrences(Calendar currentDate, List<Date> dates,
|
||||||
|
@@ -113,7 +113,8 @@ public class CalendarTimezoneHelper
|
|||||||
{
|
{
|
||||||
tzID = "(unknown)";
|
tzID = "(unknown)";
|
||||||
}
|
}
|
||||||
tzID.replaceAll("\\\\", "");
|
// De-escape commans
|
||||||
|
tzID = tzID.replace("\\,", ",");
|
||||||
|
|
||||||
// Does it have daylight savings?
|
// Does it have daylight savings?
|
||||||
if (tzDaylight.isEmpty())
|
if (tzDaylight.isEmpty())
|
||||||
@@ -123,8 +124,22 @@ public class CalendarTimezoneHelper
|
|||||||
return new SimpleTimeZone(offset, tzID);
|
return new SimpleTimeZone(offset, tzID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// Get the offsets
|
||||||
return null;
|
int stdOffset = getOffset(tzDaylight.get("TZOFFSETFROM"));
|
||||||
|
int dstOffset = getOffset(tzDaylight.get("TZOFFSETTO"));
|
||||||
|
|
||||||
|
// Turn the rules into SimpleTimeZone ones
|
||||||
|
int[] stdRules = getRuleForSimpleTimeZone(tzStandard.get("RRULE"));
|
||||||
|
int[] dstRules = getRuleForSimpleTimeZone(tzDaylight.get("RRULE"));
|
||||||
|
|
||||||
|
// Build it up
|
||||||
|
return new SimpleTimeZone(
|
||||||
|
stdOffset, tzID,
|
||||||
|
dstRules[0], dstRules[1], dstRules[2], // When DST starts
|
||||||
|
1*60*60*1000, // TODO Pull out the exact change time from DTSTART
|
||||||
|
stdRules[0], stdRules[1], stdRules[2], // When DST ends
|
||||||
|
2*60*60*1000 // TODO Pull out the exact change time from DTSTART
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -156,6 +171,62 @@ public class CalendarTimezoneHelper
|
|||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn an iCal repeating rule like
|
||||||
|
* "FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10" into a SimpleTimeZone rule
|
||||||
|
* like Month=March, StartDay=0, StartDayOfWeek=-Sunday
|
||||||
|
* See the JavaDocs of {@link SimpleTimeZone} for how to express
|
||||||
|
* the different requirements in the required int formats
|
||||||
|
*/
|
||||||
|
private static int[] getRuleForSimpleTimeZone(String rule)
|
||||||
|
{
|
||||||
|
// Turn the rule into chunks
|
||||||
|
Map<String,String> params = new HashMap<String, String>();
|
||||||
|
for (String p : rule.split(";"))
|
||||||
|
{
|
||||||
|
int splitAt = p.indexOf('=');
|
||||||
|
if (splitAt == -1)
|
||||||
|
{
|
||||||
|
logger.info("Skipping invalid param " + p + " in recurrence rule " + rule);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
params.put(p.substring(0,splitAt), p.substring(splitAt+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Java months are 1 less than normal
|
||||||
|
int month = Integer.parseInt(params.get("BYMONTH")) - 1;
|
||||||
|
|
||||||
|
// Should end with a day of the week
|
||||||
|
String byDay = params.get("BYDAY");
|
||||||
|
String dow = byDay.substring(byDay.length()-2);
|
||||||
|
int dayOfWeek = CalendarRecurrenceHelper.d2cd.get(dow);
|
||||||
|
|
||||||
|
// Where in the month does it come?
|
||||||
|
int dayOfMonth = 0;
|
||||||
|
if (byDay.startsWith("-1"))
|
||||||
|
{
|
||||||
|
// Last in month
|
||||||
|
dayOfMonth = -1;
|
||||||
|
}
|
||||||
|
else if (byDay.startsWith("1"))
|
||||||
|
{
|
||||||
|
// First in month
|
||||||
|
dayOfMonth = 1;
|
||||||
|
dayOfWeek = 0 - dayOfWeek;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Nth day in month
|
||||||
|
dayOfMonth = 1 + (Integer.parseInt(byDay.substring(0,1)) - 1)*7;
|
||||||
|
dayOfWeek = 0 - dayOfWeek;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All done
|
||||||
|
return new int[] {month, dayOfMonth, dayOfWeek};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns an iCal event into event + timezone parameters.
|
* Turns an iCal event into event + timezone parameters.
|
||||||
* This is very closely tied to the SPP / VTI implementation,
|
* This is very closely tied to the SPP / VTI implementation,
|
||||||
|
Reference in New Issue
Block a user