<?
/*
* Class for handling data values in PHP
*
* This code provides classes for handling data values.
* Features include format guess, internationalisation,
* date calculattions, formatting.
*
* If you write any additional translation files, please
* send a copy to dateutil@mderoo.nl and I will add it to
* the repository
*
* Language files contributed by:
*
* English, Dutch, German: Michiel de Roo
* French: Sylvain CÔME <scome@club-internet.fr>
* Italian: Roberto Legname <legname@betam.it>
* Greek: Tom Dionysiou <tom@united-hellas.com>
* Spanish: José Miguel Santibáñez <jms@caos.cl>
* Czech: Vratislav Cermak <kremik@centrum.cz>
* Brazilian: Claudio Pereira <cpereira@websistemas.com.br>
* Polish: cyplo <cyplo@wp.pl>
* Norwegian: Sten Johnson <Sten.Johnson@no.thalesgroup.com>
* Finnish: taken from KronoClass
* Japanese: taken from KronoClass
* Indonesian: taken from KronoClass
* Danish: taken from ezPublish
* Russian: taken from ezPublish
* Argentinian: taken from ezPublish
*
* Please note that some languages need special font types, like
* iso-8859-2 or hellenic, to be displayed correctly.
*
* Examples:
* See http://www.mderoo.nl/software/dateutil/example.php
*
* @author Michiel de Roo <michiel@belangrijk.nl>, http://www.mderoo.nl
* @copyright 2003, Michiel de Roo
* @license BSD
* @package DateUtil
* @version 1.2
*
*----------------------------------------------------------------------
* License: freeeware under BSD license
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License version 2 as published by the Free
* Software Foundation.
*
* 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.
*
* Released under GNU Public License v2.0, available
* at www.fsf.org. The author hereby disclaims all
* warranties relating to this software, express or implied,
* including with no limitation any implied warranties of
* merchantability, quality performance, or fitness for a
* particular purpose. The author and their distributors
* shall not be liable for any special, incidental,
* consequential, indirect or similar damages due to loss
* of data, even if an agent of the author has been found
* to be the source of loss or damage. In no event shall the
* author's liability for any damages ever exceed the price
* paid for the license to use software, regardless of the
* form of the claim. The person using the software bears all
* risk as to the quality and performance of the software.
*
* This software program, documentation, accompanying
* written and disk-based notes and specifications, and all
* referenced and related program files, screen display
* renditions, and text files, are the property of the
* author.
*
* The authors have done their best to insure that the
* material found in this document is both useful and
* accurate. However, please be aware that errors may exist,
* the author does not make any guarantee concerning the
* accuracy of the information found here or in the uses
* to which it may be put.
*
*----------------------------------------------------------------------
*
*/
?>
<?
/** Class that converts a date to a timestamp, using a smart parser to guess the format */
class BasicDate
{
var $date = null;
var $timestamp = null;
var $missing = array();
var $debug=false;
/** Constructor */
function BasicDate()
{
if($this->debug) trigger_error('Constructing BasicDate');
$this->timestamp = mktime();
}
/** Sets the date to be parsed */
function setDate($date=null)
{
if($this->debug) trigger_error('setDate '.$date);
if($date==null || $date=="now") $date = date("Y-m-d H:i:s", mktime());
$this->date = $date;
BasicDate::execute(); //non-virtual
return $this->execute(); //virtual
}
/** Starts parsing */
function execute()
{
if($this->debug) trigger_error('execute');
$this->missing = array();
if($this->date==null) return;
$a = preg_split("/[^0-9|:|\?]/",$this->date);
if(count($a)==1) { //unix timestamp
if(ereg(":", $a[0])) return $this->setTime($a[0]);
else $this->timestamp = $a[0]; return $this->timestamp;
}
if(count($a)==2) { $a[2]=date("Y", mktime()); } //no year is given, using current
if($a[0]>31) { $y=$a[0]; $m=$a[1]; $d=$a[2]; } //YYYY-MM-DD
else { $y=$a[2]; $m=$a[1]; $d=$a[0]; } //DD-MM-YYYY
if($m!="??") if($m>12) { $t=$d; $d=$m; $m=$t; } //unlikely case of "MM-DD-YYYY" or "YYYY-DD-MM"
if($y!="??") if($y<100) $y+=2000; //case of "DD-MM-YY"
if(count($a)>3) { //time is set
if(ereg(":", $a[3])) {
$t = explode(":", $a[3]);
if(count($t)>0) if($t[0]!="??") { $h = $t[0]; }
if(count($t)>1) if($t[1]!="??") { $i = $t[1]; }
if(count($t)>2) if($t[2]!="??") { $s = $t[2]; }
}
}
if(!$h) { $h=0; $this->missing["h"] = true; }
if(!$i) { $i=0; $this->missing["i"] = true; }
if(!$s) { $s=0; $this->missing["s"] = true; }
if($m=="??") { $m=1; $this->missing["m"] = true; }
if($d=="??") { $d=1; $this->missing["d"] = true; }
if($y=="??") { $y=0; $this->missing["y"] = true; }
$this->timestamp = date("U", mktime($h+0,$i+0,$s+0,$m+0,$d+0,$y+0));
if($this->debug) {
trigger_error('values '.$y." ".$m." ".$d." ".$h." ".$i." ".$s." ");
trigger_error('missing ->');
print_r($this->missing); echo "<br>\n";
}
return $this->timestamp;
}
function setTime($time)
{
$t = preg_split("/[^0-9|\?]/",$this->date);
if(count($t)>0) if($t[0]!="??") { $h = $t[0]; }
if(count($t)>1) if($t[1]!="??") { $i = $t[1]; }
if(count($t)>2) if($t[2]!="??") { $s = $t[2]; }
if(!$h) { $h=0; $this->missing["h"] = true; }
if(!$i) { $i=0; $this->missing["i"] = true; }
if(!$s) { $s=0; $this->missing["s"] = true; }
$m=1; $this->missing["m"] = true;
$d=1; $this->missing["d"] = true;
$y=0; $this->missing["y"] = true;
$this->timestamp = date("U", mktime($h+0,$i+0,$s+0,$m+0,$d+0,$y+0));
if($this->debug) {
trigger_error('values '.$y." ".$m." ".$d." ".$h." ".$i." ".$s." ");
trigger_error('missing ->');
print_r($this->missing); echo "<br>\n";
}
return $this->timestamp;
}
/** Returns the Unix timestamp represented by this date */
function getTimestamp()
{
return $this->timestamp;
}
/** Sets the Unix timestamp to be represented by this date */
function setTimestamp($t)
{
if($this->debug) trigger_error('setTimeStamp');
$this->timestamp = $t;
return $this->execute();
}
}
?>
<?
/** Add and subtract periods */
class DateCalculator extends FormattedDate
{
/** We overrride setDate to add some useful constants */
function setDate($date=null, $format=null)
{
if($this->debug) trigger_error('setDate '.$date);
switch($date) {
case "today" : { $this->setDate(); }
case "tomorrow" : { $this->setDate("now"); $this->add(1, "day"); break; }
case "next week" : { $this->setDate(); $this->add(1, "week"); break; }
case "next month" : { $this->setDate(); $this->add(1, "month"); break; }
case "next year" : { $this->setDate(); $this->add(1, "year"); break; }
case "yesterday" : { $this->setDate("now"); $this->subtract(1, "day"); break; }
case "last week" : { $this->setDate(); $this->subtract(1, "week"); break; }
case "last month" : { $this->setDate(); $this->subtract(1, "month"); break; }
case "last year" : { $this->setDate(); $this->subtract(1, "year"); break; }
default: return FormattedDate::setDate($date, $format); //non-virtual
}
return $this->execute(); //virtual
}
/** if $date2 is null, returns whether the the date represented by the current instance is smaller than the date given as the argument. If $date is not null, returns whether the first argument is smaller than the second. */
function lt($date, $date2=null)
{
$a = $this->_comp($date, $date2);
return $a[0] < $a[1];
}
function lte($date, $date2=null)
{
$a = $this->_comp($date, $date2);
return $a[0] <= $a[1];
}
/** if $date2 is null, returns whether the the date represented by the current instance is greater than the date given as the argument. If $date is not null, returns whether the first argument is greater than the second. */
function gt($date, $date2=null)
{
$a = $this->_comp($date, $date2);
return $a[0] > $a[1];
}
function gte($date, $date2=null)
{
$a = $this->_comp($date, $date2);
return $a[0] >= $a[1];
}
function _comp($date, $date2=null)
{
if($date2!=null) {
$this->setDate($date);
$du2 = new DateUtil();
$du2->setDate($date2);
} else {
$du2 = new DateUtil();
$du2->setDate($date);
}
$a[0] = $this->getTimestamp();
$a[1] = $du2->getTimestamp();
return $a;
}
/** Adds amount of type (year, month, week, day, hour, minute, second) */
function add($amount, $type="second")
{
if($this->debug) trigger_error('add '.$amount.' '.$type);
if($type=="month") $this->_month($amount);
if($type=="year") $this->_year($amount);
$this->timestamp = $this->timestamp + $this->_sec($amount, $type);
$this->date=null;
return $this->execute();
}
/** Subtracts amount of type (year, month, week, day, hour, minute, second) */
function subtract($amount, $type="second")
{
if($this->debug) trigger_error('subtract '.$amount.' '.$type);
if($type=="month") $this->_month($amount);
if($type=="year") $this->_year($amount);
$this->timestamp += $this->_sec(-$amount, $type);
$this->date=null;
return $this->execute();
}
function _year($amount)
{
$yy = date("Y", $this->timestamp)+$amount;
$tt = date("$yy-m-d H:i:s", $this->timestamp);
$this->setDate($tt);
return;
}
function _month($amount)
{
if($amount>=0) $sign=+1;
else $sign=-1;
$amount = abs($amount);
$yy = date("Y", $this->timestamp);
$mm = date("m", $this->timestamp)+$sign*$amount;
while(abs($mm)>=12) {
$mm-=$sign*12;
$yy+=$sign;
}
$tt = date("$yy-$mm-d H:i:s", $this->timestamp);
$this->setDate($tt);
return;
}
//private, returns diff in seconds
function _sec($amount, $type)
{
$mod = $amount;
switch($type) {
case "week" : $mod = $mod*7;
case "day" : $mod = $mod*24;
case "hour" : $mod = $mod*60;
case "minute" : $mod = $mod*60;
}
return $mod;
}
}
?>
<?
//returns the date in a specific format
class FormattedDate extends BasicDate
{
var $format = "Y-m-d";
function setDate($date=null, $format=null)
{
if($this->debug) trigger_error('setDate '.$date);
if($format!=null) {
$this->old_format = $this->format;
$this->format = $format;
}
return BasicDate::setDate($date);
}
/** Sets the format to use */
function setFormat($format)
{
if($this->debug) trigger_error('setFormat');
$this->format = $format;
return $this->execute();
}
/** Returns the formatted date */
function execute()
{
if($this->debug) trigger_error('execute');
$this->missing_format = $this->format;
foreach($this->missing as $k=>$v) {
if($k=="h") $this->missing_format = ereg_replace("[g|G|h|H]+", "??", $this->missing_format);
if($k=="i") $this->missing_format = ereg_replace("[i]+", "??", $this->missing_format);
if($k=="s") $this->missing_format = ereg_replace("[s]+", "??", $this->missing_format);
if($k=="y") $this->missing_format = ereg_replace("[Y|y]+", "??", $this->missing_format);
if($k=="m") $this->missing_format = ereg_replace("[F|j|M|m|n]+", "??", $this->missing_format);
if($k=="d") $this->missing_format = ereg_replace("[d|j]+", "??", $this->missing_format);
if($k=="y" | $k=="m" | $k=="d")
$this->missing_format = ereg_replace("[D|l|w]+ +", "", $this->missing_format);
}
if($this->debug) trigger_error('format '.$this->format);
if($this->debug) trigger_error('missing_format '.$this->missing_format);
return date($this->missing_format, $this->timestamp);
}
}
?>
<?
// performs internationalization on the format through configuration files
class InternationalDate extends DateCalculator
{
var $language = "en";
var $day = array();
var $month = array();
function InternationalDate()
{
if($this->debug) trigger_error('Constructing InternationalDate');
BasicDate::BasicDate();
$this->setLanguage($this->language);
}
/** Sets the language to use, this language must be present as the configuration file $language.cfg */
function setLanguage($language)
{
if($this->debug) trigger_error('setLanguage: '.$language);
$this->language = $language;
$path = dirname(__FILE__);
$file = "$path/$language.cfg";
$fp = fopen($file, "r");
$data = fread($fp, filesize($file));
$lines = explode("\n", $data);
$j=0;
for($i=0; $i<7; $i++) {
$l = explode(" ", $lines[$j++]);
$this->day[$i] = $l[1];
}
$j++;
for($i=0; $i<7; $i++) {
$l = explode(" ", $lines[$j++]);
$this->day_short[$i] = $l[1];
}
$j++;
for($i=0; $i<12; $i++) {
$l = explode(" ", $lines[$j++]);
$this->month[$i] = $l[1];
}
$j++;
for($i=0; $i<12; $i++) {
$l = explode(" ", $lines[$j++]);
$this->month_short[$i] = $l[1];
}
return $this->execute();
}
/** Returns the translated date */
function execute()
{
if($this->debug) trigger_error('execute()');
FormattedDate::execute();
$translated_format = str_replace( 'D','##1', $this->missing_format ); // $translated_day_short
$translated_format = str_replace( 'l','##2', $translated_format ); // $translated_day
$translated_format = str_replace( 'M','##3', $translated_format ); // $translated_month_short
$translated_format = str_replace( 'F','##4', $translated_format ); // $translated_month
$d = date( 'w', $this->timestamp ) + 0;
$translated_day = $this->day[ $d ] ;
$translated_day_short = $this->day_short[ $d ];
$m = date( 'm', $this->timestamp ) + 0;
$translated_month = $this->month[ $m-1 ] ;
$translated_month_short= $this->month_short[ $m-1 ] ;
$translated_string = str_replace( '##1',$translated_day_short, date( $translated_format, $this->timestamp ) );
$translated_string = str_replace( '##2',$translated_day, $translated_string );
$translated_string = str_replace( '##3',$translated_month_short, $translated_string );
$translated_string = str_replace( '##4',$translated_month, $translated_string );
if($this->old_format) $this->format = $this->old_format;
BasicDate::execute();
return $translated_string;
}
}
/** This is just a wrapper that is always the sub-most class in the hierarchy. It provides all the functionality. */
class DateUtil extends InternationalDate
{
}
?>
|