summaryrefslogtreecommitdiff
path: root/system/helpers/date.php
diff options
context:
space:
mode:
authorBharat Mediratta <bharat@menalto.com>2009-05-27 15:11:53 -0700
committerBharat Mediratta <bharat@menalto.com>2009-05-27 15:11:53 -0700
commit12fe58d997d2066dc362fd393a18b4e5da190513 (patch)
tree3ad8e5afb77829e1541ec96d86785760d65c04ac /system/helpers/date.php
parent00f47d4ddddcd1902db817018dd79ac01bcc8e82 (diff)
Rename 'kohana' to 'system' to conform to the Kohana filesystem layout. I'm comfortable with us not clearly drawing the distinction about the fact that it's Kohana.
Diffstat (limited to 'system/helpers/date.php')
-rw-r--r--system/helpers/date.php405
1 files changed, 405 insertions, 0 deletions
diff --git a/system/helpers/date.php b/system/helpers/date.php
new file mode 100644
index 00000000..7d5a9ab6
--- /dev/null
+++ b/system/helpers/date.php
@@ -0,0 +1,405 @@
+<?php defined('SYSPATH') OR die('No direct access allowed.');
+/**
+ * Date helper class.
+ *
+ * $Id: date.php 4316 2009-05-04 01:03:54Z kiall $
+ *
+ * @package Core
+ * @author Kohana Team
+ * @copyright (c) 2007-2008 Kohana Team
+ * @license http://kohanaphp.com/license.html
+ */
+class date_Core {
+
+ /**
+ * Converts a UNIX timestamp to DOS format.
+ *
+ * @param integer UNIX timestamp
+ * @return integer
+ */
+ public static function unix2dos($timestamp = FALSE)
+ {
+ $timestamp = ($timestamp === FALSE) ? getdate() : getdate($timestamp);
+
+ if ($timestamp['year'] < 1980)
+ {
+ return (1 << 21 | 1 << 16);
+ }
+
+ $timestamp['year'] -= 1980;
+
+ // What voodoo is this? I have no idea... Geert can explain it though,
+ // and that's good enough for me.
+ return ($timestamp['year'] << 25 | $timestamp['mon'] << 21 |
+ $timestamp['mday'] << 16 | $timestamp['hours'] << 11 |
+ $timestamp['minutes'] << 5 | $timestamp['seconds'] >> 1);
+ }
+
+ /**
+ * Converts a DOS timestamp to UNIX format.
+ *
+ * @param integer DOS timestamp
+ * @return integer
+ */
+ public static function dos2unix($timestamp = FALSE)
+ {
+ $sec = 2 * ($timestamp & 0x1f);
+ $min = ($timestamp >> 5) & 0x3f;
+ $hrs = ($timestamp >> 11) & 0x1f;
+ $day = ($timestamp >> 16) & 0x1f;
+ $mon = ($timestamp >> 21) & 0x0f;
+ $year = ($timestamp >> 25) & 0x7f;
+
+ return mktime($hrs, $min, $sec, $mon, $day, $year + 1980);
+ }
+
+ /**
+ * Returns the offset (in seconds) between two time zones.
+ * @see http://php.net/timezones
+ *
+ * @param string timezone that to find the offset of
+ * @param string|boolean timezone used as the baseline
+ * @return integer
+ */
+ public static function offset($remote, $local = TRUE)
+ {
+ static $offsets;
+
+ // Default values
+ $remote = (string) $remote;
+ $local = ($local === TRUE) ? date_default_timezone_get() : (string) $local;
+
+ // Cache key name
+ $cache = $remote.$local;
+
+ if (empty($offsets[$cache]))
+ {
+ // Create timezone objects
+ $remote = new DateTimeZone($remote);
+ $local = new DateTimeZone($local);
+
+ // Create date objects from timezones
+ $time_there = new DateTime('now', $remote);
+ $time_here = new DateTime('now', $local);
+
+ // Find the offset
+ $offsets[$cache] = $remote->getOffset($time_there) - $local->getOffset($time_here);
+ }
+
+ return $offsets[$cache];
+ }
+
+ /**
+ * Number of seconds in a minute, incrementing by a step.
+ *
+ * @param integer amount to increment each step by, 1 to 30
+ * @param integer start value
+ * @param integer end value
+ * @return array A mirrored (foo => foo) array from 1-60.
+ */
+ public static function seconds($step = 1, $start = 0, $end = 60)
+ {
+ // Always integer
+ $step = (int) $step;
+
+ $seconds = array();
+
+ for ($i = $start; $i < $end; $i += $step)
+ {
+ $seconds[$i] = ($i < 10) ? '0'.$i : $i;
+ }
+
+ return $seconds;
+ }
+
+ /**
+ * Number of minutes in an hour, incrementing by a step.
+ *
+ * @param integer amount to increment each step by, 1 to 30
+ * @return array A mirrored (foo => foo) array from 1-60.
+ */
+ public static function minutes($step = 5)
+ {
+ // Because there are the same number of minutes as seconds in this set,
+ // we choose to re-use seconds(), rather than creating an entirely new
+ // function. Shhhh, it's cheating! ;) There are several more of these
+ // in the following methods.
+ return date::seconds($step);
+ }
+
+ /**
+ * Number of hours in a day.
+ *
+ * @param integer amount to increment each step by
+ * @param boolean use 24-hour time
+ * @param integer the hour to start at
+ * @return array A mirrored (foo => foo) array from start-12 or start-23.
+ */
+ public static function hours($step = 1, $long = FALSE, $start = NULL)
+ {
+ // Default values
+ $step = (int) $step;
+ $long = (bool) $long;
+ $hours = array();
+
+ // Set the default start if none was specified.
+ if ($start === NULL)
+ {
+ $start = ($long === FALSE) ? 1 : 0;
+ }
+
+ $hours = array();
+
+ // 24-hour time has 24 hours, instead of 12
+ $size = ($long === TRUE) ? 23 : 12;
+
+ for ($i = $start; $i <= $size; $i += $step)
+ {
+ $hours[$i] = $i;
+ }
+
+ return $hours;
+ }
+
+ /**
+ * Returns AM or PM, based on a given hour.
+ *
+ * @param integer number of the hour
+ * @return string
+ */
+ public static function ampm($hour)
+ {
+ // Always integer
+ $hour = (int) $hour;
+
+ return ($hour > 11) ? 'PM' : 'AM';
+ }
+
+ /**
+ * Adjusts a non-24-hour number into a 24-hour number.
+ *
+ * @param integer hour to adjust
+ * @param string AM or PM
+ * @return string
+ */
+ public static function adjust($hour, $ampm)
+ {
+ $hour = (int) $hour;
+ $ampm = strtolower($ampm);
+
+ switch ($ampm)
+ {
+ case 'am':
+ if ($hour == 12)
+ $hour = 0;
+ break;
+ case 'pm':
+ if ($hour < 12)
+ $hour += 12;
+ break;
+ }
+
+ return sprintf('%02s', $hour);
+ }
+
+ /**
+ * Number of days in month.
+ *
+ * @param integer number of month
+ * @param integer number of year to check month, defaults to the current year
+ * @return array A mirrored (foo => foo) array of the days.
+ */
+ public static function days($month, $year = FALSE)
+ {
+ static $months;
+
+ // Always integers
+ $month = (int) $month;
+ $year = (int) $year;
+
+ // Use the current year by default
+ $year = ($year == FALSE) ? date('Y') : $year;
+
+ // We use caching for months, because time functions are used
+ if (empty($months[$year][$month]))
+ {
+ $months[$year][$month] = array();
+
+ // Use date to find the number of days in the given month
+ $total = date('t', mktime(1, 0, 0, $month, 1, $year)) + 1;
+
+ for ($i = 1; $i < $total; $i++)
+ {
+ $months[$year][$month][$i] = $i;
+ }
+ }
+
+ return $months[$year][$month];
+ }
+
+ /**
+ * Number of months in a year
+ *
+ * @return array A mirrored (foo => foo) array from 1-12.
+ */
+ public static function months()
+ {
+ return date::hours();
+ }
+
+ /**
+ * Returns an array of years between a starting and ending year.
+ * Uses the current year +/- 5 as the max/min.
+ *
+ * @param integer starting year
+ * @param integer ending year
+ * @return array
+ */
+ public static function years($start = FALSE, $end = FALSE)
+ {
+ // Default values
+ $start = ($start === FALSE) ? date('Y') - 5 : (int) $start;
+ $end = ($end === FALSE) ? date('Y') + 5 : (int) $end;
+
+ $years = array();
+
+ // Add one, so that "less than" works
+ $end += 1;
+
+ for ($i = $start; $i < $end; $i++)
+ {
+ $years[$i] = $i;
+ }
+
+ return $years;
+ }
+
+ /**
+ * Returns time difference between two timestamps, in human readable format.
+ *
+ * @param integer timestamp
+ * @param integer timestamp, defaults to the current time
+ * @param string formatting string
+ * @return string|array
+ */
+ public static function timespan($time1, $time2 = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds')
+ {
+ // Array with the output formats
+ $output = preg_split('/[^a-z]+/', strtolower((string) $output));
+
+ // Invalid output
+ if (empty($output))
+ return FALSE;
+
+ // Make the output values into keys
+ extract(array_flip($output), EXTR_SKIP);
+
+ // Default values
+ $time1 = max(0, (int) $time1);
+ $time2 = empty($time2) ? time() : max(0, (int) $time2);
+
+ // Calculate timespan (seconds)
+ $timespan = abs($time1 - $time2);
+
+ // All values found using Google Calculator.
+ // Years and months do not match the formula exactly, due to leap years.
+
+ // Years ago, 60 * 60 * 24 * 365
+ isset($years) and $timespan -= 31556926 * ($years = (int) floor($timespan / 31556926));
+
+ // Months ago, 60 * 60 * 24 * 30
+ isset($months) and $timespan -= 2629744 * ($months = (int) floor($timespan / 2629743.83));
+
+ // Weeks ago, 60 * 60 * 24 * 7
+ isset($weeks) and $timespan -= 604800 * ($weeks = (int) floor($timespan / 604800));
+
+ // Days ago, 60 * 60 * 24
+ isset($days) and $timespan -= 86400 * ($days = (int) floor($timespan / 86400));
+
+ // Hours ago, 60 * 60
+ isset($hours) and $timespan -= 3600 * ($hours = (int) floor($timespan / 3600));
+
+ // Minutes ago, 60
+ isset($minutes) and $timespan -= 60 * ($minutes = (int) floor($timespan / 60));
+
+ // Seconds ago, 1
+ isset($seconds) and $seconds = $timespan;
+
+ // Remove the variables that cannot be accessed
+ unset($timespan, $time1, $time2);
+
+ // Deny access to these variables
+ $deny = array_flip(array('deny', 'key', 'difference', 'output'));
+
+ // Return the difference
+ $difference = array();
+ foreach ($output as $key)
+ {
+ if (isset($$key) AND ! isset($deny[$key]))
+ {
+ // Add requested key to the output
+ $difference[$key] = $$key;
+ }
+ }
+
+ // Invalid output formats string
+ if (empty($difference))
+ return FALSE;
+
+ // If only one output format was asked, don't put it in an array
+ if (count($difference) === 1)
+ return current($difference);
+
+ // Return array
+ return $difference;
+ }
+
+ /**
+ * Returns time difference between two timestamps, in the format:
+ * N year, N months, N weeks, N days, N hours, N minutes, and N seconds ago
+ *
+ * @param integer timestamp
+ * @param integer timestamp, defaults to the current time
+ * @param string formatting string
+ * @return string
+ */
+ public static function timespan_string($time1, $time2 = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds')
+ {
+ if ($difference = date::timespan($time1, $time2, $output) AND is_array($difference))
+ {
+ // Determine the key of the last item in the array
+ $last = end($difference);
+ $last = key($difference);
+
+ $span = array();
+ foreach ($difference as $name => $amount)
+ {
+ if ($amount === 0)
+ {
+ // Skip empty amounts
+ continue;
+ }
+
+ // Add the amount to the span
+ $span[] = ($name === $last ? ' and ' : ', ').$amount.' '.($amount === 1 ? inflector::singular($name) : $name);
+ }
+
+ // If the difference is less than 60 seconds, remove the preceding and.
+ if (count($span) === 1)
+ {
+ $span[0] = ltrim($span[0], 'and ');
+ }
+
+ // Replace difference by making the span into a string
+ $difference = trim(implode('', $span), ',');
+ }
+ elseif (is_int($difference))
+ {
+ // Single-value return
+ $difference = $difference.' '.($difference === 1 ? inflector::singular($output) : $output);
+ }
+
+ return $difference;
+ }
+
+} // End date \ No newline at end of file