calDateTime::ToIcalTime(struct icaltimetype * icalt) { icalt->year = mYear; icalt->month = mMonth + 1; icalt->day = mDay; icalt->hour = mHour; icalt->minute = mMinute; icalt->second = mSecond; icalt->is_date = mIsDate ? 1 : 0; icalt->is_daylight = 0; icaltimezone * tz = cal::getIcalTimezone(mTimezone); icalt->zone = tz; icalt->is_utc = (tz && tz == icaltimezone_get_utc_timezone()); icalt->is_daylight = 0; // xxx todo: discuss/investigate is_daylight // if (tz) { // icaltimezone_get_utc_offset(tz, icalt, &icalt->is_daylight); // } }
static void get_revision_compare_cycle (ECalClient *client) { icalcomponent *icalcomp; struct icaltimetype now; gchar *revision_before = NULL, *revision_after = NULL, *uid = NULL; GError *error = NULL; /* Build up new component */ now = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ()); icalcomp = icalcomponent_new (ICAL_VEVENT_COMPONENT); icalcomponent_set_summary (icalcomp, "Test event summary"); icalcomponent_set_dtstart (icalcomp, now); icalcomponent_set_dtend (icalcomp, icaltime_from_timet (icaltime_as_timet (now) + 60 * 60 * 60, 0)); if (!e_client_get_backend_property_sync (E_CLIENT (client), CLIENT_BACKEND_PROPERTY_REVISION, &revision_before, NULL, &error)) g_error ("Error getting book revision: %s", error->message); if (!e_cal_client_create_object_sync (client, icalcomp, &uid, NULL, &error)) g_error ("Error creating object: %s", error->message); if (!e_client_get_backend_property_sync (E_CLIENT (client), CLIENT_BACKEND_PROPERTY_REVISION, &revision_after, NULL, &error)) g_error ("Error getting book revision: %s", error->message); g_assert (revision_before); g_assert (revision_after); g_assert (strcmp (revision_before, revision_after) != 0); g_message ("Passed cycle, revision before '%s' revision after '%s'", revision_before, revision_after); g_free (revision_before); g_free (revision_after); g_free (uid); icalcomponent_free (icalcomp); }
/* Converts a time_t to a string, relative to the specified timezone */ static gchar * timet_to_str_with_zone (ECalComponentDateTime *dt, ECalClient *client, icaltimezone *default_zone) { struct icaltimetype itt; icaltimezone *zone = NULL; struct tm tm; if (dt->tzid != NULL) { e_cal_client_get_timezone_sync ( client, dt->tzid, &zone, NULL, NULL); } else if (dt->value->is_utc) { zone = icaltimezone_get_utc_timezone (); } itt = *dt->value; if (zone != NULL) icaltimezone_convert_time (&itt, zone, default_zone); tm = icaltimetype_to_tm (&itt); return e_datetime_format_format_tm ("calendar", "table", itt.is_date ? DTFormatKindDate : DTFormatKindDateTime, &tm); }
static gchar * create_object (ECalClient *cal_client) { icalcomponent *icalcomp; struct icaltimetype now; gchar *uid = NULL; GError *error = NULL; g_return_val_if_fail (cal_client != NULL, NULL); now = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ()); icalcomp = icalcomponent_new (ICAL_VEVENT_COMPONENT); icalcomponent_set_summary (icalcomp, "To-be-removed event summary"); icalcomponent_set_dtstart (icalcomp, now); icalcomponent_set_dtend (icalcomp, icaltime_from_timet_with_zone (icaltime_as_timet (now) + 60 * 60 * 60, 0, NULL)); if (!e_cal_client_create_object_sync (cal_client, icalcomp, &uid, NULL, &error)) g_error ("create object sync: %s", error->message); icalcomponent_free (icalcomp); return uid; }
/** @brief Constructor. * * @param tm The time * @param is_date Boolean: 1 means we should treat tm as a DATE * @param zone The timezone tm is in, NULL means to treat tm as a * floating time * * Return a new icaltime instance, initialized to the given time * expressed as seconds past UNIX epoch, optionally using the given * timezone. * * If the caller specifies the is_date param as TRUE, the returned * object is of DATE type, otherwise the input is meant to be of * DATE-TIME type. * If the zone is not specified (NULL zone param) the time is taken * to be floating, that is, valid in any timezone. Note that, in * addition to the uses specified in [RFC5545], this can be used * when doing simple math on couples of times. * If the zone is specified (UTC or otherwise), it's stored in the * object and it's used as the native timezone for this object. * This means that the caller can convert this time to a different * target timezone with no need to store the source timezone. * */ struct icaltimetype icaltime_from_timet_with_zone(const time_t tm, const int is_date, const icaltimezone *zone) { struct icaltimetype tt; struct tm t; icaltimezone *utc_zone; utc_zone = icaltimezone_get_utc_timezone(); /* Convert the time_t to a struct tm in UTC time. We can trust gmtime for this. */ gmtime_r(&tm, &t); 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_daylight = 0; tt.zone = NULL; /* Use our timezone functions to convert to the required timezone. */ icaltimezone_convert_time(&tt, utc_zone, (icaltimezone *) zone); tt.is_date = is_date; /* If it is a DATE value, make sure hour, minute & second are 0. */ if (is_date) { tt.hour = 0; tt.minute = 0; tt.second = 0; } return tt; }
/** Return the time as seconds past the UNIX epoch, using the * given timezone. * * This convenience method combines a call to icaltime_convert_to_zone() * with a call to icaltime_as_timet(). * If the input timezone is null, no conversion is done; that is, the * time is simply returned as time_t in its native timezone. */ time_t icaltime_as_timet_with_zone(const struct icaltimetype tt, const icaltimezone *zone) { icaltimezone *utc_zone; struct tm stm; time_t t; struct icaltimetype local_tt; utc_zone = icaltimezone_get_utc_timezone(); /* If the time is the special null time, return 0. */ if (icaltime_is_null_time(tt)) { return 0; } local_tt = tt; /* Clear the is_date flag, so we can convert the time. */ local_tt.is_date = 0; /* Use our timezone functions to convert to UTC. */ icaltimezone_convert_time(&local_tt, (icaltimezone *) zone, utc_zone); /* Copy the icaltimetype to a struct tm. */ memset(&stm, 0, sizeof(struct tm)); stm.tm_sec = local_tt.second; stm.tm_min = local_tt.minute; stm.tm_hour = local_tt.hour; stm.tm_mday = local_tt.day; stm.tm_mon = local_tt.month - 1; stm.tm_year = local_tt.year - 1900; stm.tm_isdst = -1; t = icaltime_timegm(&stm); return t; }
NS_IMETHODIMP calDateTime::GetInTimezone(calITimezone * aTimezone, calIDateTime ** aResult) { NS_ENSURE_ARG_POINTER(aTimezone); NS_ENSURE_ARG_POINTER(aResult); if (mIsDate) { // if it's a date, we really just want to make a copy of this // and set the timezone. nsresult rv = Clone(aResult); if (NS_SUCCEEDED(rv)) { rv = (*aResult)->SetTimezone(aTimezone); } return rv; } else { icaltimetype icalt; ToIcalTime(&icalt); icaltimezone * tz = cal::getIcalTimezone(aTimezone); if (icalt.zone == tz) { return Clone(aResult); } /* If there's a zone, we need to convert; otherwise, we just * assign, since this item is floating */ if (icalt.zone && tz) { icaltimezone_convert_time(&icalt, const_cast<icaltimezone *>(icalt.zone), tz); } icalt.zone = tz; icalt.is_utc = (tz && tz == icaltimezone_get_utc_timezone()); calDateTime * cdt = new calDateTime(&icalt, aTimezone); CAL_ENSURE_MEMORY(cdt); NS_ADDREF (*aResult = cdt); return NS_OK; } }
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); }
icalsetiter icalbdbset_begin_component(icalset *set, icalcomponent_kind kind, icalgauge *gauge, const char *tzid) { icalsetiter itr = icalsetiter_null; icalcomponent *comp = NULL; icalcompiter citr; icalbdbset *bset; struct icaltimetype start, next; icalproperty *dtstart, *rrule, *prop, *due; struct icalrecurrencetype recur; icaltimezone *u_zone; int g = 0; int orig_time_was_utc = 0; icalerror_check_arg_re((set != 0), "set", icalsetiter_null); bset = (icalbdbset *) set; itr.gauge = gauge; itr.tzid = tzid; citr = icalcomponent_begin_component(bset->cluster, kind); comp = icalcompiter_deref(&citr); if (gauge == 0) { itr.iter = citr; return itr; } /* if there is a gauge, the first matched component is returned */ while (comp != 0) { /* check if it is a recurring component and with guage expand, if so * we need to add recurrence-id property to the given component */ rrule = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY); g = icalgauge_get_expand(gauge); if (rrule != 0 && g == 1) { /* it is a recurring event */ u_zone = icaltimezone_get_builtin_timezone(itr.tzid); /* use UTC, if that's all we have. */ if (!u_zone) { u_zone = icaltimezone_get_utc_timezone(); } recur = icalproperty_get_rrule(rrule); start = icaltime_from_timet(time(0), 0); if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) { dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY); if (dtstart) { start = icalproperty_get_dtstart(dtstart); } } else if (icalcomponent_isa(comp) == ICAL_VTODO_COMPONENT) { due = icalcomponent_get_first_property(comp, ICAL_DUE_PROPERTY); if (due) { start = icalproperty_get_due(due); } } /* Convert to the user's timezone in order to be able to compare * the results from the rrule iterator. */ if (icaltime_is_utc(start)) { start = icaltime_convert_to_zone(start, u_zone); orig_time_was_utc = 1; } if (itr.last_component == NULL) { itr.ritr = icalrecur_iterator_new(recur, start); next = icalrecur_iterator_next(itr.ritr); itr.last_component = comp; } else { next = icalrecur_iterator_next(itr.ritr); if (icaltime_is_null_time(next)) { itr.last_component = NULL; icalrecur_iterator_free(itr.ritr); itr.ritr = NULL; /* no matched occurrence */ goto getNextComp; } else { itr.last_component = comp; } } /* if it is excluded, do next one */ if (icalproperty_recurrence_is_excluded(comp, &start, &next)) { next = icalrecur_iterator_next(itr.ritr); continue; } /* add recurrence-id value to the property if the property already exist; * add the recurrence id property and the value if the property does not exist */ prop = icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY); if (prop == 0) { icalcomponent_add_property(comp, icalproperty_new_recurrenceid(next)); } else { icalproperty_set_recurrenceid(prop, next); } /* convert the next recurrence time into the user's timezone */ if (orig_time_was_utc) { next = icaltime_convert_to_zone(next, icaltimezone_get_utc_timezone()); } } /* end of a recurring event */ if (gauge == 0 || icalgauge_compare(itr.gauge, comp) == 1) { /* find a matched and return it */ itr.iter = citr; return itr; } /* if it is a recurring but no matched occurrence has been found OR * it is not a recurring and no matched component has been found, * read the next component to find out */ getNextComp: if ((rrule != NULL && itr.last_component == NULL) || (rrule == NULL)) { (void)icalcompiter_next(&citr); comp = icalcompiter_deref(&citr); } } /* while */ /* no matched component has found */ return icalsetiter_null; }
static void set_itip_view (SunOneInvitationList *list, int row) { SunOneInvitationListPrivate *priv = list->priv; ECalComponent *comp; ECalComponentText text; const char *string; ECalComponentDateTime datetime; GString *gstring = NULL; GSList *description_list, *l; SunOneItipView *itip_view; ECalComponentOrganizer organizer; if (row == -1) { if (GTK_WIDGET_VISIBLE (priv->control)) gtk_widget_hide (priv->control); return; } comp = sunone_invitation_list_model_get_comp (priv->model, row); if (!comp) return; itip_view = (SunOneItipView *)priv->control; sunone_itip_view_set_mode (itip_view, SUNONE_ITIP_VIEW_MODE_REQUEST); sunone_itip_view_set_item_type (itip_view, E_CAL_SOURCE_TYPE_EVENT); e_cal_component_get_organizer (comp, &organizer); sunone_itip_view_set_organizer (itip_view, organizer.cn ? organizer.cn : itip_strip_mailto (organizer.value)); sunone_itip_view_set_sentby (itip_view, organizer.sentby); e_cal_component_get_summary (comp, &text); sunone_itip_view_set_summary (itip_view, text.value ? text.value : _("None")); e_cal_component_get_location (comp, &string); sunone_itip_view_set_location (itip_view, string); e_cal_component_get_description_list (comp, &description_list); for (l = description_list; l; l = l->next) { ECalComponentText *text = l->data; if (!gstring && text->value) gstring = g_string_new (text->value); else if (text->value) g_string_append_printf (gstring, "\n\n%s", text->value); } e_cal_component_free_text_list (description_list); if (gstring) { sunone_itip_view_set_description (itip_view, gstring->str); g_string_free (gstring, TRUE); } else sunone_itip_view_set_description (itip_view, NULL); e_cal_component_get_dtstart (comp, &datetime); if (datetime.value) { struct tm start_tm; start_tm = icaltimetype_to_tm_with_zone (datetime.value, icaltimezone_get_utc_timezone (), priv->model->zone); sunone_itip_view_set_start (itip_view, &start_tm); } e_cal_component_free_datetime (&datetime); e_cal_component_get_dtend (comp, &datetime); if (datetime.value) { struct tm end_tm; end_tm = icaltimetype_to_tm_with_zone (datetime.value, icaltimezone_get_utc_timezone (), priv->model->zone); sunone_itip_view_set_end (itip_view, &end_tm); } e_cal_component_free_datetime (&datetime); /* Recurrence info */ sunone_itip_view_clear_upper_info_items (itip_view); if (e_cal_component_has_recurrences (comp)) { sunone_itip_view_add_upper_info_item (itip_view, SUNONE_ITIP_VIEW_INFO_ITEM_TYPE_INFO, "This meeting recurs"); } sunone_itip_view_set_status (itip_view, NULL); sunone_itip_view_set_comment (itip_view, NULL); sunone_itip_view_set_show_rsvp (itip_view, FALSE); if (!GTK_WIDGET_VISIBLE (priv->control)) gtk_widget_show (priv->control); }
/** @brief Contructor. * * Create a time from an ISO format string. * * @todo If the given string specifies a DATE-TIME not in UTC, there * is no way to know if this is a floating time or really refers to a * timezone. We should probably add a new constructor: * icaltime_from_string_with_zone() */ struct icaltimetype icaltime_from_string(const char *str) { struct icaltimetype tt = icaltime_null_time(); size_t size; icalerror_check_arg_re(str != 0, "str", icaltime_null_time()); size = strlen(str); if ((size == 15) || (size == 19)) { /* floating time with/without separators */ tt.is_utc = 0; tt.is_date = 0; } else if ((size == 16) || (size == 20)) { /* UTC time, ends in 'Z' */ if ((str[15] != 'Z') && (str[19] != 'Z')) goto FAIL; tt.is_utc = 1; tt.zone = icaltimezone_get_utc_timezone(); tt.is_date = 0; } else if ((size == 8) || (size == 10)) { /* A DATE */ tt.is_utc = 0; tt.is_date = 1; } else { /* error */ goto FAIL; } if (tt.is_date == 1) { if (size == 10) { char dsep1, dsep2; if (sscanf(str, "%04d%c%02d%c%02d", &tt.year, &dsep1, &tt.month, &dsep2, &tt.day) < 5) { goto FAIL; } if ((dsep1 != '-') || (dsep2 != '-')) { goto FAIL; } } else if (sscanf(str, "%04d%02d%02d", &tt.year, &tt.month, &tt.day) < 3) { goto FAIL; } } else { if (size > 16) { char dsep1, dsep2, tsep, tsep1, tsep2; if (sscanf(str, "%04d%c%02d%c%02d%c%02d%c%02d%c%02d", &tt.year, &dsep1, &tt.month, &dsep2, &tt.day, &tsep, &tt.hour, &tsep1, &tt.minute, &tsep2, &tt.second) < 11) { goto FAIL; } if ((tsep != 'T') || (dsep1 != '-') || (dsep2 != '-') || (tsep1 != ':') || (tsep2 != ':')) { goto FAIL; } } else { char tsep; if (sscanf(str, "%04d%02d%02d%c%02d%02d%02d", &tt.year, &tt.month, &tt.day, &tsep, &tt.hour, &tt.minute, &tt.second) < 7) { goto FAIL; } if (tsep != 'T') { goto FAIL; } } } return tt; FAIL: icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return icaltime_null_time(); }
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); }
static ECalComponent * comp_from_remote_record (GnomePilotConduitSyncAbs *conduit, GnomePilotRecord *remote, ECalComponent *in_comp, icaltimezone *timezone, struct MemoAppInfo *ai) { ECalComponent *comp; struct Memo memo; struct icaltimetype now; icaltimezone *utc_zone; char *txt, *txt2, *txt3; int i; #ifdef PILOT_LINK_0_12 pi_buffer_t * buffer; #endif g_return_val_if_fail (remote != NULL, NULL); #ifdef PILOT_LINK_0_12 buffer = pi_buffer_new(DLP_BUF_SIZE); if(buffer == NULL){ return NULL; } if(pi_buffer_append(buffer, remote->record, remote->length)==NULL){ return NULL; } unpack_Memo (&memo, buffer, memo_v1); pi_buffer_free(buffer); #else memset (&memo, 0, sizeof (struct Memo)); unpack_Memo (&memo, remote->record, remote->length); #endif utc_zone = icaltimezone_get_utc_timezone (); now = icaltime_from_timet_with_zone (time (NULL), FALSE, utc_zone); if (in_comp == NULL) { comp = e_cal_component_new (); e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_JOURNAL); e_cal_component_set_created (comp, &now); } else { comp = e_cal_component_clone (in_comp); } e_cal_component_set_last_modified (comp, &now); /*Category support*/ e_pilot_remote_category_to_local(remote->category, comp, &(ai->category)); /* The iCal description field */ if (!memo.text) { e_cal_component_set_comment_list (comp, NULL); e_cal_component_set_summary(comp, NULL); } else { int idxToUse = -1, ntext = strlen(memo.text); gboolean foundNL = FALSE; GSList l; ECalComponentText text, sumText; for(i = 0; i<ntext && i<50; i++){ if(memo.text[i] == '\n'){ idxToUse = i; foundNL = TRUE; break; } } if(foundNL == FALSE){ if(ntext > 50){ txt2 = g_strndup(memo.text, 50); } else{ txt2 = g_strdup(memo.text); } } else{ txt2 = g_strndup(memo.text, idxToUse); /* cuts off '\n' */ } sumText.value = txt3 = e_pilot_utf8_from_pchar(txt2); sumText.altrep = NULL; text.value = txt = e_pilot_utf8_from_pchar (memo.text); text.altrep = NULL; l.data = &text; l.next = NULL; e_cal_component_set_summary(comp, &sumText); e_cal_component_set_description_list (comp, &l); free (txt); g_free(txt2); free(txt3); } e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_NONE); if (remote->secret) e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PRIVATE); else e_cal_component_set_classification (comp, E_CAL_COMPONENT_CLASS_PUBLIC); e_cal_component_commit_sequence (comp); free_Memo(&memo); return comp; }
/** * e_cal_util_get_component_occur_times: * @comp: an #ECalComponent * @start: (out): Location to store the start time * @end: (out): Location to store the end time * @tz_cb: (closure tz_cb_data) (scope call): The #ECalRecurResolveTimezoneFn to call * @tz_cb_data: (closure): User data to be passed to the @tz_cb callback * @default_timezone: The default timezone * @kind: the type of component, indicated with an icalcomponent_kind * * Find out when the component starts and stops, being careful about * recurrences. * * Since: 2.32 **/ void e_cal_util_get_component_occur_times (ECalComponent *comp, time_t *start, time_t *end, ECalRecurResolveTimezoneFn tz_cb, gpointer tz_cb_data, const icaltimezone *default_timezone, icalcomponent_kind kind) { struct icalrecurrencetype ir; ECalComponentDateTime dt_start, dt_end; g_return_if_fail (comp != NULL); g_return_if_fail (start != NULL); g_return_if_fail (end != NULL); e_cal_recur_ensure_end_dates (comp, FALSE, tz_cb, tz_cb_data); /* Get dtstart of the component and convert it to UTC */ e_cal_component_get_dtstart (comp, &dt_start); if ((*start = componenttime_to_utc_timet (&dt_start, tz_cb, tz_cb_data, default_timezone)) == -1) *start = _TIME_MIN; e_cal_component_free_datetime (&dt_start); /* find out end date of component */ *end = _TIME_MAX; if (kind == ICAL_VTODO_COMPONENT) { /* max from COMPLETED and DUE properties */ struct icaltimetype *tt = NULL; time_t completed_time = -1, due_time = -1, max_time; ECalComponentDateTime dt_due; e_cal_component_get_completed (comp, &tt); if (tt) { /* COMPLETED must be in UTC. */ completed_time = icaltime_as_timet_with_zone ( *tt, icaltimezone_get_utc_timezone ()); e_cal_component_free_icaltimetype (tt); } e_cal_component_get_due (comp, &dt_due); if (dt_due.value != NULL) due_time = componenttime_to_utc_timet ( &dt_due, tz_cb, tz_cb_data, default_timezone); e_cal_component_free_datetime (&dt_due); max_time = MAX (completed_time, due_time); if (max_time != -1) *end = max_time; } else { /* ALARMS, EVENTS: DTEND and reccurences */ if (e_cal_component_has_recurrences (comp)) { GSList *rrules = NULL; GSList *exrules = NULL; GSList *elem; GSList *rdates = NULL; /* Do the RRULEs, EXRULEs and RDATEs*/ e_cal_component_get_rrule_property_list (comp, &rrules); e_cal_component_get_exrule_property_list (comp, &exrules); e_cal_component_get_rdate_list (comp, &rdates); for (elem = rrules; elem; elem = elem->next) { time_t rule_end; icaltimezone *utc_zone; icalproperty *prop = elem->data; ir = icalproperty_get_rrule (prop); utc_zone = icaltimezone_get_utc_timezone (); rule_end = e_cal_recur_obtain_enddate ( &ir, prop, utc_zone, TRUE); if (rule_end == -1) /* repeats forever */ *end = _TIME_MAX; else if (rule_end > *end) /* new maximum */ *end = rule_end; } /* Do the EXRULEs. */ for (elem = exrules; elem; elem = elem->next) { icalproperty *prop = elem->data; time_t rule_end; icaltimezone *utc_zone; ir = icalproperty_get_exrule (prop); utc_zone = icaltimezone_get_utc_timezone (); rule_end = e_cal_recur_obtain_enddate ( &ir, prop, utc_zone, TRUE); if (rule_end == -1) /* repeats forever */ *end = _TIME_MAX; else if (rule_end > *end) *end = rule_end; } /* Do the RDATEs */ for (elem = rdates; elem; elem = elem->next) { ECalComponentPeriod *p = elem->data; time_t rdate_end = _TIME_MAX; /* FIXME: We currently assume RDATEs are in the same timezone * as DTSTART. We should get the RDATE timezone and convert * to the DTSTART timezone first. */ /* Check if the end date or duration is set, libical seems to set * second to -1 to denote an unset time */ if (p->type != E_CAL_COMPONENT_PERIOD_DATETIME || p->u.end.second != -1) rdate_end = icaltime_as_timet (icaltime_add (p->start, p->u.duration)); else rdate_end = icaltime_as_timet (p->u.end); if (rdate_end == -1) /* repeats forever */ *end = _TIME_MAX; else if (rdate_end > *end) *end = rdate_end; } e_cal_component_free_period_list (rdates); } /* Get dtend of the component and convert it to UTC */ e_cal_component_get_dtend (comp, &dt_end); if (dt_end.value) { time_t dtend_time; dtend_time = componenttime_to_utc_timet ( &dt_end, tz_cb, tz_cb_data, default_timezone); if (dtend_time == -1 || (dtend_time > *end)) *end = dtend_time; } e_cal_component_free_datetime (&dt_end); } }
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); }
static gboolean write_calendar (gchar *uid, ESourceList *source_list, GOutputStream *stream) { ESource *source; ECal *client = NULL; GError *error = NULL; GList *objects; icaltimezone *utc; time_t start = time(NULL), end; icalcomponent *top_level; char *email = NULL; GList *users = NULL; gboolean res = FALSE; utc = icaltimezone_get_utc_timezone (); start = time_day_begin_with_zone (start, utc); end = time_add_week_with_zone (start, 6, utc); source = e_source_list_peek_source_by_uid (source_list, uid); if (source) client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT); if (!client) { g_warning (G_STRLOC ": Could not publish calendar: Calendar backend no longer exists"); return FALSE; } if (!e_cal_open (client, TRUE, &error)) { if (error) { g_warning ("%s", error->message); g_error_free (error); } g_object_unref (client); return FALSE; } if (e_cal_get_cal_address (client, &email, &error)) { if (email && *email) users = g_list_append (users, email); } top_level = e_cal_util_new_top_level (); error = NULL; if (e_cal_get_free_busy (client, users, start, end, &objects, &error)) { char *ical_string; while (objects) { ECalComponent *comp = objects->data; icalcomponent *icalcomp = e_cal_component_get_icalcomponent (comp); icalcomponent_add_component (top_level, icalcomp); objects = g_list_remove (objects, comp); } ical_string = icalcomponent_as_ical_string (top_level); res = g_output_stream_write_all (stream, ical_string, strlen (ical_string), NULL, NULL, &error); g_free (ical_string); } if (users) g_list_free (users); g_free (email); g_object_unref (client); if (error) { g_warning ("%s", error->message); g_error_free (error); } return res; }
// utility function to create a VCALENDAR from a single RideItem static icalcomponent *createEvent(RideItem *rideItem) { // calendar icalcomponent *root = icalcomponent_new(ICAL_VCALENDAR_COMPONENT); // calendar version icalproperty *version = icalproperty_new_version("2.0"); icalcomponent_add_property(root, version); icalcomponent *event = icalcomponent_new(ICAL_VEVENT_COMPONENT); // // Unique ID // QString id = rideItem->ride()->id(); if (id == "") { id = QUuid::createUuid().toString() + "@" + "goldencheetah.org"; } icalproperty *uid = icalproperty_new_uid(id.toLatin1()); icalcomponent_add_property(event, uid); // // START DATE // struct icaltimetype atime; QDateTime utc = QDateTime::currentDateTime().toUTC(); atime.year = utc.date().year(); atime.month = utc.date().month(); atime.day = utc.date().day(); atime.hour = utc.time().hour(); atime.minute = utc.time().minute(); atime.second = utc.time().second(); // this is UTC is_utc is redundant but kept for completeness atime.is_utc = 1; atime.is_date = 0; // this is a date AND time atime.is_daylight = 0; // no daylight savings - its UTC atime.zone = icaltimezone_get_utc_timezone(); // set UTC timezone icalproperty *dtstart = icalproperty_new_dtstart(atime); icalcomponent_add_property(event, dtstart); // // Duration // // override values? QMap<QString, QString> lookup; lookup = rideItem->ride()->metricOverrides.value("workout_time"); int secs = lookup.value("value", "0.0").toDouble(); // from last - first timestamp? if (!rideItem->ride()->datePoints().isEmpty() && rideItem->ride()->datePoints().last() != NULL) { if (!secs) { secs = rideItem->ride()->datePoints().last()->secs; } } // ok, got seconds so now create in vcard struct icaldurationtype dur; dur.is_neg = 0; dur.days = dur.weeks = 0; dur.hours = secs / 3600; dur.minutes = secs % 3600 / 60; dur.seconds = secs % 60; icalcomponent_set_duration(event, dur); // set title & description QString title = rideItem->ride()->getTag("Title", ""); if (title == "") { title = rideItem->ride()->getTag("Sport", "") + " Workout"; } icalcomponent_set_summary(event, title.toLatin1()); icalcomponent_set_description(event, rideItem->ride()->getTag("Calendar Text", "").toLatin1()); // put the event into root icalcomponent_add_component(root, event); return root; }
icalcomponent *icalbdbset_form_a_matched_recurrence_component(icalsetiter *itr) { icalcomponent *comp = NULL; struct icaltimetype start, next; icalproperty *dtstart, *rrule, *prop, *due; struct icalrecurrencetype recur; icaltimezone *u_zone; int orig_time_was_utc = 0; comp = itr->last_component; if (comp == NULL || itr->gauge == NULL) { return NULL; } rrule = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY); /* if there is no RRULE, simply return to the caller */ if (rrule == NULL) { return NULL; } u_zone = icaltimezone_get_builtin_timezone(itr->tzid); /* use UTC, if that's all we have. */ if (!u_zone) { u_zone = icaltimezone_get_utc_timezone(); } recur = icalproperty_get_rrule(rrule); start = icaltime_from_timet(time(0), 0); if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) { dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY); if (dtstart) { start = icalproperty_get_dtstart(dtstart); } } else if (icalcomponent_isa(comp) == ICAL_VTODO_COMPONENT) { due = icalcomponent_get_first_property(comp, ICAL_DUE_PROPERTY); if (due) { start = icalproperty_get_due(due); } } /* Convert to the user's timezone in order to be able to compare the results * from the rrule iterator. */ if (icaltime_is_utc(start)) { start = icaltime_convert_to_zone(start, u_zone); orig_time_was_utc = 1; } if (itr->ritr == NULL) { itr->ritr = icalrecur_iterator_new(recur, start); next = icalrecur_iterator_next(itr->ritr); itr->last_component = comp; } else { next = icalrecur_iterator_next(itr->ritr); if (icaltime_is_null_time(next)) { /* no more recurrence, returns */ itr->last_component = NULL; icalrecur_iterator_free(itr->ritr); itr->ritr = NULL; /* no more pending matched occurrence, * all the pending matched occurrences have been returned */ return NULL; } else { itr->last_component = comp; } } /* if it is excluded, return NULL to the caller */ if (icalproperty_recurrence_is_excluded(comp, &start, &next)) { (void)icalrecur_iterator_next(itr->ritr); return NULL; } /* set recurrence-id value to the property if the property already exist; * add the recurrence id property and the value if the property does not exist */ prop = icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY); if (prop == 0) { icalcomponent_add_property(comp, icalproperty_new_recurrenceid(next)); } else { icalproperty_set_recurrenceid(prop, next); } if (orig_time_was_utc) { next = icaltime_convert_to_zone(next, icaltimezone_get_utc_timezone()); } if (itr->gauge == 0 || icalgauge_compare(itr->gauge, comp) == 1) { /* find a matched and return it */ return comp; } /* not matched */ return NULL; }
int* icalspanlist_as_freebusy_matrix(icalspanlist* sl, int delta_t) { pvl_elem itr; int spanduration_secs; int *matrix; int matrix_slots; time_t sl_start, sl_end; icalerror_check_arg_rz( (sl!=0), "spanlist"); if (!delta_t) delta_t = 3600; /** calculate the start and end time as time_t **/ sl_start = icaltime_as_timet_with_zone(sl->start, icaltimezone_get_utc_timezone()); sl_end = icaltime_as_timet_with_zone(sl->end, icaltimezone_get_utc_timezone()); /** insure that the time period falls on a time boundary divisable by delta_t */ sl_start /= delta_t; sl_start *= delta_t; sl_end /= delta_t; sl_end *= delta_t; /** find the duration of this spanlist **/ spanduration_secs = sl_end - sl_start; /** malloc our matrix, add one extra slot for a final -1 **/ matrix_slots = spanduration_secs/delta_t + 1; matrix = (int*) malloc(sizeof(int) * matrix_slots); if (matrix == NULL) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return NULL; } memset(matrix, 0, sizeof(int) * matrix_slots); matrix[matrix_slots-1] = -1; /* loop through each span and mark the slots in the array */ for( itr = pvl_head(sl->spans); itr != 0; itr = pvl_next(itr)) { struct icaltime_span *s = (struct icaltime_span*)pvl_data(itr); if (s->is_busy == 1) { int offset_start = s->start/delta_t - sl_start/delta_t; int offset_end = (s->end - 1) /delta_t - sl_start/delta_t + 1; int i; if (offset_end >= matrix_slots) offset_end = matrix_slots - 1; i = offset_start; for (i=offset_start; i < offset_end; i++) { matrix[i]++; } } } return matrix; }
void calDateTime::FromIcalTime(icaltimetype const* icalt, calITimezone * tz) { icaltimetype t = *icalt; mIsValid = (icaltime_is_null_time(t) || icaltime_is_valid_time(t) ? PR_TRUE : PR_FALSE); mIsDate = t.is_date ? PR_TRUE : PR_FALSE; if (mIsDate) { t.hour = 0; t.minute = 0; t.second = 0; } if (mIsValid) { t = icaltime_normalize(t); } mYear = static_cast<PRInt16>(t.year); mMonth = static_cast<PRInt16>(t.month - 1); mDay = static_cast<PRInt16>(t.day); mHour = static_cast<PRInt16>(t.hour); mMinute = static_cast<PRInt16>(t.minute); mSecond = static_cast<PRInt16>(t.second); if (tz) { mTimezone = tz; } else { mTimezone = cal::detectTimezone(t, nsnull); } #if defined(DEBUG) if (mTimezone) { if (t.is_utc) { #if 1 nsCOMPtr<calITimezone> utc_tz; nsCOMPtr<calITimezoneService> tzSvc = do_GetService(CAL_TIMEZONESERVICE_CONTRACTID); tzSvc->GetUTC(getter_AddRefs(utc_tz)); NS_ASSERTION(SameCOMIdentity(mTimezone, utc_tz), "UTC mismatch!"); #else NS_ASSERTION(SameCOMIdentity(mTimezone, cal::UTC()), "UTC mismatch!"); #endif } else if (!t.zone) { #if 1 nsCOMPtr<calITimezone> float_tz; nsCOMPtr<calITimezoneService> tzSvc = do_GetService(CAL_TIMEZONESERVICE_CONTRACTID); tzSvc->GetFloating(getter_AddRefs(float_tz)); NS_ASSERTION(SameCOMIdentity(mTimezone, float_tz), "floating mismatch!"); #else NS_ASSERTION(SameCOMIdentity(mTimezone, cal::floating()), "floating mismatch!"); #endif } else { nsCAutoString tzid; mTimezone->GetTzid(tzid); NS_ASSERTION(tzid.Equals(icaltimezone_get_tzid(const_cast<icaltimezone *>(t.zone))), "tzid mismatch!"); } } #endif mWeekday = static_cast<PRInt16>(icaltime_day_of_week(t) - 1); mYearday = static_cast<PRInt16>(icaltime_day_of_year(t)); // mNativeTime: not moving the existing date to UTC, // but merely representing it a UTC-based way. t.is_date = 0; mNativeTime = IcaltimeToPRTime(&t, icaltimezone_get_utc_timezone()); }
static gboolean write_calendar (const gchar *uid, GOutputStream *stream, gint dur_type, gint dur_value, GError **error) { EShell *shell; ESource *source; ESourceRegistry *registry; EClient *client = NULL; GSList *objects = NULL; icaltimezone *utc; time_t start = time (NULL), end; icalcomponent *top_level; gchar *email = NULL; GSList *users = NULL; gboolean success = FALSE; utc = icaltimezone_get_utc_timezone (); start = time_day_begin_with_zone (start, utc); switch (dur_type) { case FB_DURATION_DAYS: end = time_add_day_with_zone (start, dur_value, utc); break; default: case FB_DURATION_WEEKS: end = time_add_week_with_zone (start, dur_value, utc); break; case FB_DURATION_MONTHS: end = time_add_month_with_zone (start, dur_value, utc); break; } shell = e_shell_get_default (); registry = e_shell_get_registry (shell); source = e_source_registry_ref_source (registry, uid); if (source != NULL) { EClientCache *client_cache; client_cache = e_shell_get_client_cache (shell); client = e_client_cache_get_client_sync (client_cache, source, E_SOURCE_EXTENSION_CALENDAR, 30, NULL, error); g_object_unref (source); } else { g_set_error ( error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_NO_SUCH_CALENDAR, _("Invalid source UID “%s”"), uid); } if (client == NULL) return FALSE; if (e_client_get_backend_property_sync (client, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS, &email, NULL, NULL)) { if (email && *email) users = g_slist_append (users, email); } top_level = e_cal_util_new_top_level (); success = e_cal_client_get_free_busy_sync ( E_CAL_CLIENT (client), start, end, users, &objects, NULL, error); if (success) { gchar *ical_string; GSList *iter; for (iter = objects; iter; iter = iter->next) { ECalComponent *comp = iter->data; icalcomponent *icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); icalcomponent_add_component (top_level, icalcomp); } ical_string = icalcomponent_as_ical_string_r (top_level); success = g_output_stream_write_all ( stream, ical_string, strlen (ical_string), NULL, NULL, error); e_cal_client_free_ecalcomp_slist (objects); g_free (ical_string); } if (users) g_slist_free (users); g_free (email); g_object_unref (client); icalcomponent_free (top_level); return success; }
/** * build_component_from_details: * @summary: * @initial_date: * @final_date: * * Create a component with the provided details * * Returns: (Transfer full): an {@link ECalComponent} object **/ ECalComponent* build_component_from_details (const gchar *summary, GDateTime *initial_date, GDateTime *final_date) { ECalComponent *event; ECalComponentDateTime dt; ECalComponentText summ; icaltimezone *zone; gboolean all_day; event = e_cal_component_new (); e_cal_component_set_new_vtype (event, E_CAL_COMPONENT_EVENT); /* * Check if the event is all day. Notice that it can be all day even * without the final date. */ all_day = datetime_is_date (initial_date) && (final_date ? datetime_is_date (final_date) : TRUE); /* * When the event is all day, we consider UTC timezone by default. Otherwise, * we always use the system timezone to create new events */ if (all_day) { zone = icaltimezone_get_utc_timezone (); } else { gchar *system_tz = e_cal_system_timezone_get_location (); zone = icaltimezone_get_builtin_timezone (system_tz); g_free (system_tz); } /* Start date */ dt.value = datetime_to_icaltime (initial_date); icaltime_set_timezone (dt.value, zone); dt.value->is_date = all_day; dt.tzid = icaltimezone_get_tzid (zone); e_cal_component_set_dtstart (event, &dt); g_free (dt.value); /* End date */ if (!final_date) final_date = g_date_time_add_days (initial_date, 1); dt.value = datetime_to_icaltime (final_date); icaltime_set_timezone (dt.value, zone); dt.value->is_date = all_day; dt.tzid = icaltimezone_get_tzid (zone); e_cal_component_set_dtend (event, &dt); g_free (dt.value); /* Summary */ summ.altrep = NULL; summ.value = summary; e_cal_component_set_summary (event, &summ); e_cal_component_commit_sequence (event); return event; }
icalcomponent *icalbdbsetiter_to_next(icalset *set, icalsetiter *i) { icalcomponent *comp = NULL; struct icaltimetype start, next; icalproperty *dtstart, *rrule, *prop, *due; struct icalrecurrencetype recur; icaltimezone *u_zone; int g = 0; int orig_time_was_utc = 0; _unused(set); do { /* no pending occurrence, read the next component */ if (i->last_component == NULL) { comp = icalcompiter_next(&(i->iter)); } else { comp = i->last_component; } /* no next component, simply return */ if (comp == 0) { return NULL; } if (i->gauge == 0) { return comp; } /* finding the next matched component and return it to the caller */ rrule = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY); g = icalgauge_get_expand(i->gauge); /* a recurring component with expand query */ if (rrule != 0 && g == 1) { u_zone = icaltimezone_get_builtin_timezone(i->tzid); /* use UTC, if that's all we have. */ if (!u_zone) { u_zone = icaltimezone_get_utc_timezone(); } recur = icalproperty_get_rrule(rrule); start = icaltime_from_timet(time(0), 0); if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) { dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY); if (dtstart) { start = icalproperty_get_dtstart(dtstart); } } else if (icalcomponent_isa(comp) == ICAL_VTODO_COMPONENT) { due = icalcomponent_get_first_property(comp, ICAL_DUE_PROPERTY); if (due) { start = icalproperty_get_due(due); } } /* Convert to the user's timezone in order to be able to compare * the results from the rrule iterator. */ if (icaltime_is_utc(start)) { start = icaltime_convert_to_zone(start, u_zone); orig_time_was_utc = 1; } if (i->ritr == NULL) { i->ritr = icalrecur_iterator_new(recur, start); next = icalrecur_iterator_next(i->ritr); i->last_component = comp; } else { next = icalrecur_iterator_next(i->ritr); if (icaltime_is_null_time(next)) { i->last_component = NULL; icalrecur_iterator_free(i->ritr); i->ritr = NULL; /* no more occurrence, should go to get next component */ continue; } else { i->last_component = comp; } } /* if it is excluded, do next one */ if (icalproperty_recurrence_is_excluded(comp, &start, &next)) { next = icalrecur_iterator_next(i->ritr); continue; } /* set recurrence-id value to the property if the property already exist; * add the recurrence id property and the value if the property does not exist */ prop = icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY); if (prop == 0) { icalcomponent_add_property(comp, icalproperty_new_recurrenceid(next)); } else { icalproperty_set_recurrenceid(prop, next); } if (orig_time_was_utc) { next = icaltime_convert_to_zone(next, icaltimezone_get_utc_timezone()); } } /* end of recurring event with expand query */ if (comp != 0 && (i->gauge == 0 || icalgauge_compare(i->gauge, comp) == 1)) { /* found a matched, return it */ return comp; } } while (comp != 0); return NULL; /*unreachable */ }
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; }
int main() { icalarray *builtin_timezones; icaltimetype tt; int dd, hh, zz, tried = 0; long zz2 = -1; set_zone_directory("../../zoneinfo"); icaltimezone_set_tzid_prefix("/softwarestudio.org/"); tt = icaltime_current_time_with_zone(icaltimezone_get_builtin_timezone("America/New_York")); tt.year = 2038; (void)icaltime_as_timet_with_zone(tt, icaltimezone_get_builtin_timezone("PST")); tried++; tt.year = 2050; (void)icaltime_as_timet_with_zone(tt, icaltimezone_get_builtin_timezone("PST")); tried++; tt.year = 1958; (void)icaltime_as_timet_with_zone(tt, icaltimezone_get_builtin_timezone("PST")); tried++; builtin_timezones = icaltimezone_get_builtin_timezones(); printf("got %lu zones\n", (unsigned long)builtin_timezones->num_elements); if (builtin_timezones->num_elements == 0) { printf("YIKES. Try running from the build/bin directory\n"); return(1); } for (zz = -1; zz < (int)builtin_timezones->num_elements; zz++) { icaltimezone *zone; if (zz < 0) { zone = icaltimezone_get_utc_timezone(); } else { zone = icalarray_element_at(builtin_timezones, (size_t)zz); } tt = icaltime_current_time_with_zone(zone); for (dd = 0; dd < 370; dd += 17) { for (hh = 0; hh < 60 * 60 * 24; hh += 567) { int zz2cnt; icaltime_adjust(&tt, 0, 0, 0, 1); for (zz2cnt = 0; zz2cnt < 15; zz2cnt++) { icaltimezone *zone2; if (zz2 < 0) { zone2 = icaltimezone_get_utc_timezone(); } else { zone2 = icalarray_element_at(builtin_timezones, (size_t)zz2); } (void)icaltime_as_timet_with_zone(tt, zone2); tried++; zz2++; if (zz2 >= (long)builtin_timezones->num_elements) zz2 = -1; } } } printf("\r%lu %% done", (zz >= 0 ? zz : 0) * 100 / (unsigned long)builtin_timezones->num_elements); fflush(stdout); } printf("\ntried %d times\n", tried); return 0; }
/* (occur-in-time-range? START END TZLOC) * * START - time_t, start of the time range, in UTC * END - time_t, end of the time range, in UTC * TZLOC - optional string with timezone location to use * as default timezone; if not set, UTC is used * * Returns a boolean indicating whether the component has any occurrences in the * specified time range. */ static ESExpResult * func_occur_in_time_range (ESExp *esexp, gint argc, ESExpResult **argv, gpointer data) { SearchContext *ctx = data; time_t start, end; ESExpResult *result; icaltimezone *default_zone = NULL; /* Check argument types */ if (argc != 2 && argc != 3) { e_sexp_fatal_error ( esexp, _("\"%s\" expects two or three arguments"), "occur-in-time-range"); return NULL; } if (argv[0]->type != ESEXP_RES_TIME) { e_sexp_fatal_error ( esexp, _("\"%s\" expects the first " "argument to be a time_t"), "occur-in-time-range"); return NULL; } start = argv[0]->value.time; if (argv[1]->type != ESEXP_RES_TIME) { e_sexp_fatal_error ( esexp, _("\"%s\" expects the second " "argument to be a time_t"), "occur-in-time-range"); return NULL; } end = argv[1]->value.time; if (argc == 3) { if (argv[2]->type != ESEXP_RES_STRING) { e_sexp_fatal_error ( esexp, _("\"%s\" expects the third " "argument to be a string"), "occur-in-time-range"); return NULL; } default_zone = resolve_tzid (argv[2]->value.string, ctx); } if (!default_zone) default_zone = icaltimezone_get_utc_timezone (); /* See if the object occurs in the specified time range */ ctx->occurs = FALSE; e_cal_recur_generate_instances ( ctx->comp, start, end, (ECalRecurInstanceFn) check_instance_time_range_cb, ctx, resolve_tzid, ctx, default_zone); result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); result->value.boolean = ctx->occurs; return result; }
/** * e_cal_util_split_at_instance: * @icalcomp: A (recurring) #icalcomponent * @rid: The base RECURRENCE-ID to remove * @master_dtstart: The DTSTART of the master object * * Splits a recurring @icalcomp into two at time @rid. The returned icalcomponent * is modified @icalcomp which contains recurrences beginning at @rid, inclusive. * The instance identified by @rid should exist. The @master_dtstart can be * a null time, then it is read from the @icalcomp. * * Use e_cal_util_remove_instances() with E_CAL_OBJ_MOD_THIS_AND_FUTURE mode * on the @icalcomp to remove the overlapping interval from it, if needed. * * Returns: the split icalcomponent, or %NULL. * * Since: 3.16 **/ icalcomponent * e_cal_util_split_at_instance (icalcomponent *icalcomp, struct icaltimetype rid, struct icaltimetype master_dtstart) { icalproperty *prop; struct instance_data instance; struct icaltimetype start, end; struct icaldurationtype duration; GSList *remove_props = NULL, *link; g_return_val_if_fail (icalcomp != NULL, NULL); g_return_val_if_fail (!icaltime_is_null_time (rid), NULL); /* Make sure this is really recurring */ if (!icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY) && !icalcomponent_get_first_property (icalcomp, ICAL_RDATE_PROPERTY)) return NULL; /* Make sure the specified instance really exists */ start = icaltime_convert_to_zone (rid, icaltimezone_get_utc_timezone ()); end = start; icaltime_adjust (&end, 0, 0, 0, 1); instance.start = icaltime_as_timet (start); instance.found = FALSE; icalcomponent_foreach_recurrence (icalcomp, start, end, check_instance, &instance); /* Make the copy */ icalcomp = icalcomponent_new_clone (icalcomp); e_cal_util_remove_instances_ex (icalcomp, rid, E_CAL_OBJ_MOD_THIS_AND_PRIOR, TRUE, FALSE); start = rid; if (icaltime_is_null_time (master_dtstart)) master_dtstart = icalcomponent_get_dtstart (icalcomp); duration = icalcomponent_get_duration (icalcomp); /* Expect that DTSTART and DTEND are already set when the instance could not be found */ if (instance.found) { icalcomponent_set_dtstart (icalcomp, start); /* Update either DURATION or DTEND */ if (icaltime_is_null_time (icalcomponent_get_dtend (icalcomp))) { icalcomponent_set_duration (icalcomp, duration); } else { end = start; if (duration.is_neg) icaltime_adjust (&end, -duration.days - 7 * duration.weeks, -duration.hours, -duration.minutes, -duration.seconds); else icaltime_adjust (&end, duration.days + 7 * duration.weeks, duration.hours, duration.minutes, duration.seconds); icalcomponent_set_dtend (icalcomp, end); } } /* any RRULE with 'count' should be shortened */ for (prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY); prop; prop = icalcomponent_get_next_property (icalcomp, ICAL_RRULE_PROPERTY)) { struct icaltimetype recur; struct icalrecurrencetype rule; rule = icalproperty_get_rrule (prop); if (rule.count != 0) { gint occurrences_count = 0; icalrecur_iterator *iter; iter = icalrecur_iterator_new (rule, master_dtstart); while (recur = icalrecur_iterator_next (iter), !icaltime_is_null_time (recur) && occurrences_count < rule.count) { if (icaltime_compare (recur, rid) >= 0) break; occurrences_count++; } icalrecur_iterator_free (iter); if (icaltime_is_null_time (recur)) { remove_props = g_slist_prepend (remove_props, prop); } else { rule.count -= occurrences_count; icalproperty_set_rrule (prop, rule); icalproperty_remove_parameter_by_name (prop, "X-EVOLUTION-ENDDATE"); } } } for (link = remove_props; link; link = g_slist_next (link)) { prop = link->data; icalcomponent_remove_property (icalcomp, prop); } g_slist_free (remove_props); return icalcomp; }
static gboolean write_calendar (const gchar *uid, GOutputStream *stream, gint dur_type, gint dur_value, GError **error) { EShell *shell; ESource *source; ESourceRegistry *registry; EClient *client = NULL; GSList *objects = NULL; icaltimezone *utc; time_t start = time (NULL), end; icalcomponent *top_level; gchar *email = NULL; GSList *users = NULL; gulong handler_id; gboolean success = FALSE; utc = icaltimezone_get_utc_timezone (); start = time_day_begin_with_zone (start, utc); switch (dur_type) { case FB_DURATION_DAYS: end = time_add_day_with_zone (start, dur_value, utc); break; default: case FB_DURATION_WEEKS: end = time_add_week_with_zone (start, dur_value, utc); break; case FB_DURATION_MONTHS: end = time_add_month_with_zone (start, dur_value, utc); break; } shell = e_shell_get_default (); registry = e_shell_get_registry (shell); source = e_source_registry_ref_source (registry, uid); if (source != NULL) { EClientCache *client_cache; client_cache = e_shell_get_client_cache (shell); client = e_client_cache_get_client_sync (client_cache, source, E_SOURCE_EXTENSION_CALENDAR, 30, NULL, error); g_object_unref (source); } else { g_set_error ( error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_NO_SUCH_CALENDAR, _("Invalid source UID '%s'"), uid); } if (client == NULL) return FALSE; if (e_client_get_backend_property_sync (client, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS, &email, NULL, NULL)) { if (email && *email) users = g_slist_append (users, email); } top_level = e_cal_util_new_top_level (); handler_id = g_signal_connect ( client, "free-busy-data", G_CALLBACK (free_busy_data_cb), &objects); success = e_cal_client_get_free_busy_sync ( E_CAL_CLIENT (client), start, end, users, NULL, error); if (handler_id > 0) g_signal_handler_disconnect (client, handler_id); if (success) { gchar *ical_string; GSList *iter; gboolean done = FALSE; /* This is to workaround broken dispatch of "free-busy-data" signal, * introduced in 3.8.0. This code can be removed once the below bug is * properly fixed: https://bugzilla.gnome.org/show_bug.cgi?id=692361 */ while (!done) { g_usleep (G_USEC_PER_SEC / 10); done = !g_main_context_iteration (NULL, FALSE); } for (iter = objects; iter; iter = iter->next) { ECalComponent *comp = iter->data; icalcomponent *icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); icalcomponent_add_component (top_level, icalcomp); } ical_string = icalcomponent_as_ical_string_r (top_level); success = g_output_stream_write_all ( stream, ical_string, strlen (ical_string), NULL, NULL, error); e_cal_client_free_ecalcomp_slist (objects); g_free (ical_string); } if (users) g_slist_free (users); g_free (email); g_object_unref (client); icalcomponent_free (top_level); return success; }
/* Generates the absolute triggers for a component */ static void generate_absolute_triggers (ECalComponent *comp, struct alarm_occurrence_data *aod, ECalRecurResolveTimezoneFn resolve_tzid, gpointer user_data, icaltimezone *default_timezone) { GList *l; ECalComponentDateTime dt_start, dt_end; e_cal_component_get_dtstart (comp, &dt_start); e_cal_component_get_dtend (comp, &dt_end); for (l = aod->alarm_uids; l; l = l->next) { const gchar *auid; ECalComponentAlarm *alarm; ECalComponentAlarmAction action; ECalComponentAlarmRepeat repeat; ECalComponentAlarmTrigger trigger; time_t abs_time; time_t occur_start, occur_end; icaltimezone *zone; gint i; auid = l->data; alarm = e_cal_component_get_alarm (comp, auid); g_return_if_fail (alarm != NULL); e_cal_component_alarm_get_action (alarm, &action); e_cal_component_alarm_get_trigger (alarm, &trigger); e_cal_component_alarm_get_repeat (alarm, &repeat); e_cal_component_alarm_free (alarm); for (i = 0; aod->omit[i] != -1; i++) { if (aod->omit[i] == action) break; } if (aod->omit[i] != -1) continue; if (trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE) continue; /* Absolute triggers are always in UTC; * see RFC 2445 section 4.8.6.3 */ zone = icaltimezone_get_utc_timezone (); abs_time = icaltime_as_timet_with_zone (trigger.u.abs_time, zone); /* No particular occurrence, so just use the times from the * component */ if (dt_start.value) { if (dt_start.tzid && !dt_start.value->is_date) zone = (* resolve_tzid) (dt_start.tzid, user_data); else zone = default_timezone; occur_start = icaltime_as_timet_with_zone ( *dt_start.value, zone); } else occur_start = -1; if (dt_end.value) { if (dt_end.tzid && !dt_end.value->is_date) zone = (* resolve_tzid) (dt_end.tzid, user_data); else zone = default_timezone; occur_end = icaltime_as_timet_with_zone (*dt_end.value, zone); } else occur_end = -1; /* Add repeating alarms */ if (repeat.repetitions != 0) { gint i; time_t repeat_time; repeat_time = icaldurationtype_as_int (repeat.duration); for (i = 0; i < repeat.repetitions; i++) { time_t t; t = abs_time + (i + 1) * repeat_time; if (t >= aod->start && t < aod->end) add_trigger ( aod, auid, t, occur_start, occur_end); } } /* Add the trigger itself */ if (abs_time >= aod->start && abs_time < aod->end) add_trigger (aod, auid, abs_time, occur_start, occur_end); } e_cal_component_free_datetime (&dt_start); e_cal_component_free_datetime (&dt_end); }
gint main (gint argc, gchar **argv) { ECalClient *cal_client; GError *error = NULL; icalcomponent *icalcomp; struct icaltimetype now; gchar *uid = NULL; main_initialize (); cal_client = new_temp_client (E_CAL_CLIENT_SOURCE_TYPE_EVENTS, NULL); g_return_val_if_fail (cal_client != NULL, FALSE); if (!e_client_open_sync (E_CLIENT (cal_client), FALSE, NULL, &error)) { report_error ("client open sync", &error); g_object_unref (cal_client); return 1; } now = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ()); icalcomp = icalcomponent_new (ICAL_VEVENT_COMPONENT); icalcomponent_set_summary (icalcomp, "Test event summary"); icalcomponent_set_dtstart (icalcomp, now); icalcomponent_set_dtend (icalcomp, icaltime_from_timet (icaltime_as_timet (now) + 60 * 60 * 60, 0)); add_attach (icalcomp, ATTACH1); add_attach (icalcomp, ATTACH2); add_attach (icalcomp, ATTACH3); if (!e_cal_client_create_object_sync (cal_client, icalcomp, &uid, NULL, &error)) { report_error ("create object sync", &error); icalcomponent_free (icalcomp); g_object_unref (cal_client); return 1; } icalcomponent_free (icalcomp); g_object_set_data_full (G_OBJECT (cal_client), "use-uid", uid, g_free); /* synchronously without main-loop */ if (!test_sync (cal_client)) { g_object_unref (cal_client); return 1; } start_in_thread_with_main_loop (test_sync_in_thread, cal_client); if (!e_client_remove_sync (E_CLIENT (cal_client), NULL, &error)) { report_error ("client remove sync", &error); g_object_unref (cal_client); return 1; } g_object_unref (cal_client); if (get_main_loop_stop_result () == 0) g_print ("Test finished successfully.\n"); return get_main_loop_stop_result (); }