<?php
/*
Date Manager Class
Copyright (C) 2004 Neil Morgan
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
Author's details:
Name: Neil Morgan
Email: hide@address.com
Create and manipulate dates and times
Algorithm implemented here was found at various sites on the web
Try a GOOGLE search for "Julian Date" or "Julian Date Algorithm"
NOTE: All method parameters to have UK format DMY NOT US format MDY
However, returned date can be either DMY or MDY
*/
class nmDate {
//Declare instance variables
var $DoW, $Day, $Month, $Year, $Hours, $Minutes, $Seconds;
var $Julian, $DayName, $MonthName, $Args;
function nmDate() {
$this->MonthName = array('','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
$this->DayName = array('Mon','Tue','Wed','Thu','Fri','Sat','Sun');
$name = 'nmDate'.func_num_args();
$this->Args = func_get_args();
$this->$name();
}
//Get today's date, use available PHP functionality
function nmDate0() {
$date = getdate();
$this->Day = $date['mday'];
$this->Month = $date['mon'];
$this->Year = $date['year'];
$this->SetTime($date['hours'],$date['minutes'],$date['seconds']);
return true;
}
//Enter a formatted date string.
//Set time to midnight.
function nmDate1() {
list($this->Day, $this->Month, $this->Year) = split('[/.-]', $this->Args[0]);
$this->SetTime();
//Make sure supplied date is valid.
if (!checkdate($this->Month, $this->Day, $this->Year)) return false;
$this->ToJul();
return true;
}
//Enter "TS", TimeStamp | "DS", DateStamp.
//[TimeStamp is equivalent to DateStamp]
//Enter 'D/M/Y','H:M:S'
function nmDate2() {
if ($this->Args[0] != "TS" && $this->Args[0] != "DS") {
list($this->Day, $this->Month, $this->Year) = split('[/.-]', $this->Args[0]);
list($this->Hours, $this->Minutes, $this->Seconds) = split('[:]', $this->Args[1]);
} else {
list($DS1, $DS2, $this->Day, $DS4, $DS5, $this->Year) = split('[ ]', $this->Args[1]);
for ($ix=1;$this->MonthName[$ix] != $DS2; $ix++);
$this->Month = $ix;
list($this->Hours, $this->Minutes, $this->Seconds) = split('[:]', $DS4);
}
$this->ToJul();
return true;
}
//Usage $var = new nmDate(dd,mm,yyyy);
//Enter days, months and years as integer parameters.
//Set time to midnight.
function nmDate3() {
$this->Day = $this->Args[0];
$this->Month = $this->Args[1];
$this->Year = $this->Args[2];
$this->SetTime();
//Make sure supplied date is valid.
if (!checkdate($this->Month, $this->Day, $this->Year)) return false;
$this->ToJul();
return true;
}
//Usage $var = new nmDate(dd,mm,yyyy,hh,mm,ss);
//Enter days, months and years as integer parameters.
//Enter hours, minutes and seconds as integer parameters.
function nmDate6() {
$this->Day = $this->Args[0];
$this->Month = $this->Args[1];
$this->Year = $this->Args[2];
$this->SetTime($this->Args[3],$this->Args[4],$this->Args[5]);
//Make sure supplied date is valid.
if (!checkdate($this->Month, $this->Day, $this->Year)) return false;
$this->ToJul();
return true;
}
//Take a Gregorian date and convert to Julian
function ToJul($era='AD') {
//Julian dates have no year 0
if( $this->Year == 0 ) {
return false;
}
//The dates 5 through 14 October, 1582,
//do not exist in the Gregorian system
if( $this->Year == 1582 && $this->Month == 10 && $this->Day > 4 && $this->Day < 15 ) {
return false;
}
if( era == 'BC' ) {
$this->Year = ($this->Year * (-1)) + 1;
}
if( $this->Month > 2 ) {
$jyr = $this->Year;
$jmth = $this->Month + 1;
} else {
$jyr = $this->Year - 1;
$jmth = $this->Month + 13;
}
$intgreg = floor( floor(365.25 * $jyr) + floor(30.6001 * $jmth) + $this->Day + 1720995 );
//check for switch to Gregorian calendar
$gregcal = 15 + 31 * (10 + 12*1582);
if( $this->Day + 31*($this->Month + 12 * $this->Year) >= $gregcal ) {
$jtmp = floor(0.01*$jyr);
$intgreg += 2 - $jtmp + floor(0.25*$jtmp);
}
//correct for half-day offset
$dayfraction = $this->Hours/24.0 - 0.5;
if( $dayfraction < 0.0 ) {
$dayfraction += 1.0;
--$intgreg;
}
//now set the fraction of a day
$fraction = $dayfraction + ($this->Minutes + $this->Seconds/60.0)/60.0/24.0;
//round to nearest second
$jd = ($intgreg + $fraction)*100000;
if( floor($jd) - $jd > 0.5 ) {
++$jd;
}
$this->Julian = $jd/100000;
return true;
}
//Take a Julian date and convert to Gregorian
function ToGreg() {
// get the date from the Julian day number
$intjul = floor($this->Julian);
$fraction = $this->Julian - $intjul;
$gregjd = 2299161;
if( $intjul >= $gregjd ) { //Gregorian calendar correction
$tmp = floor( ( ($intjul - 1867216) - 0.25 ) / 36524.25 );
$intjul = $intjul + 1 + $tmp - floor(0.25*$tmp);
}
//correction for half day offset
$dayfraction = $fraction + 0.5;
if( $dayfraction >= 1.0 ) {
$dayfraction -= 1.0;
++$intjul;
}
$j1 = $intjul + 1524;
$j2 = floor( 6680.0 + ( ($j1 - 2439870) - 122.1 )/365.25 );
$j3 = floor($j2*365.25);
$j4 = floor( ($j1 - $j3)/30.6001 );
$this->Day = floor($j1 - $j3 - floor($j4*30.6001));
$this->Month = floor($j4 - 1);
if( $this->Month > 12 ) $this->Month -= 12;
$this->Year = floor($j2 - 4715);
if( $this->Month > 2 ) {
--$this->Year;
}
if( $this->Year <= 0 ) {
--$this->Year;
}
// get time of day from day fraction
$this->Hours = floor($dayfraction * 24.0);
$this->Minutes = floor(($dayfraction*24.0 - $this->Hours)*60.0);
$fraction = (($dayfraction*24.0 - $this->Hours)*60.0 - $this->Minutes)*60.0;
$this->Seconds = floor($fraction);
$f -= $this->Seconds;
if( $fraction > 0.5 ) {
++$this->Seconds;
}
if( $this->Seconds == 60 ) {
$this->Seconds = 0;
++$this->Minutes;
}
if( $this->Minutes == 60 ) {
$this->Minutes = 0;
++$this->Hours;
}
if( $this->Hours == 24 ) {
$this->Hours = 0;
++$this->Day;
}
}
//Date Methods Here
function AddDays($dy) {
$this->ToJul();
$this->Julian += $dy;
$this->ToGreg();
$this->ToJul();
}
function AddMonths($mt) {
$this->Month += $mt;
while ($this->Month > 12) {
$this->Month -= 12;
$this->Year++;
}
$this->ToJul();
}
function AddYears($yr) {
$this->Year += $yr;
$this->ToJul();
}
function SubDays($dy) {
$this->ToJul();
$this->Julian -= $dy;
$this->ToGreg();
$this->ToJul();
}
function SubMonths($mt) {
$this->Month -= $mt;
while ($this->Month < 0) {
$this->Month += 12;
$this->Year--;
}
$this->ToJul();
}
function SubYears($yr) {
$this->Year -= $yr;
$this->ToJul();
}
function GetDateDMY($mth=false,$sep='/') {
if ($mth)
return sprintf("%02s%s%02s%s%s",$this->Day,$sep,$this->MonthName[$this->Month],$sep,$this->Year);
else
return sprintf("%02s%s%02s%s%s",$this->Day,$sep,$this->Month,$sep,$this->Year);
}
function GetDateMDY($mth=false,$sep='/') {
if ($mth)
return sprintf("%02s%s%02s%s%s",$this->MonthName[$this->Month],$sep,$this->Day,$sep,$this->Year);
else
return sprintf("%02s%s%02s%s%s",$this->Month,$sep,$this->Day,$sep,$this->Year);
}
function GetDay() {
$t = $this->Julian + 0.5;
$wd = floor(($t/7 - floor($t/7))*7 + 0.000000000317 ); //add 0.01 sec for truncation error correction
$this->DoW = $this->DayName[$wd];
return $this->DoW;
}
//Time Methods Here
function SetTime($h='0',$m='0',$s='0') {
$this->Hours = $h;
$this->Minutes = $m;
$this->Seconds = $s;
$this->ToJul();
}
function AddMinutes($mi) {
$this->Minutes += $mi;
while ($this->Minutes >= 60) {
$this->Minutes -= 60;
$this->Hours++;
}
$this->ToJul();
}
function AddHours($hr) {
$this->Hours += $hr;
while ($this->Hours >= 24) {
$this->Hours -= 24;
$this->Day++;
}
$this->ToJul();
}
function SubMinutes($mi) {
$this->Minutes -= $mi;
while ($this->Minutes < 0) {
$this->Minutes += 60;
$this->Hours--;
}
$this->ToJul();
}
function SubHours($hr) {
$this->Hours -= $hr;
while ($this->Hours < 0) {
$this->Hours += 24;
$this->Day--;
}
$this->ToJul();
}
function GetTime($sep=':') {
return sprintf("%02s%s%02s%s%02s",$this->Hours,$sep,$this->Minutes,$sep,$this->Seconds);
}
//Calculate the difference between two dates
//and return the number of seconds.
function GetDiff($date,$time='00:00:00') {
list($dd, $mm, $yy) = split('[/.-]', $date);
list($hh, $mi, $ss) = split('[:]', $time);
$diff = new nmDate($dd,$mm,$yy,$hh,$mi,$ss);
$diff->ToJul();
if ($this->Julian > $diff->Julian) {
$diff->Julian = $this->Julian - $diff->Julian;
} else {
$diff->Julian = $diff->Julian - $this->Julian;
}
$retval = $diff->Julian;
unset($diff);
list($days, $secs) = split('[.]', $retval);
$days *= 86400;
$secs = '0.'.$secs;
$secs *= 86400;
$retval = ceil($days + $secs);
return $retval;
}
}
?>