/** * 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; }
inline static gint64 interval_local_start (GTimeZone *tz, gint interval) { if (interval) return interval_start (tz, interval) + interval_offset (tz, interval); return G_MININT64; }
// --- p_start ----------------------------------------------------------------- unsigned long p_start (unsigned long ps, unsigned long s, unsigned long pi) { return ps == 0 ? interval_start (s, pi) : ps; }