Author: juha
Date: 2008-09-07 20:48:15 +0000 (Sun, 07 Sep 2008)
New Revision: 27731
Modified:
xfcalendar/trunk/tz_convert/tz_convert.c
Log:
working (alpha level) tz_convert
Modified: xfcalendar/trunk/tz_convert/tz_convert.c
===================================================================
--- xfcalendar/trunk/tz_convert/tz_convert.c 2008-09-07 18:42:57 UTC (rev
27730)
+++ xfcalendar/trunk/tz_convert/tz_convert.c 2008-09-07 20:48:15 UTC (rev
27731)
@@ -85,10 +85,10 @@
unsigned long typecnt; /* table of different time changes = types */
unsigned long charcnt; /* length of timezone name table */
-struct ical_data {
- /* check and write needs these */
+struct ical_timezone_data {
struct tm start_time;
long gmt_offset_hh, gmt_offset_mm;
+ long prev_gmt_offset_hh, prev_gmt_offset_mm;
unsigned int is_dst;
unsigned char *tz;
int hh_diff, mm_diff;
@@ -427,11 +427,12 @@
write_ical_str(line);
}
-struct ical_data wit_get_data(int i) {
+struct ical_timezone_data wit_get_data(int i
+ , struct ical_timezone_data prev) {
unsigned long tc_time;
long gmt_offset;
unsigned int tct_i, abbr_i;
- struct ical_data data;
+ struct ical_timezone_data data;
/* get timechange time */
in_head = begin_timechanges;
@@ -455,29 +456,183 @@
/* get timezone name */
in_head = begin_timezonenames;
data.tz = in_head + abbr_i;
+
+ /* ical needs the startime in the previous (=current) time, so we need to
+ * adjust by the difference */
+ data.hh_diff = prev.gmt_offset_hh - data.gmt_offset_hh;
+ data.mm_diff = prev.gmt_offset_mm - data.gmt_offset_mm;
+
+ if (data.hh_diff + data.start_time.tm_hour < 0
+ || data.hh_diff + data.start_time.tm_hour > 23
+ || data.mm_diff + data.start_time.tm_min < 0
+ || data.mm_diff + data.start_time.tm_min > 59) {
+ if (debug > 1)
+ printf("Error counting startime %s:\n", timezone_name);
+ data.hh_diff = 0;
+ data.mm_diff = 0;
+ }
+ /* we need to remember also the previous value. Note that this is from
+ * dst if we are not in std and vice versa */
+ data.prev_gmt_offset_hh = prev.gmt_offset_hh;
+ data.prev_gmt_offset_mm = prev.gmt_offset_mm;
+
return(data);
}
-void write_ical_timezones()
+int wit_get_rrule(struct ical_timezone_data prev
+ , struct ical_timezone_data cur) {
+ int days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+ int rrule_day_cnt;
+
+ printf("wit_get_rrule: start\n");
+ printf("\twit_get_rrule:
(%d/%d/%d)\n",cur.start_time.tm_year+1900,cur.start_time.tm_mon+1,cur.start_time.tm_mday);
+ if (cur.gmt_offset_hh == prev.gmt_offset_hh
+ && cur.gmt_offset_mm == prev.gmt_offset_mm
+ && !strcmp(cur.tz, prev.tz)) {
+ /* 2) check if we can use RRULE.
+ * We only check yearly same month and same week day changing
+ * rules (which should cover most real world cases). */
+ if (cur.start_time.tm_year == prev.start_time.tm_year + 1
+ && cur.start_time.tm_mon == prev.start_time.tm_mon
+ && cur.start_time.tm_wday == prev.start_time.tm_wday
+ && cur.start_time.tm_hour == prev.start_time.tm_hour
+ && cur.start_time.tm_min == prev.start_time.tm_min
+ && cur.start_time.tm_sec == prev.start_time.tm_sec
+ && cur.hh_diff == prev.hh_diff
+ && cur.mm_diff == prev.mm_diff) {
+ printf("\twit_get_rrule: rrule\n");
+ /* so far so good, now check that our weekdays are on
+ * the same week */
+ if (cur.start_time.tm_mon == 1) {
+ /* hopefully we never come here FIXME */
+ printf("leap year danger. I can not handle this!\n");
+ }
+ /* most often these change on the last week day
+ * (and on sunday, but that does not matter now) */
+ if ((days_in_month[cur.start_time.tm_mon] -
+ cur.start_time.tm_mday) < 7
+ && (days_in_month[prev.start_time.tm_mon] -
+ prev.start_time.tm_mday) < 7) {
+ /* yep, it is last */
+ rrule_day_cnt = -1;
+ }
+ else if (cur.start_time.tm_mday < 8
+ && prev.start_time.tm_mday < 8) {
+ /* ok, it is first */
+ rrule_day_cnt = 1;
+ }
+ else if (cur.start_time.tm_mday < 15
+ && prev.start_time.tm_mday < 15) {
+ /* fine, it is second */
+ rrule_day_cnt = 2;
+ }
+ else if (cur.start_time.tm_mday < 22
+ && prev.start_time.tm_mday < 22) {
+ /* must be the third then */
+ rrule_day_cnt = 3;
+ }
+ else {
+ /* give up, it did not work after all.
+ * It is quite possible that rule changed. */
+ printf("failed in finding RRULE! (%d)(%d)\n",
cur.start_time.tm_mday, prev.start_time.tm_mday);
+ rrule_day_cnt = 0;
+ }
+ /* FIXME: need to check that rule does not change */
+ }
+ else { /* 2) failed, need to use RDATE */
+ /* FIXME, let's add RRULE later and now just use
+ * full timezone enty */
+ rrule_day_cnt = 0;
+ }
+ }
+ else { /* 1) not possible to use RRULE nor RDATE, need new entry */
+ rrule_day_cnt = 0;
+ }
+ return(rrule_day_cnt);
+}
+
+void wit_write_data(int rrule_day_cnt
+ , struct ical_timezone_data old
+ , struct ical_timezone_data first
+ , struct ical_timezone_data prev)
{
- int i;
- struct ical_data ical_data
- , ical_data_prev = { {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL, 0, 0}
- , data_cur_std
- , data_prev_std = { {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL, 0, 0}
- , data_cur_dst
- , data_prev_dst = { {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, NULL, 0, 0};
- /* only write needs these */
char str[100];
int len;
char *dst_begin="BEGIN:DAYLIGHT\n";
char *dst_end="END:DAYLIGHT\n";
char *std_begin="BEGIN:STANDARD\n";
char *std_end="END:STANDARD\n";
+ char *day[] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA" };
+
+ printf("wit_write_data: start(%d)\n", rrule_day_cnt);
+ if (prev.is_dst)
+ write_ical_str(dst_begin);
+ else
+ write_ical_str(std_begin);
+
+ len = snprintf(str, 30, "TZOFFSETFROM:%+03d%02d\n"
+ , prev.prev_gmt_offset_hh, prev.prev_gmt_offset_mm);
+ fwrite(str, 1, len, ical_file);
+
+ len = snprintf(str, 30, "TZOFFSETTO:%+03d%02d\n"
+ , prev.gmt_offset_hh, prev.gmt_offset_mm);
+ fwrite(str, 1, len, ical_file);
+
+ len = snprintf(str, 99, "TZNAME:%s\n", prev.tz);
+ fwrite(str, 1, len, ical_file);
+
+ len = snprintf(str, 30, "DTSTART:%04d%02d%02dT%02d%02d%02d\n"
+ , first.start_time.tm_year + 1900
+ , first.start_time.tm_mon + 1
+ , first.start_time.tm_mday
+ , first.start_time.tm_hour + first.hh_diff
+ , first.start_time.tm_min + first.mm_diff
+ , first.start_time.tm_sec);
+ fwrite(str, 1, len, ical_file);
+
+ if (rrule_day_cnt) { /* we had repeating appointment */
+ len = snprintf(str, 50, "RRULE:FREQ=YEARLY;BYMONTH=%d;BYDAY=%d%s\n"
+ , first.start_time.tm_mon + 1
+ , rrule_day_cnt
+ , day[first.start_time.tm_wday]);
+ }
+ else {
+ len = snprintf(str, 30, "RDATE:%04d%02d%02dT%02d%02d%02d\n"
+ , prev.start_time.tm_year + 1900
+ , prev.start_time.tm_mon + 1
+ , prev.start_time.tm_mday
+ , prev.start_time.tm_hour + prev.hh_diff
+ , prev.start_time.tm_min + prev.mm_diff
+ , prev.start_time.tm_sec);
+ }
+ fwrite(str, 1, len, ical_file);
+
+ if (prev.is_dst)
+ write_ical_str(dst_end);
+ else
+ write_ical_str(std_end);
+}
+
+void write_ical_timezones()
+{
+ int i;
+ struct ical_timezone_data ical_data
+ , ical_data_prev = { {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, NULL, 0, 0}
+ , data_cur_std
+ , data_prev_std = { {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, NULL, 0, 0}
+ , data_first_std = { {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, NULL, 0, 0}
+ , data_old_std = { {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, NULL, 0, 0}
+ , data_cur_dst
+ , data_prev_dst = { {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, NULL, 0, 0}
+ , data_first_dst = { {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, NULL, 0, 0}
+ , data_old_dst = { {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, NULL, 0, 0};
+ /* only write needs these */
int dst_init_done = 0;
int dst_start = 0;
int std_init_done = 0;
int std_start = 0;
+ int rrule_day_cnt_dst = 0, rrule_day_cnt_dst_prev = 0;
+ int rrule_day_cnt_std = 0, rrule_day_cnt_std_prev = 0;
printf("write_ical_timezones: start\n");
/* we are processing "timezone_name" so we know it exists in this system,
@@ -489,106 +644,99 @@
}
for (i = 0; i < timecnt; i++) {
/***** get data *****/
- ical_data = wit_get_data(i);
+ ical_data = wit_get_data(i, ical_data_prev);
if (ical_data.is_dst) {
data_cur_dst = ical_data;
+ dst_start = 1;
}
else {
data_cur_std = ical_data;
+ std_start = 1;
}
if (i == 0) { /* first round, do starting values */
ical_data_prev = ical_data;
}
if (!dst_init_done && ical_data.is_dst) {
- data_prev_dst = ical_data;
+ data_old_dst = ical_data;
+ data_first_dst = ical_data;
+ data_prev_dst = ical_data;
dst_init_done = 1;
}
else if (!std_init_done && !ical_data.is_dst) {
- data_prev_std = ical_data;
+ data_old_std = ical_data;
+ data_first_std = ical_data;
+ data_prev_std = ical_data;
std_init_done = 1;
}
- /* ical needs the startime in the previous (=current) time, so we need to
- * adjust by the difference */
- ical_data.hh_diff = ical_data_prev.gmt_offset_hh
- - ical_data.gmt_offset_hh;
- ical_data.mm_diff = ical_data_prev.gmt_offset_mm
- - ical_data.gmt_offset_mm;
- if (ical_data.hh_diff + ical_data.start_time.tm_hour < 0
- || ical_data.hh_diff + ical_data.start_time.tm_hour > 23
- || ical_data.mm_diff + ical_data.start_time.tm_min < 0
- || ical_data.mm_diff + ical_data.start_time.tm_min > 59) {
- if (debug > 1)
- printf("Error counting startime %s:\n", timezone_name);
- ical_data.hh_diff = 0;
- ical_data.mm_diff = 0;
- }
-
/***** check if we need this data *****/
/* we only take newer than threshold values */
if (ical_data.start_time.tm_year + 1900 < ignore_older) {
- if (debug > 2)
- printf("\tskip %d = %s", i, asctime(&ical_data.start_time));
+ if (debug > 0)
+ printf("\tskip %d = (%s)%s", i
+ , ical_data.is_dst ? "dst" : "std"
+ , asctime(&ical_data.start_time));
ical_data_prev = ical_data;
- if (ical_data.is_dst)
- data_prev_dst = ical_data;
- else
- data_prev_std = ical_data;
+ if (ical_data.is_dst) {
+ data_old_dst = data_prev_dst;
+ data_first_dst = ical_data;
+ data_prev_dst = ical_data;
+ }
+ else {
+ data_old_std = data_prev_std;
+ data_first_std = ical_data;
+ data_prev_std = ical_data;
+ }
continue;
}
+ if (debug > 0)
+ printf("\tprocess %d = (%s)%s", i
+ , ical_data.is_dst ? "dst" : "std"
+ , asctime(&ical_data.start_time));
/***** check if we can shortcut the entry with RRULE or RDATE *****/
/* 1) check if it is similar to the previous values */
- if () {
+ if (ical_data.is_dst) {
+ rrule_day_cnt_dst_prev = rrule_day_cnt_dst;
+ rrule_day_cnt_dst = wit_get_rrule(data_prev_dst, ical_data);
+ if (rrule_day_cnt_dst) {
+ /* if we found RRULE, we do not have to do anything since this
+ * just continues. */
+ data_prev_dst = ical_data;
+ }
+ else { /* not RRULE, so write previous and init new round */
+ wit_write_data(rrule_day_cnt_dst_prev
+ , data_old_dst, data_first_dst, data_prev_dst);
+ data_old_dst = data_prev_dst;
+ data_first_dst = ical_data;
+ data_prev_dst = ical_data;
+ }
}
-
- /***** write data *****/
- if (ical_data.is_dst) {
- write_ical_str(dst_begin);
- }
- else {
- write_ical_str(std_begin);
- }
-
- len = snprintf(str, 30, "TZOFFSETFROM:%+03d%02d\n"
- , ical_data_prev.gmt_offset_hh, ical_data_prev.gmt_offset_mm);
- fwrite(str, 1, len, ical_file);
-
- len = snprintf(str, 30, "TZOFFSETTO:%+03d%02d\n"
- , ical_data.gmt_offset_hh, ical_data.gmt_offset_mm);
- fwrite(str, 1, len, ical_file);
-
- ical_data_prev = ical_data;
-
- len = snprintf(str, 99, "TZNAME:%s\n", ical_data.tz);
- fwrite(str, 1, len, ical_file);
-
- len = snprintf(str, 30, "DTSTART:%04d%02d%02dT%02d%02d%02d\n"
- , ical_data.start_time.tm_year + 1900
- , ical_data.start_time.tm_mon + 1
- , ical_data.start_time.tm_mday
- , ical_data.start_time.tm_hour + ical_data.hh_diff
- , ical_data.start_time.tm_min + ical_data.mm_diff
- , ical_data.start_time.tm_sec);
- fwrite(str, 1, len, ical_file);
-
- len = snprintf(str, 30, "RDATE:%04d%02d%02dT%02d%02d%02d\n"
- , ical_data.start_time.tm_year + 1900
- , ical_data.start_time.tm_mon + 1
- , ical_data.start_time.tm_mday
- , ical_data.start_time.tm_hour + ical_data.hh_diff
- , ical_data.start_time.tm_min + ical_data.mm_diff
- , ical_data.start_time.tm_sec);
- fwrite(str, 1, len, ical_file);
-
- if (ical_data.is_dst) {
- write_ical_str(dst_end);
- }
- else {
- write_ical_str(std_end);
- }
- }
+ else { /* !(ical_data.is_dst) */
+ rrule_day_cnt_std_prev = rrule_day_cnt_std;
+ rrule_day_cnt_std = wit_get_rrule(data_prev_std, ical_data);
+ if (rrule_day_cnt_std) {
+ /* if we found RRULE, we do not have to do anything since this
+ * just continues. */
+ data_prev_std = ical_data;
+ }
+ else { /* not RRULE, so write previous and init new round */
+ wit_write_data(rrule_day_cnt_std_prev
+ , data_old_std, data_first_std, data_prev_std);
+ data_old_std = data_prev_std;
+ data_first_std = ical_data;
+ data_prev_std = ical_data;
+ }
+ }
+ ical_data_prev = ical_data;
+ } /* for (i = 0; i < timecnt; i++) */
+ /* need to write the last one also */
+ printf("*****writing last entry*****\n");
+ wit_write_data(rrule_day_cnt_std_prev, data_old_std, data_first_std
+ , data_prev_std);
+ wit_write_data(rrule_day_cnt_dst_prev, data_old_dst, data_first_dst
+ , data_prev_dst);
printf("write_ical_timezones: end\n");
}
_______________________________________________
Xfce4-commits mailing list
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits