Logo Search packages:      
Sourcecode: libical version File versions

int icaltimezone_get_utc_offset_of_utc_time ( icaltimezone *  zone,
struct icaltimetype *  tt,
int *  is_daylight 

This API wasn't updated when we changed icaltimetype to contain its own timezone. Also, this takes a pointer instead of the struct.
Calculates the UTC offset of a given UTC time in the given timezone. It is the number of seconds to add to UTC to get local time. The is_daylight flag is set to 1 if the time is in daylight-savings time.

Definition at line 966 of file icaltimezone.c.

References icaltimezone_compare_change_fn(), icaltimezone_find_nearby_change(), and utc_timezone.

Referenced by icaltimezone_convert_time().

    icaltimezonechange *zone_change, tt_change, tmp_change;
    int change_num, step, change_num_to_use;

    if (is_daylight)
      *is_daylight = 0;

    /* For local times and UTC return 0. */
    if (zone == NULL || zone == &utc_timezone)
      return 0;

    /* Use the builtin icaltimezone if possible. */
    if (zone->builtin_timezone)
      zone = zone->builtin_timezone;

    /* Make sure the changes array is expanded up to the given time. */
    icaltimezone_ensure_coverage (zone, tt->year);

    if (!zone->changes || zone->changes->num_elements == 0)
      return 0;

    /* Copy the time parts of the icaltimetype to an icaltimezonechange so we
       can use our comparison function on it. */
    tt_change.year   = tt->year;
    tt_change.month  = tt->month;
    tt_change.day    = tt->day;
    tt_change.hour   = tt->hour;
    tt_change.minute = tt->minute;
    tt_change.second = tt->second;

    /* This should find a change close to the time, either the change before
       it or the change after it. */
    change_num = icaltimezone_find_nearby_change (zone, &tt_change);

    /* Sanity check. */
    icalerror_assert (change_num >= 0,
                  "Negative timezone change index");
    icalerror_assert (change_num < zone->changes->num_elements,
                  "Timezone change index out of bounds");

    /* Now move backwards or forwards to find the timezone change that applies
       to tt. It should only have to do 1 or 2 steps. */
    zone_change = icalarray_element_at (zone->changes, change_num);
    step = 1;
    change_num_to_use = -1;
    for (;;) {
      /* Copy the change and adjust it to UTC. */
      tmp_change = *zone_change;

      /* If the given time is on or after this change, then this change may
         apply, but we continue as a later change may be the right one.
         If the given time is before this change, then if we have already
         found a change which applies we can use that, else we need to step
         backwards. */
      if (icaltimezone_compare_change_fn (&tt_change, &tmp_change) >= 0)
          change_num_to_use = change_num;
          step = -1;

      /* If we are stepping backwards through the changes and we have found
         a change that applies, then we know this is the change to use so
         we exit the loop. */
      if (step == -1 && change_num_to_use != -1)

      change_num += step;

      /* If we go past the start of the changes array, then we have no data
         for this time so we return a UTC offset of 0. */
      if (change_num < 0)
          return 0;

      if ((unsigned int)change_num >= zone->changes->num_elements)

      zone_change = icalarray_element_at (zone->changes, change_num);

    /* If we didn't find a change to use, then we have a bug! */
    icalerror_assert (change_num_to_use != -1,
                  "No applicable timezone change found");

    /* Now we know exactly which timezone change applies to the time, so
       we can return the UTC offset and whether it is a daylight time. */
    zone_change = icalarray_element_at (zone->changes, change_num_to_use);
    if (is_daylight)
      *is_daylight = zone_change->is_daylight;

    return zone_change->utc_offset;

Generated by  Doxygen 1.6.0   Back to index