00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <time.h>
00023
00024 #include "opensync.h"
00025 #include "opensync_internals.h"
00026
00027
00028
00029
00030
00031 #ifdef SOLARIS
00032 time_t timegm(struct tm *t)
00033 {
00034 time_t tl, tb;
00035 struct tm *tg;
00036
00037 tl = mktime (t);
00038 if (tl == -1)
00039 {
00040 t->tm_hour--;
00041 tl = mktime (t);
00042 if (tl == -1)
00043 return -1;
00044 tl += 3600;
00045 }
00046 tg = gmtime (&tl);
00047 tg->tm_isdst = 0;
00048 tb = mktime (tg);
00049 if (tb == -1)
00050 {
00051 tg->tm_hour--;
00052 tb = mktime (tg);
00053 if (tb == -1)
00054 return -1;
00055 tb += 3600;
00056 }
00057 return (tl - (tb - tl));
00058 }
00059 #endif
00060
00061
00062
00063
00064
00065
00066
00072 static char *osync_time_timestamp_remove_dash(const char *timestamp) {
00073 int i, len;
00074 GString *str = g_string_new("");
00075
00076 len = strlen(timestamp);
00077
00078 for (i=0; i < len; i++) {
00079 if (timestamp[i] == '-')
00080 continue;
00081
00082 if (timestamp[i] == ':')
00083 continue;
00084
00085 str = g_string_append_c(str, timestamp[i]);
00086 }
00087
00088 return (char*) g_string_free(str, FALSE);
00089 }
00090
00096 char *osync_time_timestamp(const char *vtime) {
00097 osync_trace(TRACE_ENTRY, "%s(%s)", __func__, vtime);
00098
00099 char *timestamp;
00100
00101 timestamp = osync_time_timestamp_remove_dash(vtime);
00102
00103 osync_trace(TRACE_EXIT, "%s: %s", __func__, timestamp);
00104 return timestamp;
00105 }
00106
00112 char *osync_time_datestamp(const char *vtime) {
00113 osync_trace(TRACE_ENTRY, "%s(%s)", __func__, vtime);
00114
00115 char *tmp;
00116 const char *p;
00117 GString *str = g_string_new ("");
00118
00119 tmp = osync_time_timestamp_remove_dash(vtime);
00120
00121 for (p=tmp; *p && *p != 'T'; p++)
00122 str = g_string_append_c (str, *p);
00123
00124 free(tmp);
00125
00126 osync_trace(TRACE_EXIT, "%s: %s", __func__, str->str);
00127 return (char*) g_string_free(str, FALSE);
00128 }
00129
00134 osync_bool osync_time_isdate(const char *vtime) {
00135
00136 int year, month, day;
00137
00138 if (strstr(vtime, "T"))
00139 return FALSE;
00140
00141
00142 if (sscanf(vtime, "%04d%02d%02d", &year, &month, &day) != 3)
00143 return FALSE;
00144
00145 return TRUE;
00146 }
00147
00152 osync_bool osync_time_isutc(const char *vtime) {
00153
00154 if (!strstr(vtime, "Z"))
00155 return FALSE;
00156
00157 return TRUE;
00158 }
00159
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00194 struct tm *osync_time_vtime2tm(const char *vtime) {
00195
00196 osync_trace(TRACE_ENTRY, "%s(%s)", __func__, vtime);
00197
00198 struct tm *utime = g_malloc0(sizeof(struct tm));
00199
00200 utime->tm_year = 0;
00201 utime->tm_mon = 0;
00202 utime->tm_mday = 0;
00203 utime->tm_hour = 0;
00204 utime->tm_min = 0;
00205 utime->tm_sec = 0;
00206
00207 sscanf(vtime, "%04d%02d%02dT%02d%02d%02d%*01c",
00208 &(utime->tm_year), &(utime->tm_mon), &(utime->tm_mday),
00209 &(utime->tm_hour), &(utime->tm_min), &(utime->tm_sec));
00210
00211 utime->tm_year -= 1900;
00212 utime->tm_mon -= 1;
00213
00214
00215 utime->tm_isdst = -1;
00216
00217 osync_trace(TRACE_EXIT, "%s", __func__);
00218 return utime;
00219 }
00220
00230 char *osync_time_tm2vtime(const struct tm *time, osync_bool is_utc) {
00231
00232 osync_trace(TRACE_ENTRY, "%s(%p, %i)", __func__, time, is_utc);
00233 GString *vtime = g_string_new("");
00234
00235 g_string_printf(vtime, "%04d%02d%02dT%02d%02d%02d",
00236 time->tm_year + 1900, time->tm_mon + 1, time->tm_mday,
00237 time->tm_hour, time->tm_min, time->tm_sec);
00238
00239 if (is_utc)
00240 vtime = g_string_append(vtime, "Z");
00241
00242 osync_trace(TRACE_EXIT, "%s: %s", __func__, vtime->str);
00243 return g_string_free(vtime, FALSE);
00244 }
00245
00252 time_t osync_time_vtime2unix(const char *vtime, int offset) {
00253
00254 osync_trace(TRACE_ENTRY, "%s(%s, %i)", __func__, vtime, offset);
00255 struct tm *utime = NULL;
00256 time_t timestamp;
00257 char *utc = NULL;
00258
00259 utc = osync_time_vtime2utc(vtime, offset);
00260 utime = osync_time_vtime2tm(utc);
00261
00262 timestamp = osync_time_tm2unix(utime);
00263
00264 g_free(utc);
00265 g_free(utime);
00266
00267 osync_trace(TRACE_EXIT, "%s: %lu", __func__, timestamp);
00268 return timestamp;
00269 }
00270
00276 char *osync_time_unix2vtime(const time_t *timestamp) {
00277
00278 osync_trace(TRACE_ENTRY, "%s(%lu)", __func__, *timestamp);
00279 char *vtime;
00280 struct tm utc;
00281
00282 gmtime_r(timestamp, &utc);
00283 vtime = osync_time_tm2vtime(&utc, TRUE);
00284
00285 osync_trace(TRACE_EXIT, "%s: %s", __func__, vtime);
00286 return vtime;
00287 }
00288
00294 time_t osync_time_tm2unix(const struct tm *tmtime) {
00295
00296 time_t timestamp;
00297 struct tm *tmp = g_malloc0(sizeof(struct tm));
00298
00299 memcpy(tmp, tmtime, sizeof(struct tm));
00300
00301 timestamp = timegm(tmp);
00302
00303 g_free(tmp);
00304
00305 return timestamp;
00306 }
00307
00313 struct tm *osync_time_unix2tm(const time_t *timestamp) {
00314
00315 struct tm *ptr_tm;
00316 struct tm tmtime;
00317
00318 gmtime_r(timestamp, &tmtime);
00319
00320 ptr_tm = &tmtime;
00321
00322 return ptr_tm;
00323 }
00324
00325
00326
00327
00328
00334 int osync_time_timezone_diff(const struct tm *time) {
00335 osync_trace(TRACE_ENTRY, "%s()", __func__);
00336
00337 struct tm ltime, utime;
00338 unsigned int lsecs, usecs;
00339 long zonediff;
00340 time_t timestamp;
00341
00342 timestamp = osync_time_tm2unix(time);
00343
00344 tzset();
00345
00346 localtime_r(×tamp, <ime);
00347 gmtime_r(×tamp, &utime);
00348
00349 lsecs = 3600 * ltime.tm_hour + 60 * ltime.tm_min + ltime.tm_sec;
00350 usecs = 3600 * utime.tm_hour + 60 * utime.tm_min + utime.tm_sec;
00351
00352 zonediff = lsecs - usecs;
00353
00354
00355 if (utime.tm_mday != ltime.tm_mday) {
00356 if (utime.tm_mday < ltime.tm_mday)
00357 zonediff += 24 * 3600;
00358 else
00359 zonediff -= 24 * 3600;
00360 }
00361
00362 osync_trace(TRACE_EXIT, "%s: %i", __func__, zonediff);
00363 return zonediff;
00364 }
00365
00373 struct tm *osync_time_tm2utc(const struct tm *ltime, int offset) {
00374
00375 osync_trace(TRACE_ENTRY, "%s(%p, %i)", __func__, ltime, offset);
00376 struct tm *tmtime = g_malloc0(sizeof(struct tm));
00377
00378 tmtime->tm_year = ltime->tm_year;
00379 tmtime->tm_mon = ltime->tm_mon;
00380 tmtime->tm_mday = ltime->tm_mday;
00381 tmtime->tm_hour = ltime->tm_hour;
00382 tmtime->tm_min = ltime->tm_min;
00383 tmtime->tm_sec = ltime->tm_sec;
00384
00385
00386 tmtime->tm_hour -= offset / 3600;
00387 tmtime->tm_min -= (offset % 3600) / 60;
00388
00389 if (tmtime->tm_hour > 23 || tmtime->tm_hour < 0) {
00390
00391 if (tmtime->tm_hour < 0) {
00392 tmtime->tm_hour += 24;
00393 tmtime->tm_mday -= 1;
00394 } else {
00395 tmtime->tm_hour -= 24;
00396 tmtime->tm_mday += 1;
00397 }
00398 }
00399
00400 osync_trace(TRACE_EXIT, "%s: %p", __func__, tmtime);
00401 return tmtime;
00402 }
00403
00411 struct tm *osync_time_tm2localtime(const struct tm *utime, int offset) {
00412
00413 struct tm *tmtime = g_malloc0(sizeof(struct tm));
00414
00415 tmtime->tm_year = utime->tm_year;
00416 tmtime->tm_mon = utime->tm_mon;
00417 tmtime->tm_mday = utime->tm_mday;
00418 tmtime->tm_hour = utime->tm_hour;
00419 tmtime->tm_min = utime->tm_min;
00420 tmtime->tm_sec = utime->tm_sec;
00421
00422 tmtime->tm_hour += offset / 3600;
00423 tmtime->tm_min += (offset % 3600) / 60;
00424
00425 if (tmtime->tm_hour > 23 || tmtime->tm_hour < 0) {
00426
00427 if (tmtime->tm_hour < 0) {
00428 tmtime->tm_mday -= 1;
00429 tmtime->tm_hour += 24;
00430 } else {
00431 tmtime->tm_mday += 1;
00432 tmtime->tm_hour -= 24;
00433 }
00434 }
00435
00436 return tmtime;
00437 }
00438
00445 char *osync_time_vtime2utc(const char* localtime, int offset) {
00446 osync_trace(TRACE_ENTRY, "%s(%s)", __func__, localtime);
00447
00448 char *utc = NULL;
00449 struct tm *tm_local = NULL, *tm_utc = NULL;
00450
00451 if (strstr(localtime, "Z")) {
00452 utc = strdup(localtime);
00453 goto end;
00454 }
00455
00456 tm_local = osync_time_vtime2tm(localtime);
00457 tm_utc = osync_time_tm2utc(tm_local, offset);
00458 utc = osync_time_tm2vtime(tm_utc, TRUE);
00459
00460 g_free(tm_local);
00461
00462
00463
00464 end:
00465 osync_trace(TRACE_EXIT, "%s: %s", __func__, utc);
00466 return utc;
00467 }
00468
00474 char *osync_time_vtime2localtime(const char* utc, int offset) {
00475
00476 char *localtime = NULL;
00477 struct tm *tm_local = NULL, *tm_utc = NULL;
00478
00479 if (!strstr(utc, "Z")) {
00480 localtime = strdup(utc);
00481 return localtime;
00482 }
00483
00484 tm_utc = osync_time_vtime2tm(utc);
00485 tm_local = osync_time_tm2localtime(tm_utc, offset);
00486 localtime = osync_time_tm2vtime(tm_local, FALSE);
00487
00488 g_free(tm_local);
00489 g_free(tm_utc);
00490
00491 return localtime;
00492 }
00493
00494
00495
00496
00497
00498
00502 const char *_time_attr[] = {
00503 "DTSTART:",
00504 "DTEND:",
00505 "DTSTAMP:",
00506 "AALARM:",
00507 "DALARM:",
00508 "DUE:",
00509 NULL
00510 };
00511
00518 static void _convert_time_field(GString *entry, const char *field, osync_bool toUTC) {
00519
00520 int i, tzdiff;
00521 char *res = NULL;
00522 char *new_stamp = NULL;
00523
00524 GString *stamp = g_string_new("");
00525
00526 if ((res = strstr(entry->str, field))) {
00527 res += strlen(field);
00528
00529 for (i=0; res[i] != '\n' && res[i] != '\r'; i++)
00530 stamp = g_string_append_c(stamp, res[i]);
00531
00532 gssize pos = res - entry->str;
00533 entry = g_string_erase(entry, pos, i);
00534
00535
00536 struct tm *tm_stamp = osync_time_vtime2tm(stamp->str);
00537 tzdiff = osync_time_timezone_diff(tm_stamp);
00538 g_free(tm_stamp);
00539
00540 if (toUTC)
00541 new_stamp = osync_time_vtime2utc(stamp->str, tzdiff);
00542 else
00543 new_stamp = osync_time_vtime2localtime(stamp->str, tzdiff);
00544
00545 entry = g_string_insert(entry, pos, new_stamp);
00546 g_free(new_stamp);
00547 }
00548 }
00549
00556 char *_convert_entry(const char *vcal, osync_bool toUTC) {
00557
00558 int i = 0;
00559 GString *new_entry = g_string_new(vcal);
00560
00561 for (i=0; _time_attr[i] != NULL; i++)
00562 _convert_time_field(new_entry, _time_attr[i], toUTC);
00563
00564 return g_string_free(new_entry, FALSE);
00565 }
00566
00572 char *osync_time_vcal2localtime(const char *vcal) {
00573
00574 return _convert_entry(vcal, FALSE);
00575 }
00576
00582 char *osync_time_vcal2utc(const char *vcal) {
00583
00584 return _convert_entry(vcal, TRUE);
00585 }
00586
00593 char *osync_time_sec2alarmdu(int seconds) {
00594
00595 osync_trace(TRACE_ENTRY, "%s(%i)", __func__, seconds);
00596
00597 char *tmp = NULL;
00598 char *prefix = NULL;
00599
00600 if (!seconds) {
00601 tmp = g_strdup("PT0S");
00602 goto end;
00603 }
00604
00605 if (seconds > 0) {
00606 prefix = g_strdup("P");
00607 } else {
00608 prefix = g_strdup("-P");
00609 seconds *= -1;
00610 }
00611
00612
00613 if (!(seconds % (3600 * 24))) {
00614 tmp = g_strdup_printf("%s%iD", prefix, seconds / (3600 * 24));
00615 goto end;
00616 }
00617
00618
00619 if (!(seconds % 3600)) {
00620 tmp = g_strdup_printf("%sT%iH", prefix, seconds / 3600);
00621 goto end;
00622 }
00623
00624
00625 if (!(seconds % 60) && seconds < 3600) {
00626 tmp = g_strdup_printf("%sT%iM", prefix, seconds / 60);
00627 goto end;
00628 }
00629
00630
00631 if (seconds < 60) {
00632 tmp = g_strdup_printf("%sT%iS", prefix, seconds);
00633 goto end;
00634 }
00635
00636 if (seconds > 60)
00637 tmp = g_strdup_printf("%sT%iM", prefix, seconds / 60);
00638
00639 if (seconds > 3600)
00640 tmp = g_strdup_printf("%sT%iH%iM", prefix, seconds / 3600,
00641 (seconds % 3600) / 60);
00642
00643 if (seconds > (3600 * 24))
00644 tmp = g_strdup_printf("%s%iDT%iH%iM", prefix, seconds / (3600 * 24),
00645 seconds % (3600 * 24) / 3600,
00646 ((seconds % (3600 * 24) % 3600)) / 60);
00647
00648 end:
00649 g_free(prefix);
00650
00651 osync_trace(TRACE_EXIT, "%s: %s", __func__, tmp);
00652 return tmp;
00653 }
00654
00663 int osync_time_alarmdu2sec(const char *alarm) {
00664
00665 osync_trace(TRACE_ENTRY, "%s(%s)", __func__, alarm);
00666
00667 int i, secs, digits;
00668 int is_digit = 0;
00669 int sign = 1;
00670 int days = 0, weeks = 0, hours = 0, minutes = 0, seconds = 0;
00671
00672 for (i=0; i < (int) strlen(alarm); i++) {
00673
00674 switch (alarm[i]) {
00675 case '-':
00676 sign = -1;
00677 case 'P':
00678 case 'T':
00679 is_digit = 0;
00680 break;
00681 case 'W':
00682 is_digit = 0;
00683 weeks = digits;
00684 break;
00685 case 'D':
00686 is_digit = 0;
00687 days = digits;
00688 break;
00689 case 'H':
00690 is_digit = 0;
00691 hours = digits;
00692 break;
00693 case 'M':
00694 is_digit = 0;
00695 minutes = digits;
00696 break;
00697 case 'S':
00698 is_digit = 0;
00699 seconds = digits;
00700 break;
00701 case '0':
00702 case '1':
00703 case '2':
00704 case '3':
00705 case '4':
00706 case '5':
00707 case '6':
00708 case '7':
00709 case '8':
00710 case '9':
00711 if (is_digit)
00712 break;
00713
00714 sscanf((char*)(alarm+i),"%d",&digits);
00715 is_digit = 1;
00716 break;
00717 }
00718 }
00719
00720 secs = (weeks * 7 * 24 * 3600) + (days * 24 * 3600) + (hours * 3600) + (minutes * 60) + seconds;
00721
00722 secs = secs * sign;
00723
00724 osync_trace(TRACE_EXIT, "%s: %i", __func__, secs);
00725 return secs;
00726 }
00727
00728
00729
00730
00731
00737 int osync_time_str2wday(const char *swday) {
00738
00739 int weekday = -1;
00740
00741 if (!strcmp(swday, "SU"))
00742 weekday = 0;
00743 else if (!strcmp(swday, "MO"))
00744 weekday = 1;
00745 else if (!strcmp(swday, "TU"))
00746 weekday = 2;
00747 else if (!strcmp(swday, "WE"))
00748 weekday = 3;
00749 else if (!strcmp(swday, "TH"))
00750 weekday = 4;
00751 else if (!strcmp(swday, "FR"))
00752 weekday = 5;
00753 else if (!strcmp(swday, "SA"))
00754 weekday = 6;
00755
00756 return weekday;
00757 }
00758
00769 struct tm *osync_time_relative2tm(const char *byday, const int bymonth, const int year) {
00770
00771 struct tm *datestamp = g_malloc0(sizeof(struct tm));
00772 char weekday[3];
00773 int first_wday = 0, last_wday = 0;
00774 int daymod, mday, searched_wday;
00775
00776 sscanf(byday, "%d%s", &daymod, weekday);
00777 weekday[2] = '\0';
00778
00779 searched_wday = osync_time_str2wday(weekday);
00780
00781 datestamp->tm_year = year - 1900;
00782 datestamp->tm_mon = bymonth - 1;
00783 datestamp->tm_mday = 0;
00784 datestamp->tm_hour = 0;
00785 datestamp->tm_min = 0;
00786 datestamp->tm_sec = 0;
00787 datestamp->tm_isdst = -1;
00788
00789 for (mday = 0; mday <= 31; mday++) {
00790 datestamp->tm_mday = mday;
00791 mktime(datestamp);
00792
00793 if (datestamp->tm_wday == searched_wday) {
00794 if (!first_wday)
00795 first_wday = searched_wday;
00796
00797 last_wday = searched_wday;
00798 }
00799 }
00800
00801 if (daymod > 0)
00802 datestamp->tm_mday = first_wday + (7 * (daymod - 1));
00803 else
00804 datestamp->tm_mday = last_wday - (7 * (daymod - 1));
00805
00806 mktime(datestamp);
00807
00808 return datestamp;
00809 }
00810
00816 int osync_time_utcoffset2sec(const char *offset) {
00817 osync_trace(TRACE_ENTRY, "%s(%s)", __func__, offset);
00818
00819 char csign = 0;
00820 int seconds = 0, sign = 1;
00821 int hours = 0, minutes = 0;
00822
00823 sscanf(offset, "%c%2d%2d", &csign, &hours, &minutes);
00824
00825 if (csign == '-')
00826 sign = -1;
00827
00828 seconds = (hours * 3600 + minutes * 60) * sign;
00829
00830 osync_trace(TRACE_EXIT, "%s: %i", __func__, seconds);
00831 return seconds;
00832 }
00833
00841 struct tm *osync_time_dstchange(xmlNode *dstNode) {
00842
00843 int month;
00844 struct tm *dst_change = NULL, *tm_started = NULL;
00845 char *started = NULL, *rule = NULL, *byday = NULL;
00846
00847 xmlNode *current = osxml_get_node(dstNode, "DateStarted");
00848 started = (char*) xmlNodeGetContent(current);
00849 tm_started = osync_time_vtime2tm(started);
00850
00851 g_free(started);
00852
00853 current = osxml_get_node(dstNode, "RecurrenceRule");
00854 current = current->children;
00855
00856 while (current) {
00857 rule = (char *) xmlNodeGetContent(current);
00858
00859 if (strstr(rule, "BYDAY="))
00860 byday = g_strdup(rule + 6);
00861 else if (strstr(rule, "BYMONTH="))
00862 sscanf(rule, "BYMONTH=%d", &month);
00863
00864 g_free(rule);
00865
00866 current = current->next;
00867 }
00868
00869 dst_change = osync_time_relative2tm(byday, month, tm_started->tm_year + 1900);
00870
00871 g_free(byday);
00872
00873 dst_change->tm_hour = tm_started->tm_hour;
00874 dst_change->tm_min = tm_started->tm_min;
00875
00876 g_free(tm_started);
00877
00878 return dst_change;
00879 }
00880
00887 osync_bool osync_time_isdst(const char *vtime, xmlNode *tzid) {
00888
00889 osync_trace(TRACE_ENTRY, "%s(%s, %p)", __func__, vtime, tzid);
00890
00891 int year;
00892 char *newyear = NULL;
00893 time_t newyear_t, timestamp;
00894 struct tm *std_changetime, *dst_changetime;
00895 time_t dstStamp, stdStamp;
00896 xmlNode *current = NULL;
00897
00898 sscanf(vtime, "%4d%*2d%*2dT%*2d%*d%*2d%*c", &year);
00899
00900 newyear = g_strdup_printf("%4d0101T000000", year);
00901 newyear_t = osync_time_vtime2unix(newyear, 0);
00902 timestamp = osync_time_vtime2unix(vtime, 0);
00903
00904
00905 current = osxml_get_node(tzid, "Standard");
00906 std_changetime = osync_time_dstchange(current);
00907
00908 current = osxml_get_node(tzid, "DaylightSavings");
00909 dst_changetime = osync_time_dstchange(current);
00910
00911
00912 dstStamp = osync_time_tm2unix(dst_changetime);
00913 stdStamp = osync_time_tm2unix(std_changetime);
00914
00915 if (timestamp > stdStamp && timestamp < dstStamp) {
00916 osync_trace(TRACE_EXIT, "%s: FALSE (Standard Timezone)", __func__);
00917 return FALSE;
00918 }
00919
00920 osync_trace(TRACE_EXIT, "%s: TRUE (Daylight Saving Timezone)", __func__);
00921 return TRUE;
00922 }
00923
00931 int osync_time_tzoffset(const char *vtime, xmlNode *tz) {
00932
00933 osync_trace(TRACE_ENTRY, "%s(%s, %p)", __func__, vtime, tz);
00934
00935 int seconds;
00936 char *offset = NULL;
00937 xmlNode *current = NULL;
00938
00939 if (osync_time_isdst(vtime, tz))
00940 current = osxml_get_node(tz, "DaylightSavings");
00941 else
00942 current = osxml_get_node(tz, "Standard");
00943
00944 offset = osxml_find_node(current, "TZOffsetFrom");
00945 seconds = osync_time_utcoffset2sec(offset);
00946
00947 osync_trace(TRACE_EXIT, "%s: %i", __func__, seconds);
00948 return seconds;
00949 }
00950
00956 char *osync_time_tzid(xmlNode *tz) {
00957 osync_trace(TRACE_ENTRY, "%s(%p)", __func__, tz);
00958
00959 char *id = NULL;
00960
00961 id = osxml_find_node(tz, "TimezoneID");
00962
00963 osync_trace(TRACE_EXIT, "%s: %s", __func__, id);
00964 return id;
00965 }
00966
00972 char *osync_time_tzlocation(xmlNode *tz) {
00973 osync_trace(TRACE_ENTRY, "%s(%p)", __func__, tz);
00974
00975 char *location = NULL;
00976
00977 location = osxml_find_node(tz, "TimezoneLocation");
00978
00979 osync_trace(TRACE_EXIT, "%s: %s", __func__, location);
00980 return location;
00981 }
00982
00989 xmlNode *osync_time_tzinfo(xmlNode *root, const char *tzid) {
00990
00991 osync_trace(TRACE_ENTRY, "%s(%p, %s)", __func__, root, tzid);
00992
00993 int numnodes, i;
00994 char *tzinfo_tzid = NULL;
00995
00996 xmlNode *tz = NULL;
00997 xmlNodeSet *nodes = NULL;
00998 xmlXPathObject *xobj = NULL;
00999
01000
01001 xobj = osxml_get_nodeset(root->doc, "/vcal/Timezone");
01002 nodes = xobj->nodesetval;
01003 numnodes = (nodes) ? nodes->nodeNr : 0;
01004
01005 osync_trace(TRACE_INTERNAL, "Found %i Timezone field(s)", numnodes);
01006
01007 if (!numnodes)
01008 goto noresult;
01009
01010
01011 for (i=0; i < numnodes; i++) {
01012 tz = nodes->nodeTab[i];
01013 tzinfo_tzid = osync_time_tzid(tz);
01014
01015 if (!tzinfo_tzid) {
01016 g_free(tzinfo_tzid);
01017 tz = NULL;
01018 continue;
01019 }
01020
01021 if (!strcmp(tzinfo_tzid, tzid))
01022 break;
01023 }
01024
01025 g_free(tzinfo_tzid);
01026
01027 if (!tz)
01028 goto noresult;
01029
01030
01031 osync_trace(TRACE_EXIT, "%s: %p", __func__, tz);
01032 return tz;
01033
01034 noresult:
01035 osync_trace(TRACE_EXIT, "%s: No matching Timezone node found. Seems to be a be a floating timestamp.", __func__);
01036 return NULL;
01037 }
01038
01045 char *osync_time_tzlocal2utc(xmlNode *root, const char *field) {
01046 osync_trace(TRACE_ENTRY, "%s(%p, %s)", __func__, root, field);
01047
01048 int offset = 0;
01049 char *utc = NULL, *field_tzid = NULL, *vtime = NULL;
01050 xmlNode *tz = NULL;
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060 field_tzid = osync_time_tzid(root);
01061 if (!field_tzid) {
01062 g_free(field_tzid);
01063 goto noresult;
01064 }
01065
01066 tz = osync_time_tzinfo(root, field_tzid);
01067 g_free(field_tzid);
01068
01069 if (!tz)
01070 goto noresult;
01071
01072 vtime = osxml_find_node(root, "Content");
01073
01074
01075 offset = osync_time_tzoffset(vtime, tz);
01076 struct tm *ttm = osync_time_vtime2tm(vtime);
01077 ttm->tm_hour -= offset / 3600;
01078 ttm->tm_min -= (offset % 3600) / 60;
01079 mktime(ttm);
01080 utc = osync_time_tm2vtime(ttm, TRUE);
01081
01082 g_free(vtime);
01083 g_free(ttm);
01084
01085 osync_trace(TRACE_EXIT, "%s: %s", __func__, utc);
01086 return utc;
01087
01088 noresult:
01089 osync_trace(TRACE_EXIT, "%s: No matching Timezone node is found.", __func__);
01090 return NULL;
01091 }
01092