diff options
Diffstat (limited to 'core/Date.php')
-rw-r--r-- | core/Date.php | 425 |
1 files changed, 123 insertions, 302 deletions
diff --git a/core/Date.php b/core/Date.php index 87fd5d55a0..f6aefce606 100644 --- a/core/Date.php +++ b/core/Date.php @@ -18,192 +18,66 @@ class Piwik_Date { /** - * Builds a Piwik_Date object - * - * @param int timestamp - */ - protected function __construct( $timestamp, $timezone = 'UTC') - { - if(!is_int( $timestamp )) - { - throw new Exception("Piwik_Date is expecting a unix timestamp"); - } - $this->timezone = $timezone; - $this->timestamp = $timestamp ; - } - - - /** * Returns a Piwik_Date objects. + * Accepts strings 'today' 'yesterday' or any YYYY-MM-DD or timestamp * - * @param string $strDate 'today' 'yesterday' or any YYYY-MM-DD or timestamp - * @param string $timezone if specified, the dateString will be relative to this $timezone. - * For example, today in UTC+12 will be a timestamp in the future for UTC. - * This is different from using ->setTimezone() - * @return Piwik_Date + * @param string $strDate + * @return Piwik_Date */ - static public function factory($dateString, $timezone = null) + static public function factory($dateString) { - if($dateString == 'now') - { - $date = self::now(); - } - elseif($dateString == 'today') + if($dateString == 'today') { - $date = self::today(); + return self::today(); } - elseif($dateString == 'yesterday') + if($dateString == 'yesterday') { - $date = self::yesterday(); + return self::yesterday(); } - elseif($dateString == 'yesterdaySameTime') - { - $date = self::yesterdaySameTime(); - } - elseif (!is_int($dateString) + if (!is_int($dateString) && ($dateString = strtotime($dateString)) === false) { - throw new Exception(Piwik_TranslateException('General_ExceptionInvalidDateFormat', array("YYYY-MM-DD, or 'today' or 'yesterday'", "strtotime", "http://php.net/strtotime"))); - } - else - { - $date = new Piwik_Date($dateString); - } - if(is_null($timezone)) - { - return $date; - } - - // manually adjust for UTC timezones - $utcOffset = self::extractUtcOffset($timezone); - if($utcOffset !== false) - { - return $date->addHour($utcOffset); + throw new Exception("Date format must be: YYYY-MM-DD, or 'today' or 'yesterday' or any keyword supported by the strtotime function (see http://php.net/strtotime for more information)"); } - - date_default_timezone_set($timezone); - $datetime = $date->getDatetime(); - date_default_timezone_set('UTC'); - - $date = Piwik_Date::factory(strtotime($datetime)); - - return $date; + return new Piwik_Date($dateString); } - /* - * The stored timestamp is always UTC based. - * The returned timestamp via getTimestamp() will have the conversion applied - */ protected $timestamp = null; - - /* - * Timezone the current date object is set to. - * Timezone will only affect the returned timestamp via getTimestamp() - */ - protected $timezone = 'UTC'; - - const DATE_TIME_FORMAT = 'Y-m-d H:i:s'; - - /** - * Returns the datetime start in UTC - * - * @return string - */ - function getDateStartUTC() - { - $dateStartUTC = date('Y-m-d', $this->timestamp); - $date = Piwik_Date::factory($dateStartUTC)->setTimezone($this->timezone); - return $date->toString(self::DATE_TIME_FORMAT); - } - /** - * Returns the datetime of the current timestamp - * - * @return string - */ - function getDatetime() - { - return $this->toString(self::DATE_TIME_FORMAT); - } - - /** - * Returns the datetime end in UTC - * - * @return string - */ - function getDateEndUTC() - { - $dateEndUTC = date('Y-m-d 23:59:59', $this->timestamp); - $date = Piwik_Date::factory($dateEndUTC)->setTimezone($this->timezone); - return $date->toString(self::DATE_TIME_FORMAT); - } - /** - * Returns a new date object, copy of $this, with the timezone set - * This timezone is used to offset the UTC timestamp returned by @see getTimestamp() - * Doesn't modify $this - * - * @param string $timezone 'UTC', 'Europe/London', ... + * Returns the unix timestamp of the date + * + * @return int */ - public function setTimezone($timezone) + public function getTimestamp() { - return new Piwik_Date($this->timestamp, $timezone); + return $this->timestamp; } /** - * Helper function that returns the offset in the timezone string 'UTC+14' - * Returns false if the timezone is not UTC+X or UTC-X + * Builds a Piwik_Date object * - * @param $timezone - * @return int or false + * @param int timestamp */ - static protected function extractUtcOffset($timezone) + protected function __construct( $date ) { - if($timezone == 'UTC') + if(!is_int( $date )) { - return 0; - } - $start = substr($timezone, 0, 4); - if($start != 'UTC-' - && $start != 'UTC+') - { - return false; - } - $offset = (float)substr($timezone, 4); - if($start == 'UTC-') { - $offset = -$offset; + throw new Exception("Piwik_Date is expecting a unix timestamp"); } - return $offset; + $this->timestamp = $date ; } /** - * Returns the unix timestamp of the date in UTC, - * converted from the date timezone - * - * @return int + * Sets the time part of the date + * Doesn't modify $this + * + * @param string $time HH:MM:SS + * @return Piwik_Date The new date with the time part set */ - public function getTimestamp() + public function setTime($time) { - $utcOffset = self::extractUtcOffset($this->timezone); - if($utcOffset !== false) { - return (int)($this->timestamp - $utcOffset * 3600); - } - // @fixme - // The following code seems clunky - I thought the DateTime php class would allow to return timestamps - // after applying the timezone offset. Instead, the underlying timestamp is not changed. - // I decided to get the date without the timezone information, and create the timestamp from the truncated string. - // Unit tests pass (@see Date.test.php) but I'm pretty sure this is not the right way to do it - date_default_timezone_set($this->timezone); - $dtzone = timezone_open('UTC'); - $time = date('r', $this->timestamp); - $dtime = date_create($time); - date_timezone_set($dtime, $dtzone); - $dateWithTimezone = date_format($dtime, 'r'); - $dateWithoutTimezone = substr($dateWithTimezone, 0, -6); - $timestamp = strtotime($dateWithoutTimezone); - date_default_timezone_set('UTC'); - - return (int)$timestamp; + return new Piwik_Date( strtotime( $this->get("j F Y") . " $time")); } /** @@ -239,7 +113,7 @@ class Piwik_Date { return date($part, $this->getTimestamp()); } - + /** * @see toString() * @@ -251,114 +125,6 @@ class Piwik_Date } /** - * Compares the week of the current date against the given $date - * Returns 0 if equal, -1 if current week is earlier or 1 if current week is later - * Example: 09.Jan.2007 13:07:25 -> compareWeek(2); -> 0 - * - * @param Piwik_Date $date - * @return integer 0 = equal, 1 = later, -1 = earlier - */ - public function compareWeek(Piwik_Date $date) - { - $currentWeek = date('W', $this->getTimestamp()); - $toCompareWeek = date('W', $date->getTimestamp()); - if( $currentWeek == $toCompareWeek) - { - return 0; - } - if( $currentWeek < $toCompareWeek) - { - return -1; - } - return 1; - } - - /** - * Compares the month of the current date against the given $date month - * Returns 0 if equal, -1 if current month is earlier or 1 if current month is later - * For example: 10.03.2000 -> 15.03.1950 -> 0 - * - * @param Piwik_Date $month Month to compare - * @return integer 0 = equal, 1 = later, -1 = earlier - */ - function compareMonth( Piwik_Date $date ) - { - $currentMonth = date('n', $this->getTimestamp()); - $toCompareMonth = date('n', $date->getTimestamp()); - if( $currentMonth == $toCompareMonth) - { - return 0; - } - if( $currentMonth < $toCompareMonth) - { - return -1; - } - return 1; - } - - /** - * Returns true if current date is today - * - * @return bool - */ - public function isToday() - { - return $this->toString('Y-m-d') === Piwik_Date::factory('today', $this->timezone)->toString('Y-m-d'); - } - - /** - * Returns a date object set to now (same as today, except that the time is also set) - * - * @return Piwik_Date - */ - static public function now() - { - return new Piwik_date(time()); - } - - /** - * Returns a date object set to today midnight - * - * @return Piwik_Date - */ - static public function today() - { - return new Piwik_Date(strtotime(date("Y-m-d 00:00:00"))); - } - - /** - * Returns a date object set to yesterday midnight - * - * @return Piwik_Date - */ - static public function yesterday() - { - return new Piwik_Date(strtotime("yesterday")); - } - - /** - * Returns a date object set to yesterday same time of day - * - * @return Piwik_Date - */ - static public function yesterdaySameTime() - { - return new Piwik_Date(strtotime("yesterday ".date('H:i:s'))); - } - - /** - * Sets the time part of the date - * Doesn't modify $this - * - * @param string $time HH:MM:SS - * @return Piwik_Date The new date with the time part set - */ - public function setTime($time) - { - return new Piwik_Date( strtotime( date("Y-m-d", $this->timestamp) . " $time"), $this->timezone); - } - - /** * Sets a new day * Returned is the new date object * Doesn't modify $this @@ -368,7 +134,7 @@ class Piwik_Date */ public function setDay( $day ) { - $ts = $this->timestamp; + $ts = $this->getTimestamp(); $result = mktime( date('H', $ts), date('i', $ts), @@ -377,7 +143,7 @@ class Piwik_Date 1, date('Y', $ts) ); - return new Piwik_Date( $result, $this->timezone ); + return new Piwik_Date( $result ); } /** @@ -390,7 +156,7 @@ class Piwik_Date */ public function setYear( $year ) { - $ts = $this->timestamp; + $ts = $this->getTimestamp(); $result = mktime( date('H', $ts), date('i', $ts), @@ -399,9 +165,11 @@ class Piwik_Date date('j', $ts), $year ); - return new Piwik_Date( $result, $this->timezone ); + return new Piwik_Date( $result ); } + + /** * Subtracts days from the existing date object and returns a new Piwik_Date object * Returned is the new date object @@ -415,8 +183,8 @@ class Piwik_Date { return clone $this; } - $ts = strtotime("-$n day", $this->timestamp); - return new Piwik_Date( $ts, $this->timezone ); + $ts = strtotime("-$n day", $this->getTimestamp()); + return new Piwik_Date( $ts ); } /** @@ -432,7 +200,7 @@ class Piwik_Date { return clone $this; } - $ts = $this->timestamp; + $ts = $this->getTimestamp(); $result = mktime( date('H', $ts), date('i', $ts), @@ -441,8 +209,23 @@ class Piwik_Date 1, // we set the day to 1 date('Y', $ts) ); - return new Piwik_Date( $result, $this->timezone ); + return new Piwik_Date( $result ); } + + /** + * Returns a representation of a date or datepart + * + * @param string OPTIONAL Part of the date to return, if null the timestamp is returned + * @return integer|string date or datepart + */ + public function get($part = null) + { + if(is_null($part)) + { + return $this->getTimestamp(); + } + return date($part, $this->getTimestamp()); + } /** * Returns a localized date string, given a template. @@ -464,12 +247,12 @@ class Piwik_Date "%longDay%" => Piwik_Translate('General_LongDay_'.$dayOfWeek), "%longYear%" => $this->toString('Y'), "%shortYear%" => $this->toString('y'), - "%time%" => $this->toString('H:i:s') + "%time%" => $this->toString('H:i:s T') ); $out = str_replace(array_keys($patternToValue), array_values($patternToValue), $template); return $out; } - + /** * Adds days to the existing date object. * Returned is the new date object @@ -480,44 +263,82 @@ class Piwik_Date */ public function addDay( $n ) { - $ts = strtotime("+$n day", $this->timestamp); - return new Piwik_Date( $ts, $this->timezone ); + $ts = strtotime("+$n day", $this->getTimestamp()); + return new Piwik_Date( $ts ); } - + /** - * Adds hours to the existing date object. - * Returned is the new date object - * Doesn't modify $this - * - * @param int Number of hours to add - * @return Piwik_Date new date + * Compares the week of the current date against the given $date + * Returns 0 if equal, -1 if current week is earlier or 1 if current week is later + * Example: 09.Jan.2007 13:07:25 -> compareWeek(2); -> 0 + * + * @param Piwik_Date $date + * @return integer 0 = equal, 1 = later, -1 = earlier */ - public function addHour( $n ) + public function compareWeek(Piwik_Date $date) + { + $currentWeek = date('W', $this->getTimestamp()); + $toCompareWeek = date('W', $date->getTimestamp()); + if( $currentWeek == $toCompareWeek) + { + return 0; + } + if( $currentWeek < $toCompareWeek) + { + return -1; + } + return 1; + } + /** + * Compares the month of the current date against the given $date month + * Returns 0 if equal, -1 if current month is earlier or 1 if current month is later + * For example: 10.03.2000 -> 15.03.1950 -> 0 + * + * @param Piwik_Date $month Month to compare + * @return integer 0 = equal, 1 = later, -1 = earlier + */ + function compareMonth( Piwik_Date $date ) { - $minutes = 0; - if($n != round($n)) + $currentMonth = date('n', $this->getTimestamp()); + $toCompareMonth = date('n', $date->getTimestamp()); + if( $currentMonth == $toCompareMonth) { - $minutes = abs($n - floor($n)) * 60; - $n = floor($n); + return 0; } - if($n > 0 ) + if( $currentMonth < $toCompareMonth) { - $n = '+'.$n; + return -1; } - $ts = strtotime("$n hour $minutes minutes", $this->timestamp); - return new Piwik_Date( $ts, $this->timezone ); + return 1; } - + /** - * Substract hour to the existing date object. - * Returned is the new date object - * Doesn't modify $this - * - * @param int Number of hours to substract - * @return Piwik_Date new date - */ - public function subHour( $n ) + * Returns true if current date is today + * + * @return bool + */ + public function isToday() { - return $this->addHour(-$n); + return $this->get('Y-m-d') === date('Y-m-d', time()); + } + + /** + * Returns a date object set to today midnight + * + * @return Piwik_Date + */ + static public function today() + { + return new Piwik_Date(strtotime(date("Y-m-d 00:00:00"))); + } + + /** + * Returns a date object set to yesterday midnight + * + * @return Piwik_Date + */ + static public function yesterday() + { + return new Piwik_Date(strtotime("yesterday")); } } |