<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 encoding=utf-8: */
// +----------------------------------------------------------------------+
// | Eventum - Issue Tracking System |
// +----------------------------------------------------------------------+
// | Copyright (c) 2003 - 2008 MySQL AB |
// | Copyright (c) 2008 - 2009 Sun Microsystem Inc. |
// | |
// | This program is free software; you can redistribute it and/or modify |
// | it under the terms of the GNU General Public License as published by |
// | the Free Software Foundation; either version 2 of the License, or |
// | (at your option) any later version. |
// | |
// | This program is distributed in the hope that it will be useful, |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// | GNU General Public License for more details. |
// | |
// | You should have received a copy of the GNU General Public License |
// | along with this program; if not, write to: |
// | |
// | Free Software Foundation, Inc. |
// | 59 Temple Place - Suite 330 |
// | Boston, MA 02111-1307, USA. |
// +----------------------------------------------------------------------+
// | Authors: João Prado Maia <hide@address.com> |
// +----------------------------------------------------------------------+
//
// @(#) $Id: class.date.php 3797 2009-01-12 20:14:39Z balsdorf $
//
// this line needed to make sure PEAR knows all eventum dates are stored as UTC (GMT).
$_DATE_TIMEZONE_DEFAULT = 'UTC';
require_once(APP_INC_PATH . "class.auth.php");
require_once(APP_INC_PATH . "class.prefs.php");
require_once(APP_PEAR_PATH . "Date.php");
if (!defined('APP_DEFAULT_TIMEZONE')) {
define('APP_DEFAULT_TIMEZONE', 'UTC');
}
define("SECOND", 1);
define("MINUTE", SECOND * 60);
define("HOUR", MINUTE * 60);
define("DAY", HOUR * 24);
define("WEEK", DAY * 7);
define("MONTH", WEEK * 4);
define("YEAR", MONTH * 12);
/**
* Class to handle date convertion issues, which enable the
* application of storing all dates in GMT dates and allowing each
* user to specify a timezone that is supposed to be used across the
* pages.
*
* @version 1.0
* @author João Prado Maia <hide@address.com>
*/
class Date_API
{
/**
* Returns whether the given hour is AM or not.
*
* @access public
* @param integer $hour The hour number
* @return boolean
*/
function isAM($hour)
{
if (($hour >= 0) && ($hour <= 11)) {
return true;
} else {
return false;
}
}
/**
* Returns whether the given hour is PM or not.
*
* @access public
* @param integer $hour The hour number
* @return boolean
*/
function isPM($hour)
{
if (($hour >= 12) && ($hour <= 23)) {
return true;
} else {
return false;
}
}
/**
* Creates a new Date Object initialized to the current date/time in the
* GMT timezone by default. A date optionally
* passed in may be in the ISO 8601, TIMESTAMP or UNIXTIME format,
* or another Date object. If no date is passed, the current date/time
* is used.
*
* Format parameter should be one of the specified DATE_FORMAT_* constants:
*
* <code>DATE_FORMAT_ISO</code>
* - 'YYYY-MM-DD HH:MI:SS'
* <code>DATE_FORMAT_ISO_BASIC</code>
* - 'YYYYMMSSTHHMMSS(Z|(+/-)HHMM)?'
* <code>DATE_FORMAT_ISO_EXTENDED</code>
* - 'YYYY-MM-SSTHH:MM:SS(Z|(+/-)HH:MM)?'
* <code>DATE_FORMAT_ISO_EXTENDED_MICROTIME</code>
* - 'YYYY-MM-SSTHH:MM:SS(.S*)?(Z|(+/-)HH:MM)?'
* <code>DATE_FORMAT_TIMESTAMP</code>
* - 'YYYYMMDDHHMMSS'
* <code>DATE_FORMAT_UNIXTIME'</code>
* - long integer of the no of seconds since
* the Unix Epoch
* (1st January 1970 00.00.00 GMT)
*
* @param mixed $date optional ISO 8601 date/time to initialize;
* or, a Unix time stamp
* @param int $format optional format constant
* (DATE_FORMAT_*) of the input date.
* This parameter is not needed,
* except to force the setting of the
* date from a Unix time-stamp
* (DATE_FORMAT_UNIXTIME).
*
* @return Object Date in GMT timezone
* @access public
* @see new Date()
*/
function getDateGMT($date = null, $format = DATE_FORMAT_ISO)
{
$dt = new Date();
$dt->toUTC();
if (is_a($date, 'Date')) {
$dt->copy($date);
} else {
if (!is_null($date)) {
$dt->setDate($date, $format);
} else {
$dt->setDate(gmdate("Y-m-d H:i:s"));
}
}
return $dt;
}
/**
* Returns the current UNIX timestamp in the GMT timezone.
*
* @access public
* @return integer The current UNIX timestamp in GMT
*/
function getCurrentUnixTimestampGMT()
{
return gmmktime();
}
/**
* Method used to get a pretty-like formatted time output for the
* difference in time between two unix timestamps.
*
* @access public
* @param integer $now_ts The current UNIX timestamp
* @param integer $old_ts The old UNIX timestamp
* @return string The formatted difference in time
*/
function getFormattedDateDiff($now_ts, $old_ts)
{
$value = (integer) (($now_ts - $old_ts) / DAY);
$ret = sprintf("%d", round($value, 1)) . "d";
$mod = (integer) (($now_ts - $old_ts) % DAY);
$mod = (integer) ($mod / HOUR);
return $ret . " " . $mod . "h";
}
/**
* Method used to get the user's current time (timezone included) as
* a UNIX timestamp.
*
* @access public
* @param integer $timestamp The current UNIX timestamp
* @param string $timezone The needed timezone
* @return integer The UNIX timestamp representing the user's current time
*/
function getUnixTimestamp($timestamp, $timezone = FALSE)
{
if (!$timezone) {
$timezone = Date_API::getPreferredTimezone();
}
$date = new Date($timestamp);
// now convert to another timezone and return the timestamp
$date->convertTZById($timezone);
return $date->getDate(DATE_FORMAT_UNIXTIME);
}
/**
* Method used to get the current date in the GMT timezone in an
* RFC822 compliant format.
*
* @access public
* @return string The current GMT date
* @param string $timezone The needed timezone
*/
function getRFC822Date($timestamp, $timezone = FALSE)
{
if (!$timezone) {
$timezone = Date_API::getPreferredTimezone();
}
$date = new Date($timestamp);
// now convert to another timezone and return the date
$date->convertTZById($timezone);
return $date->format('%a, %d %b %Y %H:%M:%S') . " GMT";
}
/**
* Method used to get the current date in the GMT timezone.
*
* @access public
* @return string The current GMT date in DATE_FORMAT_ISO format.
*/
function getCurrentDateGMT()
{
return gmdate('Y-m-d H:i:s');
}
/**
* Method used to get the full list of available timezones to be
* presented to the user.
*
* @access public
* @return array The list of timezones
*/
function getTimezoneList()
{
return Date_TimeZone::getAvailableIDs();
}
/**
* Method used to get the proper short name for a given date.
*
* @access public
* @param object $date The Date object
* @return string The timezone short name
* @note PEAR Date 1.5.0 Includes this method itself.
*/
function getTimezoneShortName($date)
{
if ($date->inDaylightTime()) {
return $date->tz->getDSTShortName();
} else {
return $date->tz->getShortName();
}
}
/**
* Method used to get the proper timezone short name for the current date
* and time on the given user's timezone.
*
* @access public
* @param object $date The Date object
* @return string The timezone short name
*/
function getTimezoneShortNameByUser($usr_id)
{
$date = new Date();
$date->convertTZById(Date_API::getPreferredTimezone($usr_id));
return Date_API::getTimezoneShortName($date);
}
/**
* Method used to get the formatted date for a specific timestamp
* and a specific timezone, provided by the user' preference.
*
* @access public
* @param string $ts The date timestamp to be formatted
* @param string $timezone The timezone name
* @return string
*/
function getFormattedDate($ts, $timezone = FALSE)
{
if ($timezone === FALSE) {
$timezone = Date_API::getPreferredTimezone();
}
$date = self::getDateGMT($ts);
// now convert to another timezone and return the date
$date->convertTZById($timezone);
return $date->format('%a, %d %b %Y, %H:%M:%S %Z');
}
/**
* Method used to get the formatted date for a specific timestamp
* and a specific timezone, provided by the user' preference.
*
* @access public
* @param string $timestamp The date timestamp to be formatted
* @param boolean $convert If the timestamp should be converted to the preferred timezone
* @return string
*/
function getSimpleDate($timestamp, $convert = true)
{
if (empty($timestamp)) {
return '';
}
$date = new Date($timestamp);
// now convert to another timezone and return the date
if ($convert) {
$timezone = Date_API::getPreferredTimezone();
$date->convertTZById($timezone);
}
return $date->format('%d %b %Y');
}
/**
* Method used to get the timezone preferred by the user.
*
* @access public
* @param integer $usr_id The user ID
* @return string The timezone preferred by the user
*/
function getPreferredTimezone($usr_id = FALSE)
{
if ($usr_id === FALSE) {
$usr_id = Auth::getUserID();
}
if (empty($usr_id)) {
return Date_API::getDefaultTimezone();
}
$prefs = Prefs::get($usr_id);
if (empty($prefs["timezone"])) {
return Date_API::getDefaultTimezone();
} else {
return $prefs["timezone"];
}
}
/**
* Method used to get the application default timezone.
*
* @access public
* @return string The default timezone
*/
function getDefaultTimezone()
{
return APP_DEFAULT_TIMEZONE;
}
/**
* Method used to convert the user date (that is in a specific timezone) to
* a GMT date.
*
* @access public
* @param string $date The date in use timezone
* @return string The date in the GMT timezone
*/
function convertDateGMT($date)
{
$dt = new Date($date);
$dt->setTZbyID(Date_API::getPreferredTimezone());
$dt->toUTC();
return $dt->format('%Y-%m-%d %H:%M:%S');
}
/**
* Method used to convert a unix timestamp date to a GMT date.
*
* @access public
* @param integer $timestamp The user based date
* @return string The date in the GMT timezone
*/
function convertDateGMTByTS($timestamp)
{
return gmdate('Y-m-d H:i:s', $timestamp);
}
/**
* Returns a list of weeks (May 2 - May 8, May 9 - May 15).
*
* @access public
* @param integer $weeks_past The number of weeks in the past to include.
* @param integer $weeks_future The number of weeks in the future to include.
* @return array An array of weeks.
*/
function getWeekOptions($weeks_past, $weeks_future)
{
$options = array();
// get current week details
$current_start = date("U") - (DAY * (date("w") - 1));
// previous weeks
for ($week = $weeks_past; $week > 0; $week--) {
$option = Date_API::formatWeekOption($current_start - ($week * WEEK));
$options[$option[0]] = $option[1];
}
$option = Date_API::formatWeekOption($current_start);
$options[$option[0]] = $option[1];
// future weeks
for ($week = 1; $week <= $weeks_future; $week++) {
$option = Date_API::formatWeekOption($current_start + ($week * WEEK));
$options[$option[0]] = $option[1];
}
return $options;
}
/**
* Returns the current week in the same format formatWeekOption users.
*
* @access public
* @return string A string containg the current week.
*/
function getCurrentWeek()
{
$value_format = "Y-m-d";
$start = date("U") - (DAY * (date("w") - 1));
return date($value_format, $start) . "_" . date($value_format, ($start + (DAY * 6)));
}
/**
* Formats a given week start and week end to a format useable by getWeekOptions().
*
* @access private
* @param integer $start The start date of the week.
* @return array An array usable as an option in getWeekOptions.
*/
function formatWeekOption($start)
{
$value_format = "Y-m-d";
$display_format = "M jS";
$end = ($start + (DAY * 6));
$value = date($value_format, $start) . "_" . date($value_format, $end);
$display = date($display_format, $start) . " - " . date($display_format, $end);
return array($value,$display);
}
}
// benchmarking the included file (aka setup time)
if (APP_BENCHMARK) {
$GLOBALS['bench']->setMarker('Included Date_API Class');
}