<?php
/*
_____ ______ _ _ ______
| __ \ | ___ \ | | || ___ \
| | \/_ __ ___ ___ _ __ | |_/ / |_| || |_/ /
| | __| '__/ _ \/ _ \ '_ \| __/| _ || __/
| |_\ \ | | __/ __/ | | | | | | | || |
\____/_| \___|\___|_| |_\_| \_| |_/\_|
----------------------------------------------
(C)BOBAK 2008 V4.0
----------------------------------------------
web : http://www.greenphp.com
email : hide@address.com
----------------------------------------------
*/
/**
* Management dates
* - Check a format
* - Convert between more format
* - Finds that the date will be in X days/months
* - Detect a leap year
* - Number of days in a year/ month
* - Find the difference between 2 dates (in years,months,days)
*
* @author Bobak
* @package data
* @subpackage date
*/
class date
{
//Formats------------------------------------------------------------------------------------
/**
* Check a format (Date,Time,DateTime,Timer)
*
* @param string $Data String to analyze
* @return String format (DATE,TIME,DATETIME,TIMER)
*/
public static function FormatTest($Data)
{
//Error default format
$Out=FALSE;
if (is_integer($Data) and $Data>=0)
{
//Timer
$Out='TIMER';
}
elseif (substr_count($Data,'-')==2 AND substr_count($Data,':')==2)
{
//Date and Time
$DataExp=explode(" ",$Data);
if (count($DataExp)==2 AND self::FormatTest($DataExp[0])=='DATE' AND self::FormatTest($DataExp[1])=='TIME')
{$Out="DATETIME";}
}
elseif (substr_count($Data,'-')==2)
{
//Date
if (ereg("^[0-3][0-9]{3}-[0-9]{1,2}-[0-9]{1,2}$",$Data))
{
$DataExp=explode("-",$Data);
if (checkdate($DataExp[1],$DataExp[2],$DataExp[0]))
{
$Out="DATE";
}
}
}
elseif (substr_count($Data,':')==2)
{
//Time
if (ereg("^[0-2]?[0-9]:[0-5]?[0-9]:[0-5]?[0-9]$",$Data))
{$Out="TIME";}
}
return $Out;
}
/**
* Protects the limits and corrected if necessary
*
* @param string $Data
* @param int $DataMin Value Mini
* @param int $DataMax Value Max
* @param int $DataDefo Default
* @param int $Taille Complete with zero till this size
* @return string
*/
public static function FormatCorrige($Data,$DataMin,$DataMax,$DataDefo,$Taille)
{
//Valide
if (!is_numeric($Data) OR $Data<$DataMin OR $Data>$DataMax) {$Data=$DataDefo;}
//Complete by 0
if (strlen($Data)!=$Taille)
{$Data=str_pad($Data,$Taille,'0',STR_PAD_LEFT);}
return $Data;
}
/**
* Convert DateGet into a string
*
* @param array $DateArray Array with the date and time
* @param string $Format vue most of option Date()
* @return string
*/
public static function Format($DateArray,$Format="Y-m-d H:i:s")
{
if (is_array($DateArray))
{
$Out=$Format;
foreach ($DateArray as $DataNom=>$DataVal)
{$Out=str_replace($DataNom,$DataVal,$Out);}
}
else
{
//Error input format
$Out=FALSE;
}
return $Out;
}
/**
* Converts a date-type 1D,2W in second
*
* @param string $Text
* @return int
*/
public static function FormatT2S($Text)
{
if (!is_numeric($Text))
{
$Text=strtoupper(trim($Text));
$TextVal=$Text+0;
$TextMul=substr($Text,strlen($TextVal.''));
$Dico['S']=1;
$Dico['M']=60;
$Dico['H']=3600;
$Dico['D']=86400;
$Dico['W']=604800;
$Out=$TextVal*$Dico[$TextMul];
}
else
{$Out=abs(round($Text,0));}
return $Out;
}
/**
* Converts a date-type second in 1D, 2W
*
* @param int $Sec date in second
* @return string
*/
public static function FormatS2T($Sec)
{
$Dico[604800]="W";
$Dico[86400] ="D";
$Dico[3600] ='H';
$Dico[60] ='M';
$Sec+=0;
if (is_integer($Sec))
{
$Sec=abs($Sec);
$Out=$Sec;
foreach ($Dico as $DataKey=>$DataVal)
{
if (is_integer($Sec/$DataKey))
{
$Out=($Sec/$DataKey).$DataVal;
break;
}
}
}
else
{$Out=0;}
return $Out;
}
/**
* Converts humain date to mysql format
*
* @param string $DateTime
* @param string $Separateur Separator for date
* @return string
*/
public static function FormatHumain2Mysql($DateTime,$Separateur='/')
{
$Out=FALSE;
$Date=explode($Separateur,$DateTime);
if (count($Date)==3)
{$Out=$Date[2].'-'.$Date[1].'-'.$Date[0];}
return $Out;
}
//Other------------------------------------------------------------------------------------
/**
* Convert a Date, Time, DateTime, Timer in DateTime cut in a array
*
* @param string $DateTime Date|Time|DateTime|Timer to cut
* @return array
*/
public static function Get($DateTime)
{
//Initialise
$Out=array();
$Out['NULL']=FALSE; //Empty or NULL
$Out['Y']="0000"; //Year on 4 Char
$Out['m']="00"; //Month on Char 2
$Out['d']="00"; //Day on 2 Char
$Out['H']="00"; //Hour on 2 Char
$Out['i']="00"; //Minute on 2 Char
$Out['s']="00"; //Second on 2 Char
//Pass Timer in DateTime
if (self::FormatTest($DateTime)=="TIMER")
{$DateTime=date("Y-m-d H:i:s",$DateTime);}
//Finds the Format
$Format=self::FormatTest($DateTime);
//Cut
if (!$DateTime OR $DateTime=="NULL" OR $DateTime===NULL OR $DateTime=='0000-00-00' OR $DateTime=='0000-00-00 00:00:00')
{
//Date Null or Empty
$Out['NULL']=TRUE;
}
elseif ($Format=="DATE")
{
//Date
list($Out['Y'],$Out['m'],$Out['d'])=split("-",trim($DateTime),3);
}
elseif ($Format=="TIME")
{
//Time
list($Out['H'],$Out['i'],$Out['s'])=split(":",trim($DateTime),3);
}
elseif ($Format=="DATETIME")
{
//Date and Time
list($DataD,$DataT)=split(" ",trim($DateTime),2);
list($Out['Y'],$Out['m'],$Out['d'])=split("-",trim($DataD),3);
list($Out['H'],$Out['i'],$Out['s'])=split(":",trim($DataT),3);
}
else
{
//Unknown
return FALSE;
}
if (!$Out['NULL'])
{
//Protects the limits and correction
$Out['Y']=self::FormatCorrige($Out['Y'],1,3000,"0001",4);
$Out['m']=self::FormatCorrige($Out['m'],1,12 ,"01" ,2);
$Out['d']=self::FormatCorrige($Out['d'],1,31 ,"01" ,2);
$Out['H']=self::FormatCorrige($Out['H'],0,23 ,"00" ,2);
$Out['i']=self::FormatCorrige($Out['i'],0,59 ,"00" ,2);
$Out['s']=self::FormatCorrige($Out['s'],0,59 ,"00" ,2);
//Adding extension
$Out['a']=($Out['H']>11)?'pm':'am';
$Out['w']=JDDayOfWeek(cal_to_jd(CAL_GREGORIAN,$Out['m'],$Out['d'],$Out['Y']),0);
$Out['g']=$Out['H']%13+1;
$Out['h']=str_pad($Out['g'],2,'0',STR_PAD_LEFT);
$Out['y']=substr($Out['Y'],2,2);
$Out['X']=$Out['Y'].$Out['m'].$Out['d'];
}
return $Out;
}
/**
* Retourn the date format GMT
*
* @param int $Timer Number of seconds befor 1970-01-01 00:00:00
* @return string
*/
public static function GMT($Timer=NULL)
{
if (is_null($Timer))
{$Out=gmdate('D, d M Y H:i:s').' GMT';}
else
{$Out=gmdate('D, d M Y H:i:s',$Timer).' GMT';}
return $Out;
}
/**
* Returning the curentlty DateTime
*
* @param bool $Timer If true then this is the return Timestamp which is a place of the DateTime
* @return string/int
*/
public static function Now($Timer=FALSE)
{
if ($Timer)
{$Out=time();}
else
{$Out=date("Y-m-d H:i:s");}
return $Out;
}
/**
* Finds that the date will be in X days
*
* @param date/datetime $DateDebut Date of begin
* @param int $Jours Number of days to adding (if negative, it forward)
* @param bool $FinDuMois With a seat at the end of the ending month
* @param bool $FormatDateTime return the date and time
* @return date/datetime
*/
public static function DansXJous($DateDebut,$Jours,$FinDuMois=FALSE,$FormatDateTime=FALSE)
{
//Complete with the curently date
if (is_null($DateDebut))
{$DateDebut=self::Now();}
//Cutting
if (!is_array($DateDebut)) {$DateDebut=self::Get($DateDebut);}
//Years
while ($Jours>=self::NbJoursAnnee($DateDebut['Y']))
{
$Jours-=self::NbJoursAnnee($DateDebut['Y']);
$DateDebut['Y']++;
}
//Month
while ($Jours>=self::NbJoursMois($DateDebut['Y'],$DateDebut['m']))
{
$Jours-=self::NbJoursMois($DateDebut['Y'],$DateDebut['m']);
$DateDebut['m']++;
if ($DateDebut['m']>12)
{
$DateDebut['m']=1;
$DateDebut['Y']++;
}
}
//Days
$DateDebut['d']+=$Jours;
if ($DateDebut['d']>self::NbJoursMois($DateDebut['Y'],$DateDebut['m']))
{
$DateDebut['d']-=self::NbJoursMois($DateDebut['Y'],$DateDebut['m']);
$DateDebut['m']++;
if ($DateDebut['m']>12)
{
$DateDebut['m']=1;
$DateDebut['Y']++;
}
}
//With a seat at the end of the ending month
if ($FinDuMois)
{$DateDebut['d']=self::NbJoursMois($DateDebut['Y'],$DateDebut['m']);}
//Complete the early 0
$DateDebut['m']=str_pad($DateDebut['m'],2,'0',STR_PAD_LEFT);
$DateDebut['d']=str_pad($DateDebut['d'],2,'0',STR_PAD_LEFT);
//Return the date and time
if ($FormatDateTime)
{$Out=self::Format($DateDebut,"Y-m-d H:i:s");}
else
{$Out=self::Format($DateDebut,"Y-m-d");}
return $Out;
}
/**
* Finds that the date will be in X months
*
* @param date/datetime $DateDebut Date of begin
* @param int $Mois Number of months to adding (if negative, it forward)
* @param bool $FinDuMois With a seat at the end of the ending month
* @param bool $FormatDateTime return the date and time
* @return date/datetime
*/
public static function DansXMois($DateDebut,$Mois,$FinDuMois=FALSE,$FormatDateTime=FALSE)
{
//Complete with curently date
if (is_null($DateDebut))
{$DateDebut=self::Now();}
//Cutting
if (!is_array($DateDebut)) {$DateDebut=self::Get($DateDebut);}
//Years
while ($Mois>=12)
{
$Mois-=12;
$DateDebut['Y']++;
}
//Month
$DateDebut['m']+=$Mois;
if ($DateDebut['m']>12)
{
$DateDebut['m']-=12;
$DateDebut['Y']++;
}
//With a seat at the end of the ending month
if ($FinDuMois)
{$DateDebut['d']=self::NbJoursMois($DateDebut['Y'],$DateDebut['m']);}
//Complete les 0 au début
$DateDebut['m']=str_pad($DateDebut['m'],2,'0',STR_PAD_LEFT);
$DateDebut['d']=str_pad($DateDebut['d'],2,'0',STR_PAD_LEFT);
//return the date and time
if ($FormatDateTime)
{$Out=self::Format($DateDebut,"Y-m-d H:i:s");}
else
{$Out=self::Format($DateDebut,"Y-m-d");}
return $Out;
}
//Duration------------------------------------------------------------------------------------
/**
* Detect if a leap year
*
* @param int $Annee Year to test
* @return bool
*/
public static function IsBissextile($Annee)
{
if ($Annee%4==0 AND ($Annee%100!=0 OR $Annee%400==0))
{$Out=TRUE;}
else
{$Out=FALSE;}
return $Out;
}
/**
* Number of days in a year
*
* @param int $Annee Year to test (or a date)
* @return int
*/
public static function NbJoursAnnee($Annee)
{
//It is a date, so I extracted the year
if (!is_numeric($Annee))
{
$Date=self::Get($Annee);
$Annee=$Date['Y'];
}
//leap year
if (self::IsBissextile($Annee))
{$Out=366;}
else
{$Out=365;}
return $Out;
}
/**
* Number of days in a month
*
* @param int $Annee Year to test (or a date)
* @param int $Mois Month to test
* @return int
*/
public static function NbJoursMois($Annee,$Mois)
{
//It is a date, so I extracted the year
if (!is_numeric($Annee))
{
$Date=self::Get($Annee);
$Annee=$Date['Y'];
$Mois =$Date['m'];
}
//Eliminates 0 and force passage digital
$Mois+=0;
$MoisJours[ 1]=31;
$MoisJours[ 2]=28;
$MoisJours[ 3]=31;
$MoisJours[ 4]=30;
$MoisJours[ 5]=31;
$MoisJours[ 6]=30;
$MoisJours[ 7]=31;
$MoisJours[ 8]=31;
$MoisJours[ 9]=30;
$MoisJours[10]=31;
$MoisJours[11]=30;
$MoisJours[12]=31;
//Correction possible for leap year
if ($Mois==2)
{
if (self::IsBissextile($Annee))
{$MoisJours[2]++;}
}
//Find the number of days in a month
$Out=$MoisJours[$Mois];
return $Out;
}
//Unlike------------------------------------------------------------------------------------
/**
* Find the difference between 2 dates
* The negative result means that the dates are in line with decreasing
*
* @param date $DateDebut Date of begin
* @param date $DateFin Date of end
* @return array (0 or Y = Year, or 1 m = Month, or d = 2 Days)
*/
public static function DiffDate($DateDebut,$DateFin=NULL)
{
//Complete with curently date
if (is_null($DateFin))
{$DateFin=self::Now();}
//cutting
if (!is_array($DateDebut)) {$DateDebut=self::Get($DateDebut);}
if (!is_array($DateFin)) {$DateFin =self::Get($DateFin);}
//Met dates in the correct order
if ($DateDebut['X']>$DateFin['X'])
{
core::Swap($DateDebut,$DateFin);
$Signe=-1;
}
else
{$Signe=1;}
//Numerical Approach
$Annees=$DateFin['Y']-$DateDebut['Y'];
$Mois =$DateFin['m']-$DateDebut['m'];
$Jours =$DateFin['d']-$DateDebut['d'];
//Fix by the day
if ($Jours<0)
{
$Mois--;
$Jours+=self::NbJoursMois($DateDebut['Y'],$DateDebut['m']);
}
$JoursMax=self::NbJoursMois($DateFin['Y'],$DateFin['m']);
if ($Jours>=$JoursMax)
{
$Jours-=$JoursMax;
$Mois++;
}
//Fix by the month
if ($Mois<0)
{
$Annees--;
$Mois+=12;
}
if ($Mois>=12)
{
$Mois-=12;
$Annees++;
}
$Out=array($Signe*$Annees,$Signe*$Mois,$Signe*$Jours);
return $Out;
}
/**
* Find out how many years between 2 dates
* The negative result means that the dates are in line with decreasing
*
* @param date $DateDebut Date of begin
* @param date $DateFin Date of end
* @return int
*/
public static function DiffAnnee($DateDebut,$DateFin=NULL)
{
$Diff=self::DiffDate($DateDebut,$DateFin);
return $Diff[0];
}
/**
* Find out how many months between 2 dates
* The negative result means that the dates are in line with decreasing
*
* @param date $DateDebut Date of begin
* @param date $DateFin Date of end
* @return int
*/
public static function DiffMois($DateDebut,$DateFin=NULL)
{
$Diff=self::DiffDate($DateDebut,$DateFin);
$Mois=$Diff[0]*12+$Diff[1];
return $Mois;
}
/**
* Find out how many days between 2 dates
* The negative result means that the dates are in line with decreasing
*
* @param date $DateDebut Date of begin
* @param date $DateFin Date of end
* @return int
*/
public static function DiffJours($DateDebut,$DateFin=NULL)
{
//complet with date this
if (is_null($DateFin))
{$DateFin=self::Now();}
//cutting
if (!is_array($DateDebut)) {$DateDebut=self::Get($DateDebut);}
if (!is_array($DateFin)) {$DateFin =self::Get($DateFin);}
//Met dates in the correct order
if ($DateDebut['X']>$DateFin['X'])
{
core::Swap($DateDebut,$DateFin);
$Signe=-1;
}
else
{$Signe=1;}
//Determine whether it is the same month in the same year
if ($DateFin['Y']==$DateDebut['Y'] AND $DateFin['m']==$DateDebut['m'])
{$Jours=$DateFin['d']-$DateDebut['d'];}
else
{
//Number of days until the end of the month
$Jours=self::NbJoursMois($DateDebut['Y'],$DateDebut['m'])-$DateDebut['d'];
//Number of days at the end
$Jours+=$DateFin['d'];
//Determine whether it's the same year
if ($DateFin['Y']==$DateDebut['Y'])
{
for ($i=$DateDebut['m']+1;$i<$DateFin['m'];$i++)
{$Jours+=self::NbJoursMois($DateDebut['Y'],$i);}
}
else
{
//Number of days until the end of the year
for ($i=$DateDebut['m']+1;$i<13;$i++)
{$Jours+=self::NbJoursMois($DateDebut['Y'],$i);}
//Number of days at the end
for ($i=1;$i<$DateFin['m'];$i++)
{$Jours+=self::NbJoursMois($DateFin['Y'],$i);}
//Number of days in years
for ($i=$DateDebut['Y']+1;$i<$DateFin['Y'];$i++)
{$Jours+=self::NbJoursAnnee($i);}
}
}
$Out=$Signe*$Jours;
return $Out;
}
}
?>