/**
  * Creates a new calendar instance with the current time set.
  *
  * @param      mixed This can be either an AgaviLocale, an AgaviTimeZone or
  *                   a string specifying the calendar type.
  *
  * @return     AgaviCalendar The current timezone instance.
  *
  * @author     Dominik del Bondio <*****@*****.**>
  * @since      0.11.0
  */
 public function createCalendar($type = null)
 {
     $locale = $this->getCurrentLocale();
     $calendarType = null;
     $zone = null;
     $time = null;
     if ($type instanceof AgaviLocale) {
         $locale = $type;
     } elseif ($type instanceof AgaviTimeZone) {
         $zone = $type;
     } elseif ($type instanceof DateTime) {
         $time = $type;
     } elseif (is_int($type)) {
         $time = $type * AgaviDateDefinitions::MILLIS_PER_SECOND;
     } elseif ($type !== null) {
         $calendarType = $type;
     }
     if ($time === null) {
         $time = AgaviCalendar::getNow();
     }
     if (!$zone) {
         if ($locale->getLocaleTimeZone()) {
             $zone = $this->createTimeZone($locale->getLocaleTimeZone());
         }
     }
     if (!$calendarType) {
         $calendarType = $locale->getLocaleCalendar();
         if (!$calendarType) {
             $calendarType = AgaviCalendar::GREGORIAN;
         }
     }
     switch ($calendarType) {
         case AgaviCalendar::GREGORIAN:
             $c = new AgaviGregorianCalendar($this);
             break;
         default:
             throw new AgaviException('Calendar type ' . $calendarType . ' not supported');
     }
     // Now, reset calendar to default state:
     if ($zone) {
         $c->setTimeZone($zone);
     }
     if ($time instanceof DateTime) {
         // FIXME: we can't use $time->getTimezone()->getName() here since that triggers
         // https://github.com/facebook/hhvm/issues/1777 but luckily using format('e')
         // works for both php and hhvm
         $tzName = $time->format('e');
         if (preg_match('/^[+-0-9]/', $tzName)) {
             $tzName = 'GMT' . $tzName;
         }
         $c->setTimeZone($this->createTimeZone($tzName));
         $dateStr = $time->format('Y z G i s');
         list($year, $doy, $hour, $minute, $second) = explode(' ', $dateStr);
         $c->set(AgaviDateDefinitions::YEAR, $year);
         $c->set(AgaviDateDefinitions::DAY_OF_YEAR, $doy + 1);
         $c->set(AgaviDateDefinitions::HOUR_OF_DAY, $hour);
         $c->set(AgaviDateDefinitions::MINUTE, $minute);
         $c->set(AgaviDateDefinitions::SECOND, $second);
         // complete the calendar
         $c->getAll();
     } else {
         $c->setTime($time);
         // let the new calendar have the current time.
     }
     return $c;
 }
예제 #2
0
 /**
  * Sets the GregorianCalendar change date. This is the point when the switch 
  * from Julian dates to Gregorian dates occurred. Default is 00:00:00 local 
  * time, October 15, 1582. Previous to this time and date will be Julian 
  * dates.
  *
  * @param      float The given Gregorian cutover date.
  * 
  * @author     Dominik del Bondio <*****@*****.**>
  * @author     The ICU Project
  * @since      0.11.0
  */
 public function setGregorianChange($date)
 {
     $this->fGregorianCutover = $date;
     // Precompute two internal variables which we use to do the actual
     // cutover computations.  These are the normalized cutover, which is the
     // midnight at or before the cutover, and the cutover year.  The
     // normalized cutover is in pure date milliseconds; it contains no time
     // of day or timezone component, and it used to compare against other
     // pure date values.
     $cutoverDay = (int) floor($this->fGregorianCutover / AgaviDateDefinitions::MILLIS_PER_DAY);
     $this->fNormalizedGregorianCutover = $cutoverDay * AgaviDateDefinitions::MILLIS_PER_DAY;
     // Handle the rare case of numeric overflow.  If the user specifies a
     // change of UDate(Long.MIN_VALUE), in order to get a pure Gregorian
     // calendar, then the epoch day is -106751991168, which when multiplied
     // by ONE_DAY gives 9223372036794351616 -- the negative value is too
     // large for 64 bits, and overflows into a positive value.  We correct
     // this by using the next day, which for all intents is semantically
     // equivalent.
     if ($cutoverDay < 0 && $this->fNormalizedGregorianCutover > 0) {
         $this->fNormalizedGregorianCutover = ($cutoverDay + 1) * AgaviDateDefinitions::MILLIS_PER_DAY;
     }
     // Normalize the year so BC values are represented as 0 and negative
     // values.
     $cal = new AgaviGregorianCalendar($this->getTimeZone());
     $cal->setTime($date);
     $this->fGregorianCutoverYear = $cal->get(AgaviDateDefinitions::YEAR);
     if ($cal->get(AgaviDateDefinitions::ERA) == self::BC) {
         $this->fGregorianCutoverYear = 1 - $this->fGregorianCutoverYear;
     }
     $this->fCutoverJulianDay = $cutoverDay;
 }
 /**
  * Queries if the given date is in daylight savings time in
  * this time zone.
  * This method is wasteful since it creates a new AgaviGregorianCalendar and
  * deletes it each time it is called. 
  *
  * @param      float The given time
  * 
  * @return     bool  True if the given date is in daylight savings time,
  *                   false, otherwise.
  * 
  * @author     Dominik del Bondio <*****@*****.**>
  * @author     The ICU Project
  * @since      0.11.0
  */
 public function inDaylightTime($date)
 {
     $cal = new AgaviGregorianCalendar($this);
     $cal->setTime($date);
     return $cal->inDaylightTime();
 }
 /**
  * Creates a new calendar instance with the current time set.
  *
  * @param      mixed This can be either an AgaviLocale, an AgaviTimeZone or
  *                   a string specifying the calendar type.
  *
  * @return     AgaviCalendar The current timezone instance.
  *
  * @author     Dominik del Bondio <*****@*****.**>
  * @since      0.11.0
  */
 public function createCalendar($type = null)
 {
     $locale = $this->getCurrentLocale();
     $calendarType = null;
     $zone = null;
     $time = null;
     if ($type instanceof AgaviLocale) {
         $locale = $type;
     } elseif ($type instanceof AgaviTimeZone) {
         $zone = $type;
     } elseif ($type instanceof DateTime) {
         $time = $type;
     } elseif (is_int($type)) {
         $time = $type * AgaviDateDefinitions::MILLIS_PER_SECOND;
     } elseif ($type !== null) {
         $calendarType = $type;
     }
     if ($time === null) {
         $time = AgaviCalendar::getNow();
     }
     if (!$zone) {
         if ($locale->getLocaleTimeZone()) {
             $zone = $this->createTimeZone($locale->getLocaleTimeZone());
         }
     }
     if (!$calendarType) {
         $calendarType = $locale->getLocaleCalendar();
         if (!$calendarType) {
             $calendarType = AgaviCalendar::GREGORIAN;
         }
     }
     switch ($calendarType) {
         case AgaviCalendar::GREGORIAN:
             $c = new AgaviGregorianCalendar($this);
             break;
         default:
             throw new AgaviException('Calendar type ' . $calendarType . ' not supported');
     }
     // Now, reset calendar to default state:
     if ($zone) {
         $c->setTimeZone($zone);
     }
     if ($time instanceof DateTime) {
         $tzName = $time->getTimezone()->getName();
         if (version_compare(PHP_VERSION, '5.3', '<')) {
             // when a datetime object is created with an timezone offset like in '2005-02-21 00:00:00+01:00'
             // php falsely returns the name of the current default timezone as the name of the datetimes timezone
             // but luckily timezone abbreviation (T) is GMT name (GMT-0200) of the timezone
             // to not accidentally report dates which are really in the default timezone the name is explicitly checked
             if ($tzName == date_default_timezone_get()) {
                 $abbr = $time->format('T');
                 if (preg_match('/^GMT[+-]\\d{4}$/', $abbr)) {
                     $tzName = $abbr;
                 }
             }
         }
         if (preg_match('/^[+-0-9]/', $tzName)) {
             $tzName = 'GMT' . $tzName;
         }
         $c->setTimeZone($this->createTimeZone($tzName));
         $dateStr = $time->format('Y z G i s');
         list($year, $doy, $hour, $minute, $second) = explode(' ', $dateStr);
         $c->set(AgaviDateDefinitions::YEAR, $year);
         $c->set(AgaviDateDefinitions::DAY_OF_YEAR, $doy + 1);
         $c->set(AgaviDateDefinitions::HOUR_OF_DAY, $hour);
         $c->set(AgaviDateDefinitions::MINUTE, $minute);
         $c->set(AgaviDateDefinitions::SECOND, $second);
         // complete the calendar
         $c->getAll();
     } else {
         $c->setTime($time);
         // let the new calendar have the current time.
     }
     return $c;
 }