Пример #1
0
/**
 * g_time_zone_adjust_time:
 * @tz: a #GTimeZone
 * @type: the #GTimeType of @time
 * @time: a pointer to a number of seconds since January 1, 1970
 *
 * Finds an interval within @tz that corresponds to the given @time,
 * possibly adjusting @time if required to fit into an interval.
 * The meaning of @time depends on @type.
 *
 * This function is similar to g_time_zone_find_interval(), with the
 * difference that it always succeeds (by making the adjustments
 * described below).
 *
 * In any of the cases where g_time_zone_find_interval() succeeds then
 * this function returns the same value, without modifying @time.
 *
 * This function may, however, modify @time in order to deal with
 * non-existent times.  If the non-existent local @time of 02:30 were
 * requested on March 13th 2010 in Toronto then this function would
 * adjust @time to be 03:00 and return the interval containing the
 * adjusted time.
 *
 * Returns: the interval containing @time, never -1
 *
 * Since: 2.26
 **/
gint
g_time_zone_adjust_time (GTimeZone *tz,
                         GTimeType  type,
                         gint64    *time)
{
  gint i;

  if (tz->zoneinfo == NULL)
    return 0;

  /* find the interval containing *time UTC
   * TODO: this could be binary searched (or better) */
  for (i = 0; i < tz->timecnt; i++)
    if (*time <= interval_end (tz, i))
      break;

  g_assert (interval_start (tz, i) <= *time && *time <= interval_end (tz, i));

  if (type != G_TIME_TYPE_UNIVERSAL)
    {
      if (*time < interval_local_start (tz, i))
        /* if time came before the start of this interval... */
        {
          i--;

          /* if it's not in the previous interval... */
          if (*time > interval_local_end (tz, i))
            {
              /* it doesn't exist.  fast-forward it. */
              i++;
              *time = interval_local_start (tz, i);
            }
        }

      else if (*time > interval_local_end (tz, i))
        /* if time came after the end of this interval... */
        {
          i++;

          /* if it's not in the next interval... */
          if (*time < interval_local_start (tz, i))
            /* it doesn't exist.  fast-forward it. */
            *time = interval_local_start (tz, i);
        }

      else if (interval_isdst (tz, i) != type)
        /* it's in this interval, but dst flag doesn't match.
         * check neighbours for a better fit. */
        {
          if (i && *time <= interval_local_end (tz, i - 1))
            i--;

          else if (i < tz->timecnt &&
                   *time >= interval_local_start (tz, i + 1))
            i++;
        }
    }

  return i;
}
Пример #2
0
inline static gint64
interval_local_start (GTimeZone *tz,
                      gint       interval)
{
  if (interval)
    return interval_start (tz, interval) + interval_offset (tz, interval);

  return G_MININT64;
}
Пример #3
0
// --- p_start -----------------------------------------------------------------
unsigned long
p_start (unsigned long ps, unsigned long s, unsigned long pi) {
   return ps == 0 ? interval_start (s, pi) : ps;
}