/** 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;
}
示例#2
0
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);
}
示例#3
0
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;
}
示例#4
0
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);
}
示例#5
0
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);
}
示例#6
0
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);
}
示例#7
0
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;
}
示例#9
0
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;
}
示例#10
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);
}