<?php
/*
Version 1.0, last update 11/12/2004
All code copyright Corey Tisdale (hide@address.com)
unless otherwise noted. This is freely distributable.
Use it. Tell me how to make it better.
*/
//A class for easy time format conversion
//TO MAKE COMPLIANT WITH PHP v4.x OR LESS, DO THE FOLLOWING:
//1) change the name of
// function __construct
// to
// function DateBuddy
//2)change the internal variable declarations from
// public $someVariable
// or
// protected $someVariable
// to
// var $someVariable
//3)change the internal function declarations from
// protected function Somefunction() {
// or
// private function Somefunction() {
// to
// function Somefunction() {
//USAGE:
// $myVar = new DateBuddy('2004-05-01 04:15:27');
// echo $myVar->GetDate(MYSQL_TIMESTAMP_TIME_FORMAT_STRING);
//OR
// $myVar = new DateBuddy('09/01/1982', USA_TIME_FORMAT);
// echo $myVar->GetDate(ISO_TIME_FORMAT_STRING);
//OR
// $myVar = new DateBuddy('09/01/1982 02:15:13 PM', USA_TIME_FORMAT);
// echo $myVar->year;
// echo $myVar->timestamp;
// echo $myVar->hour;
//OR
// echo Datebuddy::QuickDate();
//OR
// echo Datebuddy::QuickDate(ISO_TIME_FORMAT_STRING, '09/01/1982');
//NOTE: Be careful when using AM and PM without seconds on your
// time. This is when you need to use the special time format
// ALTURA_TIME_FORMAT!!!!!
//These are used by the class
define('UNKNOWN_TIME_FORMAT', 2342);
define('ISO_TIME_FORMAT', 31243);
define('USA_TIME_FORMAT', 432);
define('PHP_TIME_FORMAT', 45667);
//These save some time
define('ISO_TIME_FORMAT_STRING', 'Y/m/d H:i:s');
define('MYSQL_TIMESTAMP_TIME_FORMAT_STRING', 'YmdHis');
define('USA_TIME_FORMAT_STRING', 'm/d/Y H:i:s');
define('PHP_TIME_FORMAT_STRING', 'U');
//Quick reference
define('DAYS', 86400);
class DateBuddy {
public $raw;
public $hour;
public $minute;
public $second;
public $year;
public $month;
public $day;
public $timestamp;
public $format;
protected $regexs;
/**
* @return void
* @param string $date
* @param int $format
* @desc Creates a DateBuddy object corresponding to the date
* represented by $date in the format $format. DateBuddy
* WILL TRY TO FIGURE OUT THE DATE FORMAT IF ONE IS NOT
* GIVEN, BUT DateBuddy MAY GUESS INCORRECTLY AND GIVE
* UNEXPECTED RESULTS! IT IS USUALLY BETTER TO SPECIFY
* A FORMAT!!! Unknown formats use strtotime(). A null
* date initializes the object to now using time()
*/
function __construct($date=null, $format=UNKNOWN_TIME_FORMAT) {
$this->LoadRegexs(); //Prepare our regexs from an easy to read function
//Make a date buddy for right now if nothing is passed to the constructor.
if (is_null($date)) {
$date = time();
$format = PHP_TIME_FORMAT;
}
$this->raw = $date; //Store the raw data
$this->format = $format; //Tell us the format!
$this->Parse(); //Load up the parts of the date
}
/**
* @return bool
* @desc Parses $this->raw into an internal date representation
* from which other date formats can be generated. The
* internals of this function could change if the
* current algorithm proves to be too processor-intensive.
* The future remains to be seen!
*/
function Parse() {
$result = false;
$this->ClearInfo(); //Make sure no old data persists incase something changed and parse is recalled.
$matches = array();
switch ($this->format) {
case ISO_TIME_FORMAT:
$result = preg_match($this->regexs[$this->format], $this->raw, $matches);
if ($result == 1) {
$this->hour = (isset($matches[4])) ? $matches[4] : 0;
$this->minute = (isset($matches[5])) ? $matches[5] : 0;
$this->second = (isset($matches[6])) ? $matches[6] : 0;
$this->year = (isset($matches[1])) ? $matches[1] : 0;
$this->month = (isset($matches[2])) ? $matches[2] : 0;
$this->day = (isset($matches[3])) ? $matches[3] : 0;
$result = true;
} else {
$result = false;
}
break;
case USA_TIME_FORMAT:
$result = preg_match($this->regexs[$this->format], $this->raw, $matches);
if ($result == 1) {
$this->hour = (isset($matches[4])) ? $matches[4] : 0;
$this->minute = (isset($matches[5])) ? $matches[5] : 0;
$this->second = (isset($matches[6])) ? $matches[6] : 0;
$this->year = (isset($matches[3])) ? $matches[3] : 0;
$this->month = (isset($matches[1])) ? $matches[1] : 0;
$this->day = (isset($matches[2])) ? $matches[2] : 0;
$result = true;
} else {
$result = false;
}
break;
case PHP_TIME_FORMAT:
$this->timestamp = $this->raw;
$this->hour = date('H', $this->timestamp);
$this->minute = date('i', $this->timestamp);
$this->second = date('s', $this->timestamp);
$this->year = date('Y', $this->timestamp);
$this->month = date('m', $this->timestamp);
$this->day = date('d', $this->timestamp);
$this->timestamp = $this->raw;
$result = true;
break;
case UNKNOWN_TIME_FORMAT:
$this->timestamp = strtotime($this->raw);
if ($this->timestamp != -1) {
$this->hour = date('H', $this->timestamp);
$this->minute = date('i', $this->timestamp);
$this->second = date('s', $this->timestamp);
$this->year = date('Y', $this->timestamp);
$this->month = date('m', $this->timestamp);
$this->day = date('d', $this->timestamp);
$result = true;
} else {
$this->timestamp = '';
}
$result = true;
break;
}
//Verify formats
$this->VerifyYearFormat();
$this->VerifyHourFormat( (isset($matches[7]) ? $matches[7] : '') ); //pass it the AM or PM ness of the input
$this->VerifyTimestamp();
return $result;
}
/**
* @return void
* @desc Loads up the known regexs to match known formats
* into the internal variable $this->regexs.
*/
protected function LoadRegexs() {
//Load format regexs into an array indexed by the format constant
$this->regexs = array(
ISO_TIME_FORMAT => '/([\d]{2,4}).?([\d]{1,2}).?([\d]{1,2}).?([\d]{0,2}).?([\d]{0,2}).?([\d]{0,2}).?(AM|PM)?/i',
USA_TIME_FORMAT => '/([\d]{1,2}).?([\d]{1,2}).?([\d]{2,4}).?([\d]{0,2}).?([\d]{0,2}).?([\d]{0,2}).?(AM|PM)?/i',
PHP_TIME_FORMAT => '/(-?[\d]+)/'
);
}
/**
* @return void
* @desc Clears the current internal representation of a date.
*/
protected function ClearInfo() {
$this->hour = '';
$this->minute = '';
$this->second = '';
$this->year = '';
$this->month = '';
$this->day = '';
$this->timestamp = '';
}
/**
* @return void
* @desc Internal utility function to make sure
* the year is in four digit format. Assumes
* 2-digit year dates that would be more than
* 35 years in the future should be past dates.
* Look out for old dates -- they crash systems!
*/
protected function VerifyYearFormat() {
//Format year correctly
if (strlen($this->year) < 4) {
//if this date would be more than 35 years in the future
if ((2000 + $this->year) - date('Y', time()) > 35) {
//put it in the past
$this->year += 1900;
} else {
//put it in the future
$this->year += 2000;
}
}
}
/**
* @return void
* @desc Internal utility function to make sure
* the timestamp variable represents the time
*/
protected function VerifyTimestamp() {
// Make that timestamp from our internal vars!
if ($this->timestamp == '') {
$this->timestamp = mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
}
}
/**
* @return void
* @param string $specs
* @desc Internal utility function to make sure
* the hour is in military time format
*/
protected function VerifyHourFormat($specs = '') {
//adjust the time to military if necessary
if (($this->hour < 12) && (strtolower($specs) == 'pm')) {
$this->hour += 12;
}
}
/**
* @return mixed
* @param string $formatString
* @desc Returns the internal date in the format
* specified by $formatString. Uses the same
* format strings as the php function date().
* Note that a few handy format strings come
* as constants with this class. This way you
* don't have to remember the formats for PHP,
* ISO, or MySQL timestamps off the top of your
* head.
*/
function GetDate($formatString = ISO_TIME_FORMAT_STRING) {
$result = false;
//If we can parse the time, then we do it!
if ($this->timestamp != '') { $result = date($formatString, $this->timestamp); }
return $result;
}
/**
* @return string
* @param string $outgoingFormat
* @param string $date
* @param string $incomingFormat
* @desc Quick function for handling most
* of DateBuddy's uses in one line
* of code. Formats output to
* $outgoingformat, and parses
* $date according to $inputFormat
*/
static function QuickDate($outgoingFormat = ISO_TIME_FORMAT_STRING, $date=null, $incomingFormat=UNKNOWN_TIME_FORMAT) {
$d = new DateBuddy($date, $incomingFormat);
return $d->GetDate($outgoingFormat);
}
}
?>