Location: PHPKode > scripts > Date tools > date-tools/date.php
<?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;
}

}
?>
Return current item: Date tools