| px | top | add code | search | signup | login | help |
<?php //---Calendar.class
//---Description: Gregorian Calendar Class
//--- This class now not limited to computing
//--- dates before 1970 and after 2037
//---
//---Author: Edwin C. Villapando (jgreco@surfshop.net.ph)
//---Version: 0.2
//---Date: 2002-1-1 1:53
//---File: Calendar.class
//---include "Calendar.inc" //---originally this is called instead of
//---defining some constants. This is so
//---to use the class with HTTP Cookies.
//---Since include() sends HTTP header,
//---(I think?) and setting cookies must
//---be set prior to sending the HTTP Header.
//---With this in the class("include()") will
//---cause an HTTP Header to be sent before
//---setting the Cookies and will cause an error.
//---define(s) same as content of Calendar.inc
define("SECONDS_PER_DAY", 86400);
define("MINUTES_PER_DAY", 1440);
define("HOURS_PER_DAY", 24);
define("DAYS_PER_WEEK", 7);
define("MONTHS_PER_YEAR", 12);
define("DAYS_PER_YEAR", 365.25);
define("DAYS_PER_MONTH", 30);
define("CENTURY", 100);
define("LEAPCENTURY", 400);
//---end of define(s)
Class Calendar {
//---
//---Calendar class variables
//---
var $date; //---(GREGORIAN JD) + fractional part (TIME)
var $SECONDS; //---"seconds"
var $MINUTES; //---"minutes"
var $HOURS; //---"hours"
var $DAY; //---"mday"
var $WEEKDAY; //---"wday"
var $CWEEKDAY; //---"weekday"
var $MONTH; //---"mon"
var $YEAR; //---"year"
var $DAYOFYEAR; //---"yday"
var $CMONTH; //---"month"
var $CDATE; //---date rep. of $date "12/31/2001"
var $CTIME; //---time rep. of $date "11:30:45"
var $GREGORIANDATE; //---Holds the GREGORIAN JD
var $JULIANDATE; //---Holds the JULIAN JD
//---end of Calendar class variables
//---
//---Calendar class methods
//---
function Calendar($date = NULL) {
//--- Date class constructor
//---populate the properties with values
$this->init_date($this->eval_dparm($date));
} //---end of Date class constructor
function defaultdate() {
//---Return the current date/time stamp
$defaultdate = getdate(time());
$defaultdate[0] = GregorianToJD($defaultdate["mon"],
$defaultdate["mday"],
$defaultdate["year"]);
return $defaultdate;
} //---end of defaultdate()
function eval_dparm($date) {
//---Evaluate a date parameter and return a date/time stamp
$defaultdate = $this->defaultdate();
$tmpdate = $defaultdate;
$regdate = $defaultdate;
//---no parameter passed
if (is_null($date)) {
$tmpdate = $defaultdate;
//---date string passed
} elseif (is_string($date)) {
//---Valid date formats:
//--- mm/dd/yyyy, mm.dd.yyyy, mm-dd-yyyy
//--- yyyy/mm/dd, yyyy.mm.dd, yyyy-mm-dd
//---for B.C. years valid formats:
//--- mm/dd/-yyyy, mm.dd.-yyyy
//--- -yyyy/mm/dd, -yyyy.mm.dd
//---The Date part of the $date string
//---Hope that this compute the years on B.C.
$token = $this->gettoken($date);
$pattern = "([0-9-]{1,5})[$token]([0-9]{1,2})[$token]([0-9-]{1,5})";
$Dereg = ereg($pattern, $date, $eregDATE);
//---THis is the old expression that does not compute on B.C. dates
//---$Dereg = ereg("([0-9]{1,4})[/.-]([0-9]{1,2})[/.-]([0-9]{1,4})", $date, $eregDATE);
//---THe Time part of the $date string
$Tereg = ereg("([0-9]{1,2}):([0-9]{1,2})[: ]([0-9]{0,2})", "$date ", $eregTIME);
//---Determine the validity of the Date part
if ($Dereg) {
if ($eregDATE[1] > 0 && $eregDATE[1] < 13) { //---assume mm/dd/yyyy
$regdate["mon"] = $eregDATE[1];
$regdate["mday"] = $eregDATE[2];
$regdate["year"] = $eregDATE[3];
} else { //---assume yyyy/mm/dd
$regdate["mon"] = $eregDATE[2];
$regdate["mday"] = $eregDATE[3];
$regdate["year"] = $eregDATE[1];
}
if (GregorianToJD($regdate["mon"], $regdate["mday"], $regdate["year"]) == 0) {
//---Undetermine date, force return the default date value
return $defaultdate;
}
} else {
//---Undetermine date, force return the default date value
return $defaultdate;
}
//---Determine the validity of the Time part
if ($Tereg && (((int) $eregTIME[1]) <= 23)
&& (((int) $eregTIME[2]) <= 59)
&& (((int) $eregTIME[3]) <= 59)) {
$regdate["hours"] = (int) $eregTIME[1];
$regdate["minutes"] = (int) $eregTIME[2];
$regdate["seconds"] = (int) $eregTIME[3];
} else {
$regdate["hours"] = 0;
$regdate["minutes"] = 0;
$regdate["seconds"] = 0;
}
//---now supply the values of the array
$regdate[0] = GregorianToJD($regdate["mon"],
$regdate["mday"],
$regdate["year"]);
$regdate["weekday"] = JDDayofWeek($regdate[0], 1);
$regdate["wday"] = JDDayofWeek($regdate[0], 0);
$regdate["month"] = JDMonthName($regdate[0], 1);
$regdate["yday"] = $this->dayofyear($regdate["mon"],
$regdate["mday"],
$regdate["year"]);
$tmpdate = $regdate;
//---numeric value passed. assume a JD value
} elseif (is_numeric($date)) {
//---get array values from time expression (12:30:59)
$gregtime = $this->jdtime($date);
list($regdate["hours"],
$regdate["minutes"],
$regdate["seconds"]) = explode(":", $gregtime[0]);
//---get array values from date expression (12/31/2001)
list($regdate["mon"],
$regdate["mday"],
$regdate["year"]) = explode("/", JDToGregorian($date));
//---now supply the values of the array
$regdate[0] = GregorianToJD($regdate["mon"],
$regdate["mday"],
$regdate["year"]);
$regdate["weekday"] = JDDayofWeek($regdate[0], 1);
$regdate["wday"] = JDDayofWeek($regdate[0], 0);
$regdate["month"] = JDMonthName($regdate[0], 1);
$regdate["yday"] = $this->dayofyear($regdate["mon"],
$regdate["mday"],
$regdate["year"]);
$tmpdate = $regdate;
} else {
if (get_class($date) == "calendar") {
//---The passed parameter is a Calendar class
//---so, get the $obj->date properties
$tmpdate[0] = (int) ($date->date);
$tmpdate["seconds"] = $date->SECONDS;
$tmpdate["minutes"] = $date->MINUTES;
$tmpdate["hours"] = $date->HOURS;
$tmpdate["mday"] = $date->DAY;
$tmpdate["wday"] = $date->WEEKDAY;
$tmpdate["weekday"] = $date->CWEEKDAY;
$tmpdate["mon"] = $date->MONTH;
$tmpdate["year"] = $date->YEAR;
$tmpdate["yday"] = $date->DAYOFYEAR;
$tmpdate["month"] = $date->CMONTH;
} else {
//---Catch anything else, return current date
$tmpdate = $defaultdate;
}
}
return $tmpdate;
} //---end of eval_dparm
function gettoken($str)
//---Determine which date separator is used.
{
$slash = substr_count($str, "/");
$dash = substr_count($str, "-");
$dot = substr_count($str, ".");
if ($slash == 2) {
//---priority token
return "/";
} elseif ($dash == 2) {
//---second priority
return "-";
} elseif ($dot == 2) {
return ".";
} else {
return "";
}
} //---end of gettoken()
function init_date($date_arr) {
//---Initialize the properties
//---recalculate the Gregorian date with decimals days.
$daysdecimal = $this->DaysDecimal($date_arr["hours"],
$date_arr["minutes"],
$date_arr["seconds"]);
$this->date = $date_arr[0] + $daysdecimal;
$this->SECONDS = $date_arr["seconds"];
$this->MINUTES = $date_arr["minutes"];
$this->HOURS = $date_arr["hours"];
$this->DAY = $date_arr["mday"];
$this->WEEKDAY = $date_arr["wday"];
$this->CWEEKDAY = $date_arr["weekday"];
$this->MONTH = $date_arr["mon"];
$this->YEAR = $date_arr["year"];
$this->DAYOFYEAR = $date_arr["yday"];
$this->CMONTH = $date_arr["month"];
$this->CDATE = "$this->MONTH/$this->DAY/$this->YEAR";
$this->CTIME = "$this->HOURS:$this->MINUTES:$this->SECONDS";
$this->GREGORIANDATE = GregorianToJD($this->MONTH, $this->DAY, $this->YEAR);
$this->JULIANDATE = JulianToJD($this->MONTH, $this->DAY, $this->YEAR);
} //---end of init_date()
function format($format = "SHORT") {
//---String format the date of Calendar object
$fmt = JDToGregorian($this->GREGORIANDATE);
switch ($format) {
case "SHORT":
//---MM/DD/YYYY
$fmt = JDToGregorian($this->GREGORIANDATE);
break;
case "MEDIUM":
//---DD-CMONTH-YYYY
$fmt = $this->DAY . "-" . substr($this->CMONTH, 0, 3)
. "-" . $this->YEAR;
break;
case "LONG":
//---CMONTH DD, YYYY
$fmt = "$this->CMONTH $this->DAY, $this->YEAR";
break;
case "FULL":
//---CWEEKDAY, CMONTH DD, YYYY HH:MM:SS
$fmt = "$this->CWEEKDAY, $this->CMONTH $this->DAY, $this->YEAR " .
"$this->CTIME";
break;
}
return $fmt;
} //---end of format()
function dayofyear($month, $day, $year) {
//---Returns the day of the year
$doy = array(0, 28, 59, 89, 120, 150, 181, 212, 242, 273, 303, 334);
return ($day + $doy[$month -1] + ((int) ($this->isleapyear($year))));
} //---end of dayofyear
function isleapyear($year = NULL) {
//---Determine if $year is leap year
$year = is_null($year) ? $this->YEAR : $year;
if (($year % 4) == 0) {
if (($year % CENTURY) == 0) {
return (($year % LEAPCENTURY) == 0);
} else {
return TRUE;
}
} else {
return FALSE;
}
} //---end of isleapyear
function daysdecimal($hours = 0, $minutes = 0, $seconds = 0) {
//---Return fractional days of hours:minutes:seconds
return (($seconds / SECONDS_PER_DAY) +
($minutes / MINUTES_PER_DAY) +
($hours / HOURS_PER_DAY) );
} //---end of daysdecimal()
function jdtime($jd) {
//---Return time array based on the fractional part of JD
$fracjd = round(($jd - ((int) ($jd))) * SECONDS_PER_DAY);
$hrpart = (int) ($fracjd / (3600));
$fracjd -= ($hrpart * 3600);
$minpart = (int) ($fracjd / 60);
$fracjd -= ($minpart * 60);
$secpart = ($fracjd);
return array("hours" => $hrpart,
"minutes" => $minpart,
"seconds" => $secpart,
0 => "$hrpart:$minpart:$secpart");
} //---end of jdtime()
function setdate($date = NULL) {
//---Change the current date value of the Calendar object with new one
//---without destroying the current Calendar object. Useful on loops
$this->init_date($this->eval_dparm($date));
} //---end of setdate()
function datediff($date, $elaps = "d") {
//---
//---Returns number of weeks/days/hours/minutes/seconds
//---between two dates/time. Default is "d" days to return
//---
//---Legend ($elaps):
//---
//--- y - years = (365.25 days / year)
//--- m - months
//--- w - weeks
//--- d - days
//--- h - hours
//--- n - minutes
//--- s - seconds
//---
//---Compute days elaps. This is the default return value
$subdate = new Calendar($date);
$dayselaps = ($this->date - $subdate->date);
switch ($elaps) {
case "y":
//---Convert it to years
$dayselaps = $dayselaps / DAYS_PER_YEAR;
break;
case "m":
//---Convert it to months
$dayselaps = ($dayselaps / DAYS_PER_YEAR) * MONTHS_PER_YEAR;
break;
case "w":
//---Convert it to weeks
$dayselaps = $dayselaps / DAYS_PER_WEEK;
break;
case "h":
//---Convert it to hours
$dayselaps = $dayselaps * HOURS_PER_DAY;
break;
case "n":
//---Convert it to minutes
$dayselaps = $dayselaps * MINUTES_PER_DAY;
break;
case "s":
//---Convert it to seconds
$dayselaps = $dayselaps * SECONDS_PER_DAY;
break;
}
return $dayselaps;
} //---end of datediff()
function firstdayofmonth() {
//---Returns a Calendar object representating the first day of the
//---month of the current Calendar object
//---
return (new Calendar("$this->MONTH/1/$this->YEAR"));
} //---end of firstdayofmonth()
function firstdayofyear() {
//---Returns a Calendar object representating the first day of the
//---year of the current Calendar object
//---
return (new Calendar("1/1/$this->YEAR"));
} //---end of firstdayofyear()
function lastdayofmonth() {
//---Returns a Calendar object representating the last day of the
//---month of the current Calendar object
//---
$month = ($this->MONTH + 1) > 12 ? 1 : $this->MONTH + 1;
$year = ($this->MONTH + 1) > 12 ? $this->YEAR + 1 : $this->YEAR;
return (new Calendar(GregorianToJD($month, 1, $year) - 1));
} //---end of lastdayofmonth()
function lastdayofyear() {
//---Returns a Calendar object representating the last day of the
//---year of the current Calendar object
//---
return (new Calendar("12/31/$this->YEAR"));
} //---end of lastdayofyear()
function dateadd($number = 0, $interval = "d") {
//---Returns Calendar object upon adding $interval/$number to
//---current Calendar object. $number is the number to add
//---
//---Legend ($interval):
//---
//--- yyyy - year
//--- q - quarter
//--- m - month
//--- y - day of year
//--- d - day (default with $number = 0)
//--- w - weekday
//--- ww - week of year
//--- h - hour
//--- n - minute
//--- s - second
//---
$elaps = $number;
switch ($interval)
{
case "yyyy":
//---Add $number to year
return (new Calendar(GregorianToJD($this->MONTH,
$this->DAY,
($this->YEAR + $number))));
break;
case "q":
//---Add $number to quarter
$elaps = $number * 3 * DAYS_PER_MONTH;
break;
case "m":
//---Add $number to month
$elaps = $number * DAYS_PER_MONTH;
break;
case "y":
case "d":
case "w":
//---Add $number to day of year, day, day of week
$elaps = $number;
break;
case "ww":
//---Add $number to week
$elaps = $number * DAYS_PER_WEEK;
break;
case "h":
//---Add $number to hours
$elaps = $number / HOURS_PER_DAY;
break;
case "n":
//---Add $number to minutes
$elaps = $number / MINUTES_PER_DAY;
break;
case "s":
//---Add $number to seconds
$elaps = $number / SECONDS_PER_DAY;
break;
}
return (new Calendar($this->date + $elaps));
} //---end of dateadd()
} //---end of Calendar Class
?>
Comments or questions?
PX is running PHP 5.2.11
Thanks to Miranda Productions for hosting and bandwidth.
Use of any code from PX is at your own risk.