<?php
/**
* This will accept three parameters of type integer, representing
* a numerically written date, for instance, dd/mm/yy, assuming 2000 onwards.
* It will then construct and return a string based on the numeric
* date sent, so for instance 29/10/02 will return
* Tuesday 29th October 2002. It will also work with future dates, which is
* useful unless we start commonly using something different from the
* gregorian calendar.
* The bugs have been fixed when it was deployed on a live blog-site.
* Put in a folder called libraries and call it dateClass.php or something.
*
* @author: Shaun_B
* @date: 2012-10-17
* @todo: Accept four-digit length years (2003 rather than 03)
* and also implement the 20th century bit, so that dates
* between 1900 - 1999 are accepted too. Got caught up in
* an OO frenzy (nearly).
*
**/
class DateClass {
public $dayNo;
public $day;
public $month;
public $year;
public $fullDate;
public $ddmmyy;
public $dbDate;
public function __contruct() {
$this->dayNo = 0;
$this->day = 0;
$this->month = 0;
$this->year = 0;
$this->fullDate = '';
$this->ddmmyy = '';
$this->dbDate = '';
}
public function setDate( $d = null, $m = null, $y = 0) {
if (!$d || !$m ){
return 'Error in setDate';
} else {
$this->dayNo = $d;
$this->day = $this->dayFromDate( $d, $m, $y );
$this->month = $this->monthAsString( $m );
if ($y<=99 && $y>=0) {
$this->year = $y+2000;
} else {
$this->year = $y;
}
$this->fullDate = (string) $this->dateConstruct( $d, $m, $y );
if( $d <10 ) {
$this->ddmmyy = '0' . $d;
} else {
$this->ddmmyy = $d;
}
if( $m <10 ) {
$this->ddmmyy .= '/0' . $m;
} else {
$this->ddmmyy .= '/' . $m;
}
if( $y <10 ) {
$this->ddmmyy .= '/0' . $y;
} else {
$this->ddmmyy .= '/' . $y;
}
$this->dbDate = $this->year . '-';
if( $m<10 ) {
$this->dbDate .= '0' . $m;
} else {
$this->dbDate .= $m;
}
$this->dbDate .= '-';
if( $d<10 ) {
$this->dbDate .= '0' . $d;
} else {
$this->dbDate .= $d;
}
}
}
// Sets default year to zero (ie, 2000 etc...)
public static function dateConstruct( $dd = null, $mm = null, $yy = 0 ) {
// Number of days in each month (excluding leap-years)
// We have special conditions later for leap-years and February 29th:
$noOfDays = array( 1=>31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
// This will test each variable sent to the function
// to see if it's not null and each is numeric:
if( !$dd || !$mm ) {
echo 'invalid or null date type, please enter numeric date as <br />';
echo 'DD/MM/YY, ie, 28/02/10.';
return;
}
// We'll transfer the sent variables to local variables:
$day = (int)$dd;
$month = (int)$mm;
$year = (int)$yy;
// We get onto the real testing now, to check that
// each numeric number entered is within the legal
// range (ie, DD/MM/YY):
if( $month<1 || $month>12 ) {
echo 'Month invalid, reset to default. <br />';
$month = 1;
}
if( $day<1 || $day>31 ) {
echo 'Day invalid, reset to default.<br />';
$day = 1;
}
if( $year<0 || $year>99 ) {
echo 'Year is invalid, reset to default.<br />';
$year = 1;
}
// Now further validation on the day to check for
// specific months and leap-years etc...
if( $day>29 && $month==2 ) {
echo 'Day invalid, reset to default.<br />';
$day = 1;
}
// Now let's do some calculations for the leap-year
// Remember that 2000 was a leap year and 1900 wasn't:
if( $day==29 && $month==2 && ((2000-$year)%4!=0) ) {
echo 'Not a leap year, reset to default.<br />';
$day = 28;
}
// Next, to validate the rest of the months:
if( $day>$noOfDays[ $month ] && $month!=2 ) {
echo 'Day not valid, reset to default.<br />';
$day = 1;
}
// Finally, let's print out the date as we need it:
if( $year<10 ) {
$returnValue = (string) DateClass::dayFromDate( $day, $month, $year )
. ' ' . $day . DateClass::suffix( $day ) . ' ' . DateClass::monthAsString( $month ) . ' 200' . $year;
} else {
$returnValue = (string) DateClass::dayFromDate( $day, $month, $year )
. ' ' . $day . DateClass::suffix( $day ) . ' ' . DateClass::monthAsString( $month ) . ' 20' . $year;
}
return $returnValue;
}
// Here are the functions to echo values as strings:
public static function monthAsString( $month = null ) {
$month = (int) $month;
// Here are the months of the year:
$monthToString = array( 1=>'January', 'February', 'March',
'April', 'May', 'June', 'July', 'August',
'September', 'October', 'Novermber', 'December' );
if( $month>0 && $month<13 ) {
return $monthToString[ $month ];
} else {
return 'Month not set';
}
}
// This will deal with the suffix of the numeric day,
// ie, 01/xx/xx will be 1st/xx/xx:
public static function suffix( $day = null ) {
switch( (int) $day ) {
case 1:
return 'st';
break;
case 2:
return 'nd';
break;
case 3:
return 'rd';
break;
case 21:
return 'st';
break;
case 22:
return 'nd';
break;
case 23:
return 'rd';
break;
case 31:
return 'st';
break;
default:
return 'th';
break;
}
}
public static function dayFromDate( $d = null, $m = null, $y = null ) {
$day = (int)$d;
$month = (int)$m;
$year = (int)$y;
// This is for the day validation. If the day is in the
// 20th century (1901 - 1999), here's the correct look-up
// table for the days according to my maths (has eight
// elements to stop errors):
$daysOfWeek20th = array( 'Mon', 'Tues', 'Wednes', 'Thurs', 'Fri', 'Satur', 'Sun', 'Mon' );
// Here is the same look-up table for the 21st century:
$daysOfWeek21st = array ( 'Sun', 'Mon', 'Tues', 'Wednes', 'Thurs', 'Fri', 'Satur', 'Sun', 'Mon' );
// Here is the month codes which will be used in the
// algorithm later on:
$monthCodes = array( 1=>6, 2, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4, 6 );
$a = $year+( abs( $year/4 ) );
$x = $monthCodes[ $month ];
$y = $day;
$z = $a + $x + $y;
$a = abs( $z );
$c = round( $a );
$v = $c % 7;
while( $v<=0 ) {
$v += 7;
}
$leapYear = (int)(2000-$year)%4;
// A bug in the algorithmn means that the year immediately proceeding
// a leap year is mis-calculated, so we need to increase $v by one:
if($leapYear==3) {
$v++;
}
// Another bug found: this one involves months after February on all
// years but leap-years.
if($month>=3 && $leapYear) {
$v--;
}
if( $month>=1 && $month<=2 ) {
return $daysOfWeek21st[ $v-1 ] . 'day';
} else if( $month>=3 ) {
return $daysOfWeek21st[ $v ] . 'day';
} else {
return 'Day unknown';
}
}
public function __destruct() {
;;
}
}
?>