/** Returns a single builtin timezone, given its Olson city name. */ icaltimezone* icaltimezone_get_builtin_timezone (const char *location) { icaltimezone *zone; int lower, upper, middle, cmp; char *zone_location; if (!location || !location[0]) return NULL; if (!builtin_timezones) icaltimezone_init_builtin_timezones (); if (!strcmp (location, "UTC")) return &utc_timezone; /* Do a simple binary search. */ lower = middle = 0; upper = builtin_timezones->num_elements; while (lower < upper) { middle = (lower + upper) / 2; zone = icalarray_element_at (builtin_timezones, middle); zone_location = icaltimezone_get_location (zone); cmp = strcmp (location, zone_location); if (cmp == 0) return zone; else if (cmp < 0) upper = middle; else lower = middle + 1; } return NULL; }
static void on_timezone_set (GnomeDialog *dialog, int button, ETimezoneDialog *etd) { icaltimezone *zone; zone = e_timezone_dialog_get_timezone (etd); if (zone) calendar_config_set_timezone (icaltimezone_get_location (zone)); g_object_unref (etd); }
static gchar * test_timezones (ECal *client) { icaltimezone *zone; GError *error = NULL; if (!e_cal_get_timezone (client, "UTC", &zone, &error)) { cl_printf (client, "Could not get the timezone\n"); } printf ("\n\nTime Zones : \n%s *** %s", icaltimezone_get_display_name (zone), icaltimezone_get_tzid (zone)); printf ("\n\nTime Zones : \n%s", icaltimezone_get_location (zone)); return NULL; }
static void test_libical_timezones_compatibility (gconstpointer user_data) { gboolean retval = TRUE; gint i; for (i = 0; i < builtin_timezones->num_elements; i++) { icaltimezone *zone; const gchar *zone_location; zone = icalarray_element_at (builtin_timezones, i); zone_location = icaltimezone_get_location (zone); if (ical_to_msdn_equivalent (zone_location) == NULL) { if (!is_a_known_unknown_timezone (zone_location)) { retval = FALSE; g_printerr ("\nMissing ical_tz_location: %s\n", zone_location); } } } g_assert (retval == TRUE); }
void calendar_config_select_day_second_zone (void) { icaltimezone *zone = NULL; ETimezoneDialog *tzdlg; GtkWidget *dialog; gchar *second_location; second_location = calendar_config_get_day_second_zone (); if (second_location && *second_location) zone = icaltimezone_get_builtin_timezone (second_location); g_free (second_location); if (!zone) zone = calendar_config_get_icaltimezone (); tzdlg = e_timezone_dialog_new (); e_timezone_dialog_set_timezone (tzdlg, zone); dialog = e_timezone_dialog_get_toplevel (tzdlg); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { const gchar *location = NULL; zone = e_timezone_dialog_get_timezone (tzdlg); if (zone == icaltimezone_get_utc_timezone ()) { location = "UTC"; } else if (zone) { location = icaltimezone_get_location (zone); } calendar_config_set_day_second_zone (location); } g_object_unref (tzdlg); }
static void test_time_zones_sync (gconstpointer user_data) { gboolean retval = FALSE; gint i; GError *error = NULL; UhmServer *local_server; EwsTestData *etd = (gpointer) user_data; EwsCalendarConvertData convert_data; EwsFolderId *calendar_fid = NULL; gboolean includes_last_folder = FALSE; gchar *old_sync_state = NULL; gchar **tokens; GSList *zone_location_errors = NULL; local_server = ews_test_get_mock_server (); ews_test_server_set_trace_directory (local_server, etd->version, "calendar/timezones"); ews_test_server_start_trace (local_server, etd, "get_server_time_zones_sync", &error); if (error != NULL) { g_printerr ("\n%s\n", error->message); goto exit; } while (!includes_last_folder) { GSList *folders_created = NULL; GSList *folders_updated = NULL; GSList *folders_deleted = NULL; GSList *l; gchar *new_sync_state = NULL; gboolean found = FALSE; old_sync_state = new_sync_state; e_ews_connection_sync_folder_hierarchy_sync ( etd->connection, EWS_PRIORITY_MEDIUM, old_sync_state, &new_sync_state, &includes_last_folder, &folders_created, &folders_updated, &folders_deleted, NULL, &error); if (error != NULL) { g_free (old_sync_state); g_printerr ("\n%s\n", error->message); goto exit; } for (l = folders_created; l != NULL; l = l->next) { EEwsFolder *folder = l->data; if (e_ews_folder_get_folder_type (folder) == E_EWS_FOLDER_TYPE_CALENDAR) { const EwsFolderId *fid; fid = e_ews_folder_get_id (folder); calendar_fid = g_new0 (EwsFolderId, 1); calendar_fid->id = g_strdup (fid->id); calendar_fid->change_key = g_strdup (fid->change_key); found = TRUE; break; } } g_slist_free_full (folders_created, g_object_unref); g_slist_free_full (folders_updated, g_object_unref); g_slist_free_full (folders_deleted, g_free); g_free (old_sync_state); old_sync_state = NULL; if (found) { g_free (new_sync_state); break; } } if (!calendar_fid) { g_printerr ("No calendar folder found\n"); goto exit; } convert_data.connection = etd->connection; convert_data.default_zone = icaltimezone_get_utc_timezone (); tokens = g_strsplit (str_comp, "ICAL_TIMEZONE", 0); for (i = 0; i < builtin_timezones->num_elements; i++) { GSList *ll; GSList *ids = NULL; icaltimezone *zone; ECalComponent *comp; const gchar *zone_location; gchar *str; zone = icalarray_element_at (builtin_timezones, i); zone_location = icaltimezone_get_location (zone); if (is_a_known_unknown_timezone (zone_location)) continue; str = g_strdup_printf ("%s%s%s%s%s", tokens[0], zone_location, tokens[1], zone_location, tokens[2]); comp = e_cal_component_new_from_string (str); g_free (str); convert_data.icalcomp = e_cal_component_get_icalcomponent (comp); e_ews_connection_create_items_sync ( etd->connection, EWS_PRIORITY_MEDIUM, "SaveOnly", "SendToNone", calendar_fid, convert_calcomp_to_xml, &convert_data, &ids, NULL, &error); g_object_unref (comp); if (error != NULL) { g_printerr ("\n%s\n", error->message); g_clear_error (&error); zone_location_errors = g_slist_append (zone_location_errors, g_strdup (zone_location)); continue; } for (ll = ids; ll != NULL; ll = ll->next) { EEwsItem *item = ll->data; if (e_ews_item_get_item_type (item) == E_EWS_ITEM_TYPE_ERROR) { const GError *item_error = e_ews_item_get_error (item); g_printerr ("\n%s\n", item_error->message); g_clear_error (&error); zone_location_errors = g_slist_append (zone_location_errors, g_strdup (zone_location)); continue; } } g_slist_free_full (ids, g_object_unref); } retval = zone_location_errors == NULL; exit: if (zone_location_errors != NULL) { GSList *l; g_printerr ("Errors found in: \n"); for (l = zone_location_errors; l != NULL; l = l->next) g_printerr (" - %s\n", (gchar *) l->data); g_slist_free_full (zone_location_errors, g_free); } uhm_server_end_trace (local_server); g_clear_error (&error); g_assert (retval == TRUE); }
int main() { icalarray *timezones; icaltimezone *zone, *utc_zone; char *zone_location; size_t i; int ret = 0; unsigned int total_failed = 0; unsigned int total_okay = 0; unsigned int percent_failed = 0; int verbose = 0; int day; time_t start_time; struct tm start_tm; time_t curr_time; struct tm curr_tm; struct icaltimetype curr_tt; int failed = 0; int curr_failed; int zonedef_printed = 0; #if !defined(HAVE_SETENV) static char new_tz[256]; #endif set_zone_directory("../../zoneinfo"); icaltimezone_set_tzid_prefix("/softwarestudio.org/"); timezones = icaltimezone_get_builtin_timezones(); utc_zone = icaltimezone_get_utc_timezone(); /* for all known time zones... */ for (i = 0; i < timezones->num_elements; i++) { zone = (icaltimezone *)icalarray_element_at(timezones, i); zone_location = (char *)icaltimezone_get_location(zone); if (!zone_location) continue; /* * select this location for glibc: needs support for TZ=<location> * which is not POSIX */ #if defined(HAVE_SETENV) setenv("TZ", zone_location, 1); #else new_tz[0] = '\0'; strncat(new_tz, "TZ=", 255); strncat(new_tz, zone_location, 255 - strlen(new_tz)); putenv(new_tz); #endif tzset(); /* * determine current local time and date: always use midday in * the current zone and first day of first month in the year */ start_time = time(NULL); localtime_r(&start_time, &start_tm); start_tm.tm_hour = 12; start_tm.tm_min = 0; start_tm.tm_sec = 0; start_tm.tm_mday = 1; start_tm.tm_mon = 0; start_time = mktime(&start_tm); /* check time conversion for the next 365 days */ for (day = 0, curr_time = start_time; day < 365; day++, curr_time += 24 * 60 * 60) { /* determine date/time with glibc */ localtime_r(&curr_time, &curr_tm); /* determine date/time with libical */ curr_tt = icaltime_from_timet_with_zone(curr_time, 0, utc_zone); curr_tt.zone = utc_zone; /* workaround: icaltime_from_timet_with_zone() should do this, but doesn't! */ curr_tt = icaltime_convert_to_zone(curr_tt, zone); /* compare... */ curr_failed = curr_tm.tm_year + 1900 != curr_tt.year || curr_tm.tm_mon + 1 != curr_tt.month || curr_tm.tm_mday != curr_tt.day || curr_tm.tm_hour != curr_tt.hour || curr_tm.tm_min != curr_tt.minute || curr_tm.tm_sec != curr_tt.second; /* only print first failed day and first day which is okay again */ if (verbose || curr_failed != failed) { struct tm utc_tm; if (!gmtime_r(&curr_time, &utc_tm)) memset(&utc_tm, 0, sizeof(utc_tm)); printf( "%s: day %03d: %s: %04d-%02d-%02d %02d:%02d:%02d UTC = " "libc %04d-%02d-%02d %02d:%02d:%02d dst %d", zone_location, day, verbose ? (curr_failed ? "failed" : "okay") : (curr_failed ? "first failed" : "okay again"), utc_tm.tm_year + 1900, utc_tm.tm_mon + 1, utc_tm.tm_mday, utc_tm.tm_hour, utc_tm.tm_min, utc_tm.tm_sec, curr_tm.tm_year + 1900, curr_tm.tm_mon + 1, curr_tm.tm_mday, curr_tm.tm_hour, curr_tm.tm_min, curr_tm.tm_sec, curr_tm.tm_isdst); if (curr_failed) { printf(" != libical %04d-%02d-%02d %02d:%02d:%02d dst %d", curr_tt.year, curr_tt.month, curr_tt.day, curr_tt.hour, curr_tt.minute, curr_tt.second, curr_tt.is_daylight); ret = 1; } printf("\n"); failed = curr_failed; if (!zonedef_printed) { icalcomponent *comp = icaltimezone_get_component(zone); if (comp) { printf("%s\n", icalcomponent_as_ical_string(comp)); } zonedef_printed = 1; } } if (curr_failed) { total_failed++; } else { total_okay++; } } } if (total_failed || total_okay) { percent_failed = total_failed * 100 / (total_failed + total_okay); printf(" *** Summary: %lu zones tested, %u days failed, %u okay => %u%% failed ***\n", (unsigned long)timezones->num_elements, total_failed, total_okay, percent_failed); if (!icaltzutil_get_exact_vtimezones_support()) { if (!percent_failed) { ret = 0; printf(" *** Expect some small error rate with inter-operable vtimezones *** \n"); } } } icaltimezone_free_builtin_timezones(); return ret; }
static gchar * system_timezone_find (void) { GHashTable *ical_zones; icalarray *builtin_timezones; gint ii; gchar *tz, *config_tz = NULL; /* return only timezones known to libical */ ical_zones = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); g_hash_table_insert (ical_zones, g_strdup ("UTC"), GINT_TO_POINTER (1)); builtin_timezones = icaltimezone_get_builtin_timezones (); for (ii = 0; ii < builtin_timezones->num_elements; ii++) { icaltimezone *zone; const gchar *location; zone = icalarray_element_at (builtin_timezones, ii); if (!zone) continue; location = icaltimezone_get_location (zone); if (location) g_hash_table_insert (ical_zones, g_strdup (location), GINT_TO_POINTER (1)); } /* softlink is the best option, it points to the correct file */ tz = system_timezone_read_etc_localtime_softlink (ical_zones); if (system_timezone_is_valid (tz, ical_zones)) { g_hash_table_destroy (ical_zones); return tz; } g_free (tz); config_tz = NULL; /* read correct timezone name from config file; checking * on /etc/localtime content can pick wrong timezone name, * even the file is same */ for (ii = 0; get_system_timezone_methods_config[ii] != NULL; ii++) { config_tz = get_system_timezone_methods_config[ii] (ical_zones); if (system_timezone_is_valid (config_tz, ical_zones)) { break; } g_free (config_tz); config_tz = NULL; } if (config_tz) { struct stat stat_localtime; gchar *localtime_content = NULL; gsize localtime_content_len = -1; if (g_stat (ETC_LOCALTIME, &stat_localtime) == 0 && S_ISREG (stat_localtime.st_mode) && g_file_get_contents (ETC_LOCALTIME, &localtime_content, &localtime_content_len, NULL)) { struct stat stat_config_tz; gchar *filename = g_build_filename (SYSTEM_ZONEINFODIR, config_tz, NULL); if (filename && g_stat (filename, &stat_config_tz) == 0 && files_are_identical_content (&stat_localtime, &stat_config_tz, localtime_content, localtime_content_len, filename)) { g_free (filename); g_free (localtime_content); g_hash_table_destroy (ical_zones); /* corresponding file name to config_tz matches /etc/localtime, * thus that's the correct one - return it as system timezone; * bonus is that it might match configured system timezone name too */ return config_tz; } g_free (filename); } g_free (localtime_content); } for (ii = 0; get_system_timezone_methods_slow[ii] != NULL; ii++) { tz = get_system_timezone_methods_slow[ii] (ical_zones); if (system_timezone_is_valid (tz, ical_zones)) { g_hash_table_destroy (ical_zones); g_free (config_tz); return tz; } g_free (tz); } g_hash_table_destroy (ical_zones); return config_tz; }
int main(int argc, char* argv[]) { icalarray *zones; icaltimezone *zone; char *zone_directory, *zone_subdirectory, *zone_filename, *location; char output_directory[PATHNAME_BUFFER_SIZE]; char filename[PATHNAME_BUFFER_SIZE]; FILE *fp; int i; int skipping = TRUE; /* * Command-Line Option Parsing. */ for (i = 1; i < argc; i++) { /* --dump-changes: Dumps a list of times when each timezone changed, and the new local time offset from UTC. */ if (!strcmp (argv[i], "--dump-changes")) VzicDumpChanges = TRUE; else usage (); } zones = icaltimezone_get_builtin_timezones (); ensure_directory_exists (directory); for (i = 0; i < zones->num_elements; i++) { zone = icalarray_element_at (zones, i); location = icaltimezone_get_location (zone); #if 0 /* Use this to start at a certain zone. */ if (skipping && strcmp (location, "America/Boise")) continue; #endif skipping = FALSE; /* Use this to only output data for certain timezones. */ #if 0 if (strcmp (location, "America/Cancun") && strcmp (location, "Asia/Baku") && strcmp (location, "Asia/Nicosia") && strcmp (location, "Asia/Novosibirsk") && strcmp (location, "Asia/Samarkand") && strcmp (location, "Asia/Tashkent") && strcmp (location, "Asia/Tbilisi") && strcmp (location, "Asia/Yerevan") && strcmp (location, "Australia/Broken_Hill") && strcmp (location, "Europe/Simferopol") && strcmp (location, "Europe/Tallinn") && strcmp (location, "Europe/Zaporozhye") ) continue; #endif #if 0 printf ("%s\n", location); #endif parse_zone_name (location, &zone_directory, &zone_subdirectory, &zone_filename); sprintf (output_directory, "%s/%s", directory, zone_directory); ensure_directory_exists (output_directory); sprintf (filename, "%s/%s", output_directory, zone_filename); if (zone_subdirectory) { sprintf (output_directory, "%s/%s/%s", directory, zone_directory, zone_subdirectory); ensure_directory_exists (output_directory); sprintf (filename, "%s/%s", output_directory, zone_filename); } fp = fopen (filename, "w"); if (!fp) { fprintf (stderr, "Couldn't create file: %s\n", filename); exit (1); } /* We can run 2 different tests - output all changes for each zone, or test against mktime()/localtime(). Should have a command-line option or something. */ if (VzicDumpChanges) icaltimezone_dump_changes (zone, CHANGES_MAX_YEAR, fp); else dump_local_times (zone, fp); if (ferror (fp)) { fprintf (stderr, "Error writing file: %s\n", filename); exit (1); } fclose (fp); } return 0; }
static void dump_local_times (icaltimezone *zone, FILE *fp) { static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; icaltimezone *utc_timezone; struct icaltimetype tt, tt_copy; struct tm tm, local_tm; time_t t; char tzstring[256], *location; int last_year_output = 0; int total_error = 0, total_error2 = 0; utc_timezone = icaltimezone_get_utc_timezone (); /* This is our UTC time that we will use to iterate over the period. */ tt.year = DUMP_START_YEAR; tt.month = 1; tt.day = 1; tt.hour = 0; tt.minute = 0; tt.second = 0; tt.is_utc = 0; tt.is_date = 0; tt.zone = ""; tm.tm_year = tt.year - 1900; tm.tm_mon = tt.month - 1; tm.tm_mday = tt.day; tm.tm_hour = tt.hour; tm.tm_min = tt.minute; tm.tm_sec = tt.second; tm.tm_isdst = -1; /* Convert it to a time_t by saying it is in UTC. */ putenv ("TZ=UTC"); t = mktime (&tm); location = icaltimezone_get_location (zone); sprintf (tzstring, "TZ=%s", location); /*printf ("Zone: %s\n", location);*/ putenv (tzstring); /* Loop around converting the UTC time to local time, outputting it, and then adding on 15 minutes to the UTC time. */ while (tt.year <= DUMP_END_YEAR) { if (tt.year > last_year_output) { last_year_output = tt.year; #if 0 printf (" %i\n", last_year_output); fprintf (fp, " %i\n", last_year_output); #endif } #if 1 /* First use the Unix functions. */ /* Now convert it to a local time in the given timezone. */ local_tm = *localtime (&t); #endif #if 1 /* Now use libical. */ tt_copy = tt; icaltimezone_convert_time (&tt_copy, utc_timezone, zone); #endif #if 1 if (local_tm.tm_year + 1900 != tt_copy.year || local_tm.tm_mon + 1 != tt_copy.month || local_tm.tm_mday != tt_copy.day || local_tm.tm_hour != tt_copy.hour || local_tm.tm_min != tt_copy.minute || local_tm.tm_sec != tt_copy.second) { /* The error format is: ERROR: Original-UTC-Time Local-Time-From-mktime Local-Time-From-Libical */ total_error++; fprintf (fp, "ERROR:%2i %s %04i %2i:%02i:%02i UTC", tt.day, months[tt.month - 1], tt.year, tt.hour, tt.minute, tt.second); fprintf (fp, " ->%2i %s %04i %2i:%02i:%02i", local_tm.tm_mday, months[local_tm.tm_mon], local_tm.tm_year + 1900, local_tm.tm_hour, local_tm.tm_min, local_tm.tm_sec); fprintf (fp, " Us:%2i %s %04i %2i:%02i:%02i\n", tt_copy.day, months[tt_copy.month - 1], tt_copy.year, tt_copy.hour, tt_copy.minute, tt_copy.second); } #endif /* Now convert it back, and check we get the original time. */ icaltimezone_convert_time (&tt_copy, zone, utc_timezone); if (tt.year != tt_copy.year || tt.month != tt_copy.month || tt.day != tt_copy.day || tt.hour != tt_copy.hour || tt.minute != tt_copy.minute || tt.second != tt_copy.second) { total_error2++; fprintf (fp, "ERROR 2: %2i %s %04i %2i:%02i:%02i UTC", tt.day, months[tt.month - 1], tt.year, tt.hour, tt.minute, tt.second); fprintf (fp, " Us:%2i %s %04i %2i:%02i:%02i UTC\n", tt_copy.day, months[tt_copy.month - 1], tt_copy.year, tt_copy.hour, tt_copy.minute, tt_copy.second); } /* Increment the time. */ icaltime_adjust (&tt, 0, 0, 15, 0); /* We assume leap seconds are not included in time_t values, which should be true on POSIX systems. */ t += 15 * 60; } printf ("Zone: %40s Errors: %i (%i)\n", icaltimezone_get_location (zone), total_error, total_error2); }