/** * AgaviTimeZone API. * * @see AgaviTimeZone::getOffsetIIIIII() * * @author Dominik del Bondio <*****@*****.**> * @author The ICU Project * @since 0.11.0 */ protected function getOffsetIIIIII($era, $year, $month, $dom, $dow, $millis) { if ($month < AgaviDateDefinitions::JANUARY || $month > AgaviDateDefinitions::DECEMBER) { throw new InvalidArgumentException('Month out of range'); } else { return $this->getOffsetIIIIIII($era, $year, $month, $dom, $dow, $millis, AgaviCalendarGrego::monthLength($year, $month)); } }
/** * 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; } } }
/** * Gets the time zone offset, for current date, modified in case of * daylight savings. This is the offset to add *to* UTC to get local time. * * @param int The era of the given date. * @param int The year in the given date. * @param int The month in the given date. * Month is 0-based. e.g., 0 for January. * @param int The day-in-month of the given date. * @param int The day-of-week of the given date. * @param int The millis in day in <em>standard</em> local time. * @param int The length of the given month in days. * * @return int The offset to add *to* GMT to get local time. * * @author Dominik del Bondio <*****@*****.**> * @author The ICU Project * @since 0.11.0 */ public function getOffsetIIIIIII($era, $year, $month, $day, $dayOfWeek, $millis, $monthLength) { // Check the month before calling Grego::monthLength(). This // duplicates a test that occurs in the 9-argument getOffset(), // however, this is unavoidable. We don't mind because this method, in // fact, should not be called; internal code should always call the // 9-argument getOffset(), and outside code should use Calendar.get(int // field) with fields ZONE_OFFSET and DST_OFFSET. We can't get rid of // this method because it's public API. - liu 8/10/98 if ($month < AgaviDateDefinitions::JANUARY || $month > AgaviDateDefinitions::DECEMBER) { throw new InvalidArgumentException('Month out of range'); return -1; } // We ignore monthLength because it can be derived from year and month. // This is so that February in leap years is calculated correctly. // We keep this argument in this function for backwards compatibility. return $this->getOffsetIIIIIIII($era, $year, $month, $day, $dayOfWeek, $millis, AgaviCalendarGrego::monthLength($year, $month), AgaviCalendarGrego::previousMonthLength($year, $month)); }
/** * Returns the time specified by the input arguments. * * @param int The year. * @param int The month. * @param array The date definition. * @param array The at (time into the day) definition. * @param int The gmt offset. * @param int The dst offset. * * @return int The unix timestamp. * * @author Dominik del Bondio <*****@*****.**> * @since 0.11.0 */ protected function getOnDate($year, $month, $dateDef, $atDef, $gmtOff, $dstOff) { static $cal = null; if (!$cal) { $cal = $this->getContext()->getTranslationManager()->createCalendar(); } $cal->clear(); $cal->set(AgaviDateDefinitions::YEAR, $year); $cal->set(AgaviDateDefinitions::MONTH, $month); if ($dateDef['type'] == 'date') { $cal->set(AgaviDateDefinitions::DATE, $dateDef['date']); } elseif ($dateDef['type'] == 'last') { $daysInMonth = AgaviCalendarGrego::monthLength($year, $month); $cal->set(AgaviDateDefinitions::DATE, $daysInMonth); // loop backwards until we found the last occurrence of the day while ($cal->get(AgaviDateDefinitions::DAY_OF_WEEK) != $dateDef['day']) { $cal->roll(AgaviDateDefinitions::DATE, -1); } } elseif ($dateDef['type'] == '<=') { $cal->set(AgaviDateDefinitions::DATE, $dateDef['date']); while ($cal->get(AgaviDateDefinitions::DAY_OF_WEEK) != $dateDef['day']) { $cal->roll(AgaviDateDefinitions::DATE, -1); } } elseif ($dateDef['type'] == '>=') { $cal->set(AgaviDateDefinitions::DATE, $dateDef['date']); while ($cal->get(AgaviDateDefinitions::DAY_OF_WEEK) != $dateDef['day']) { $cal->roll(AgaviDateDefinitions::DATE, 1); } } else { throw new AgaviException('Unknown on type ' . $dateDef['type']); } $time = $cal->getTime() / 1000; $time += $atDef['secondsInDay']; if ($atDef['type'] == 'wallclock') { $time -= $dstOff; $time -= $gmtOff; } elseif ($atDef['type'] == 'standard') { $time -= $gmtOff; } return $time; }