/** * Returns the time zone raw and GMT offset for the given moment * in time. Upon return, local-millis = GMT-millis + rawOffset + * dstOffset. All computations are performed in the proleptic * Gregorian calendar. The default implementation in the TimeZone * class delegates to the 8-argument getOffset(). * * @param float Moment in time for which to return offsets, in units of * milliseconds from January 1, 1970 0:00 GMT, either GMT * time or local wall time, depending on `local'. * @param bool If true, `date' is local wall time; otherwise it * is in GMT time. * @param int Output parameter to receive the raw offset, that is, the * offset not including DST adjustments * @param int Output parameter to receive the DST offset, that is, the * offset to be added to `rawOffset' to obtain the total * offset between local and GMT time. If DST is not in * effect, this value is zero; otherwise it is a positive * value, typically one hour. * * @author Dominik del Bondio <*****@*****.**> * @author The ICU Project * @since 0.11.0 */ public function getOffsetRef($date, $local, &$rawOffset, &$dstOffset) { $rawOffset = $this->getRawOffset(); // Convert to local wall millis if necessary if (!$local) { $date += $rawOffset; // now in local standard millis } // When local==FALSE, we might have to recompute. This loop is // executed once, unless a recomputation is required; then it is // executed twice. for ($pass = 0; true; ++$pass) { $year = $month = $dom = $dow = 0; $day = floor($date / AgaviDateDefinitions::MILLIS_PER_DAY); $millis = (int) ($date - $day * AgaviDateDefinitions::MILLIS_PER_DAY); AgaviCalendarGrego::dayToFields($day, $year, $month, $dom, $dow); $dstOffset = $this->getOffsetIIIIIII(AgaviGregorianCalendar::AD, $year, $month, $dom, $dow, $millis, AgaviCalendarGrego::monthLength($year, $month)) - $rawOffset; // Recompute if local==FALSE, dstOffset!=0, and addition of // the dstOffset puts us in a different day. if ($pass != 0 || $local || $dstOffset == 0) { break; } $date += $dstOffset; if (floor($date / AgaviDateDefinitions::MILLIS_PER_DAY) == $day) { break; } } }
/** * AgaviTimeZone API. * * @see AgaviTimeZone::useDaylightTime() * * @author Dominik del Bondio <*****@*****.**> * @author The ICU Project * @since 0.11.0 */ public function useDaylightTime() { // If DST was observed in 1942 (for example) but has never been // observed from 1943 to the present, most clients will expect // this method to return FALSE. This method determines whether // DST is in use in the current year (at any point in the year) // and returns TRUE if so. $days = floor(AgaviCalendar::getNow() / AgaviDateDefinitions::MILLIS_PER_DAY); // epoch days $year = 0; $month = 0; $dom = 0; $dow = 0; AgaviCalendarGrego::dayToFields($days, $year, $month, $dom, $dow); if ($year > $this->finalYear) { // [sic] >, not >=; see above if ($this->finalZone) { return $this->finalZone->useDaylightTime(); } else { return true; } } // Find start of this year, and start of next year $start = (int) AgaviCalendarGrego::fieldsToDay($year, 0, 1) * AgaviDateDefinitions::SECONDS_PER_DAY; $limit = (int) AgaviCalendarGrego::fieldsToDay($year + 1, 0, 1) * AgaviDateDefinitions::SECONDS_PER_DAY; // Return TRUE if DST is observed at any time during the current year. for ($i = 0, $transitionCount = count($this->transitions); $i < $transitionCount; ++$i) { if ($this->transitions[$i]['time'] >= $limit) { break; } if ($this->transitions[$i]['time'] >= $start && $this->types[$this->transitions[$i]['type']]['dstOffset'] != 0 || $this->transitions[$i]['time'] > $start && $i > 0 && $this->types[$this->transitions[$i - 1]['type']]['dstOffset'] != 0) { return true; } } return false; }
/** * Compute the Gregorian calendar year, month, and day of month from the * Julian day. These values are not stored in fields, but in member * variables gregorianXxx. They are used for time zone computations and by * subclasses that are Gregorian derivatives. Subclasses may call this * method to perform a Gregorian calendar millis->fields computation. * To perform a Gregorian calendar fields->millis computation, call * computeGregorianMonthStart(). * @see #computeGregorianMonthStart * * @param int The julian day * * @author Dominik del Bondio <*****@*****.**> * @author The ICU Project * @since 0.11.0 */ private function computeGregorianFields($julianDay) { $gregorianDayOfWeekUnused = 0; AgaviCalendarGrego::dayToFields($julianDay - AgaviDateDefinitions::EPOCH_START_AS_JULIAN_DAY, $this->fGregorianYear, $this->fGregorianMonth, $this->fGregorianDayOfMonth, $gregorianDayOfWeekUnused, $this->fGregorianDayOfYear); }