aboutsummaryrefslogtreecommitdiffstats
path: root/libical/src
diff options
context:
space:
mode:
authorDamon Chaplin <damon@ximian.com>2001-10-23 07:40:29 +0800
committerDamon Chaplin <damon@src.gnome.org>2001-10-23 07:40:29 +0800
commit1da29bab5d909484d332cf2777da92def62023a6 (patch)
tree9aa683dc3cf6cbbf712ab76fe46a633d1f581e75 /libical/src
parent4807a4d7e75993aefc6860d2747403a7019c49e7 (diff)
downloadgsoc2013-evolution-1da29bab5d909484d332cf2777da92def62023a6.tar.gz
gsoc2013-evolution-1da29bab5d909484d332cf2777da92def62023a6.tar.zst
gsoc2013-evolution-1da29bab5d909484d332cf2777da92def62023a6.zip
updated all files again, placing current RDATEs first, so Outlook uses
2001-10-22 Damon Chaplin <damon@ximian.com> * zoneinfo/*: updated all files again, placing current RDATEs first, so Outlook uses those. Also fixed a few bugs in vzic which resulted in a few changes. * zoneinfo/Makefile.am (DIRS): added America/North_Dakota. 2001-10-22 Damon Chaplin <damon@ximian.com> * src/libical/icaltimezone.c (icaltimezone_get_utc_offset): (icaltimezone_get_utc_offset_of_utc_time): if we go off the start of the changes array, return the TZOFFSETFROM of the first change. Also changed the maximum year to 2037. * src/libical/icaltime.c (icaltime_day_of_week): (icaltime_start_doy_of_week): (icaltime_week_number): init tm_hour to 12. Sometimes mktime() adjusts the time, if that local time doesn't actually exist, leading to the wrong day being returned. It is unlikely to adjust by 12 hours. (icaltime_as_timet_with_zone): (icaltime_from_timet_with_zone): change it back so it does convert DATE values to/from the timezone. time_t values don't really go well with DATE values, so be very careful when using them. We now assume that the time_t points to the start of the day in the given timezone. (We used to assume it pointed to the start of the day in UTC, but that meant it was actually incorrect wrt the displayed calendar.) * src/libical/icalrecur.c (expand_year_days): for FREQ=YEARLY with no modifiers, we add one day, using the month and day from DTSTART. (next_year): make sure we never go past 2037. * scripts/mkderivedproperties.pl: Updated to allow DTSTART, DTEND, DUE and RECURRENCE-ID to be set with DATE values. I think it now handles all properties which can take DATE values, except RDATE which uses DATE-TIME-PERIOD. svn path=/trunk/; revision=13912
Diffstat (limited to 'libical/src')
-rw-r--r--libical/src/libical/icalrecur.c32
-rw-r--r--libical/src/libical/icaltime.c55
-rw-r--r--libical/src/libical/icaltimezone.c62
-rw-r--r--libical/src/libical/icaltimezone.h3
4 files changed, 103 insertions, 49 deletions
diff --git a/libical/src/libical/icalrecur.c b/libical/src/libical/icalrecur.c
index d998cd0e39..9af9abd8f5 100644
--- a/libical/src/libical/icalrecur.c
+++ b/libical/src/libical/icalrecur.c
@@ -148,6 +148,10 @@
#include "pvl.h"
+/* This is the last year we will go up to, since 32-bit time_t values only
+ go up to the start of 2038. */
+#define MAX_TIME_T_YEAR 2037
+
#define TEMP_MAX 1024
@@ -727,6 +731,11 @@ int has_by_data(struct icalrecur_iterator_impl* impl, enum byrule byrule){
}
+void increment_year(struct icalrecur_iterator_impl* impl, int inc)
+{
+ impl->last.year+=inc;
+}
+
int expand_year_days(struct icalrecur_iterator_impl* impl,short year);
@@ -999,11 +1008,6 @@ void icalrecur_iterator_free(icalrecur_iterator* i)
}
-void increment_year(struct icalrecur_iterator_impl* impl, int inc)
-{
- impl->last.year+=inc;
-}
-
/* Increment month is different that the other incement_* routines --
it figures out the interval for itself, and uses BYMONTH data if
available. */
@@ -1732,6 +1736,16 @@ int expand_year_days(struct icalrecur_iterator_impl* impl,short year)
case 0: {
/* FREQ=YEARLY; */
+
+ short doy;
+
+ t = impl->dtstart;
+ t.year = year;
+ t.is_date = 1;
+
+ doy = icaltime_day_of_year(t);
+
+ impl->days[days_index++] = doy;
break;
}
@@ -2031,6 +2045,12 @@ int next_year(struct icalrecur_iterator_impl* impl)
for (;;) {
increment_year(impl,impl->rule.interval);
+
+ /* Make sure we don't go past the max time_t year, or any calls to
+ mktime() etc. will fail. */
+ if (impl->last.year > MAX_TIME_T_YEAR)
+ return 1;
+
expand_year_days(impl,impl->last.year);
if (impl->days[0] != ICAL_RECURRENCE_ARRAY_MAX)
break;
@@ -2167,7 +2187,7 @@ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr)
}
}
- if(impl->last.year >= 2038 ){
+ if(impl->last.year > MAX_TIME_T_YEAR ){
/* HACK */
return icaltime_null_time();
}
diff --git a/libical/src/libical/icaltime.c b/libical/src/libical/icaltime.c
index 698035537b..3c99dfacf7 100644
--- a/libical/src/libical/icaltime.c
+++ b/libical/src/libical/icaltime.c
@@ -73,6 +73,10 @@ icaltime_from_timet(time_t tm, int is_date)
return tt;
}
+/* Note that DATE values and floating values do not have their own timezones,
+ so you should use the default or current timezone in that case.
+ This assumes that if is_date is set, the time_t points to the start of the
+ day in the given zone, so be very careful about using it. */
struct icaltimetype
icaltime_from_timet_with_zone(time_t tm, int is_date, icaltimezone *zone)
{
@@ -89,24 +93,24 @@ icaltime_from_timet_with_zone(time_t tm, int is_date, icaltimezone *zone)
tt.year = t.tm_year + 1900;
tt.month = t.tm_mon + 1;
tt.day = t.tm_mday;
-
+ tt.hour = t.tm_hour;
+ tt.minute = t.tm_min;
+ tt.second = t.tm_sec;
+ tt.is_date = 0;
tt.is_utc = (zone == utc_zone) ? 1 : 0;
- tt.is_date = is_date;
tt.is_daylight = 0;
tt.zone = NULL;
+ /* Use our timezone functions to convert to the required timezone. */
+ icaltimezone_convert_time (&tt, utc_zone, zone);
+
+ tt.is_date = is_date;
+
+ /* If it is a DATE value, make sure hour, minute & second are 0. */
if (is_date) {
- /* We don't convert DATE values between timezones. */
tt.hour = 0;
tt.minute = 0;
tt.second = 0;
- } else {
- tt.hour = t.tm_hour;
- tt.minute = t.tm_min;
- tt.second = t.tm_sec;
-
- /* Use our timezone functions to convert to the required timezone. */
- icaltimezone_convert_time (&tt, utc_zone, zone);
}
return tt;
@@ -229,7 +233,12 @@ time_t icaltime_as_timet(struct icaltimetype tt)
}
-time_t icaltime_as_timet_with_zone(struct icaltimetype tt, icaltimezone *zone)
+/* Note that DATE values and floating values do not have their own timezones,
+ so you should use the default or current timezone in that case.
+ If is_date is set, the time_t returned points to the start of the day in
+ the given zone. */
+time_t
+icaltime_as_timet_with_zone(struct icaltimetype tt, icaltimezone *zone)
{
icaltimezone *utc_zone;
struct tm stm;
@@ -243,9 +252,11 @@ time_t icaltime_as_timet_with_zone(struct icaltimetype tt, icaltimezone *zone)
return 0;
}
+ /* Clear the is_date flag, so we can convert the time. */
+ tt.is_date = 0;
+
/* Use our timezone functions to convert to UTC. */
- if (!tt.is_date)
- icaltimezone_convert_time (&tt, zone, utc_zone);
+ icaltimezone_convert_time (&tt, zone, utc_zone);
/* Copy the icaltimetype to a struct tm. */
memset (&stm, 0, sizeof (struct tm));
@@ -405,13 +416,25 @@ short icaltime_day_of_week(struct icaltimetype t){
stm.tm_year = t.year - 1900;
stm.tm_mon = t.month - 1;
stm.tm_mday = t.day;
- stm.tm_hour = 0;
+ stm.tm_hour = 12;
stm.tm_min = 0;
stm.tm_sec = 0;
stm.tm_isdst = -1;
mktime (&stm);
+ if (stm.tm_year != t.year - 1900
+ || stm.tm_mon != t.month - 1
+ || stm.tm_mday != t.day)
+ printf ("WARNING: icaltime_day_of_week: mktime() changed our date!!\n");
+
+#if 0
+ printf ("Day of week %i/%i/%i (%i/%i/%i) -> %i (0=Sun 6=Sat)\n",
+ t.day, t.month, t.year,
+ stm.tm_mday, stm.tm_mon + 1, stm.tm_year + 1900,
+ stm.tm_wday);
+#endif
+
return stm.tm_wday + 1;
}
@@ -423,7 +446,7 @@ short icaltime_start_doy_of_week(struct icaltimetype t){
stm.tm_year = t.year - 1900;
stm.tm_mon = t.month - 1;
stm.tm_mday = t.day;
- stm.tm_hour = 0;
+ stm.tm_hour = 12;
stm.tm_min = 0;
stm.tm_sec = 0;
stm.tm_isdst = -1;
@@ -466,7 +489,7 @@ short icaltime_week_number(struct icaltimetype ictt)
stm.tm_year = ictt.year - 1900;
stm.tm_mon = ictt.month - 1;
stm.tm_mday = ictt.day;
- stm.tm_hour = 0;
+ stm.tm_hour = 12;
stm.tm_min = 0;
stm.tm_sec = 0;
stm.tm_isdst = -1;
diff --git a/libical/src/libical/icaltimezone.c b/libical/src/libical/icaltimezone.c
index 17a3b437d7..b36e34eb74 100644
--- a/libical/src/libical/icaltimezone.c
+++ b/libical/src/libical/icaltimezone.c
@@ -53,7 +53,7 @@
/* This is the maximum year we will expand to. time_t values only go up to
somewhere around 2037. */
-#define ICALTIMEZONE_MAX_YEAR 2035
+#define ICALTIMEZONE_MAX_YEAR 2037
struct _icaltimezone {
@@ -833,15 +833,17 @@ icaltimezone_get_utc_offset (icaltimezone *zone,
/* If we are stepping backwards through the changes and we have found
a change that applies, then we know this is the change to use so
we exit the loop. */
- if (step == -1 && change_num_to_use != -1)
- break;
+ if (step == -1) {
+ if (change_num_to_use != -1)
+ break;
- change_num += step;
+ /* If we go past the start of the changes array, then return the
+ TZOFFSETFROM of the first change.. */
+ if (change_num == 0)
+ return zone_change->prev_utc_offset;
+ }
- /* If we go past the start of the changes array, then we have no data
- for this time so we return a UTC offset of 0. */
- if (change_num < 0)
- return 0;
+ change_num += step;
if (change_num >= zone->changes->num_elements)
break;
@@ -867,24 +869,28 @@ icaltimezone_get_utc_offset (icaltimezone *zone,
/* The time is in the overlapped region, so we may need to use
either the current zone_change or the previous one. If the
time has the is_daylight field set we use the matching change,
- else we use the change with standard time. */
+ else we use the change with standard time. Note that iCalendar
+ doesn't let us distinguish between the different possible
+ choices here, so it isn't very reliable. Currently the main
+ use of the is_daylight flag is for testing. */
prev_zone_change = icalarray_element_at (zone->changes,
change_num_to_use - 1);
- /* I was going to add an is_daylight flag to struct icaltimetype,
- but iCalendar doesn't let us distinguish between standard and
- daylight time anyway, so there's no point. So we just use the
- standard time instead. */
- want_daylight = (tt->is_daylight == 1) ? 1 : 0;
-
+ /* If both possible changes have the same is_daylight setting,
+ then we choose the last one for now. It looks like the standard
+ Unix functions choose the each one half the time, so we may
+ want to try to figure out the rule for doing that. */
+ if (zone_change->is_daylight == prev_zone_change->is_daylight) {
#if 0
- if (zone_change->is_daylight == prev_zone_change->is_daylight)
- printf (" **** Same is_daylight setting\n");
+ printf (" **** Same is_daylight setting (%i). Choosing last change.\n", zone_change->is_daylight);
#endif
+ } else {
+ want_daylight = (tt->is_daylight == 1) ? 1 : 0;
- if (zone_change->is_daylight != want_daylight
- && prev_zone_change->is_daylight == want_daylight)
- zone_change = prev_zone_change;
+ if (zone_change->is_daylight != want_daylight
+ && prev_zone_change->is_daylight == want_daylight)
+ zone_change = prev_zone_change;
+ }
}
}
@@ -965,15 +971,17 @@ icaltimezone_get_utc_offset_of_utc_time (icaltimezone *zone,
/* If we are stepping backwards through the changes and we have found
a change that applies, then we know this is the change to use so
we exit the loop. */
- if (step == -1 && change_num_to_use != -1)
- break;
+ if (step == -1) {
+ if (change_num_to_use != -1)
+ break;
- change_num += step;
+ /* If we go past the start of the changes array, then return the
+ TZOFFSETFROM of the first change.. */
+ if (change_num == 0)
+ return zone_change->prev_utc_offset;
+ }
- /* If we go past the start of the changes array, then we have no data
- for this time so we return a UTC offset of 0. */
- if (change_num < 0)
- return 0;
+ change_num += step;
if (change_num >= zone->changes->num_elements)
break;
diff --git a/libical/src/libical/icaltimezone.h b/libical/src/libical/icaltimezone.h
index 1e8ec70048..b072f0dd9a 100644
--- a/libical/src/libical/icaltimezone.h
+++ b/libical/src/libical/icaltimezone.h
@@ -93,6 +93,9 @@ int icaltimezone_set_component (icaltimezone *zone,
* Converting times between timezones.
*/
+/* This converts the icaltimetype from one timezone to another. Note that it
+ does not convert DATE values. If you need to do that, you should clear the
+ is_date field first. */
void icaltimezone_convert_time (struct icaltimetype *tt,
icaltimezone *from_zone,
icaltimezone *to_zone);