PageRenderTime 35ms CodeModel.GetById 10ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 1ms

/sgl/includes/qcubed/_core/framework/QDateTime.class.php

http://logisticsouth.googlecode.com/
PHP | 838 lines | 498 code | 96 blank | 244 comment | 97 complexity | e8a33aabdf6d4964b26d6fdfda3bbec5 MD5 | raw file
  1<?php
  2
  3	// These Aid with the PHP 5.2 DateTime error handling
  4	class QDateTimeNullException extends QCallerException {}
  5	function QDateTimeErrorHandler() {}
  6
  7	/**
  8	 * QDateTime (Standard)
  9	 * REQUIRES: PHP >= 5.2.0
 10	 * 
 11	 * This DateTime class manages datetimes for the entire system.  It basically
 12	 * provides a nice wrapper around the PHP DateTime class, which is included with
 13	 * all versions of PHP >= 5.2.0.
 14	 * 
 15	 * For legacy PHP users (PHP < 5.2.0), please refer to QDateTime.legacy
 16	 */
 17	class QDateTime extends DateTime {
 18		const Now = 'now';
 19		const FormatIso = 'YYYY-MM-DD hhhh:mm:ss';
 20		const FormatIsoCompressed = 'YYYYMMDDhhhhmmss';
 21		const FormatDisplayDate = 'DD/MM/YYYY';
 22		const FormatDisplayDateFull = 'DDD, MMMM D, YYYY';
 23		const FormatDisplayDateTime = 'MMM DD YYYY hh:mm zz';
 24		const FormatDisplayDateTimeFull = 'DDDD, MMMM D, YYYY, h:mm:ss zz';
 25		const FormatDisplayTime = 'hh:mm:ss zz';
 26		const FormatRfc822 = 'DDD, DD MMM YYYY hhhh:mm:ss ttt';
 27
 28		const FormatSoap = 'YYYY-MM-DDThhhh:mm:ss';
 29
 30		/**
 31		 * The "Default" Display Format
 32		 * @var string $DefaultFormat
 33		 */
 34		public static $DefaultFormat = QDateTime::FormatDisplayDate;
 35		
 36		/**
 37		 * The "Default" Display Format for Times
 38		 * @var string $DefaultTimeFormat
 39		 */
 40		public static $DefaultTimeFormat = QDateTime::FormatDisplayTime;
 41	
 42		/**
 43		 * Returns a new QDateTime object that's set to "Now"
 44		 * Set blnTimeValue to true (default) for a DateTime, and set blnTimeValue to false for just a Date
 45		 *
 46		 * @param boolean $blnTimeValue whether or not to include the time value
 47		 * @return QDateTime the current date and/or time
 48		 */
 49		public static function Now($blnTimeValue = true) {
 50			$dttToReturn = new QDateTime(QDateTime::Now);
 51			if (!$blnTimeValue) {
 52				$dttToReturn->blnTimeNull = true;
 53				$dttToReturn->ReinforceNullProperties();
 54			}
 55			return $dttToReturn;
 56		}
 57
 58		protected $blnDateNull = true;
 59		protected $blnTimeNull = true;
 60
 61		public static function NowToString($strFormat = null) {
 62			$dttNow = new QDateTime(QDateTime::Now);
 63			return $dttNow->qFormat($strFormat);
 64		}
 65		public function IsDateNull() {
 66			return $this->blnDateNull;
 67		}
 68		public function IsNull() {
 69			return ($this->blnDateNull && $this->blnTimeNull);
 70		}
 71		public function IsTimeNull() {
 72			return $this->blnTimeNull;
 73		}
 74		public function PhpDate($strFormat) {
 75			// This just makes a call to format
 76			return parent::format($strFormat);
 77		}
 78		public function GetSoapDateTimeArray($dttArray) {
 79			if (!$dttArray)
 80				return null;
 81
 82			$strArrayToReturn = array();
 83			foreach ($dttArray as $dttItem)
 84				array_push($strArrayToReturn, $dttItem->qFormat(QDateTime::FormatSoap));
 85			return $strArrayToReturn;
 86		}
 87
 88		/**
 89		 * @param integer $intTimestamp
 90		 * @param DateTimeZone $objTimeZone
 91		 * @return QDateTime
 92		 */
 93		public static function FromTimestamp($intTimestamp, DateTimeZone $objTimeZone = null) {
 94			return new QDateTime(date('Y-m-d H:i:s', $intTimestamp), $objTimeZone);
 95		}
 96
 97		public function __construct($mixValue = null, DateTimeZone $objTimeZone = null) {
 98
 99			// Cloning from another QDateTime object
100			if ($mixValue instanceof QDateTime) {
101				if ($objTimeZone)
102					throw new QCallerException('QDateTime cloning cannot take in a DateTimeZone parameter');
103				if ($mixValue->GetTimeZone()->GetName() == date_default_timezone_get())
104					parent::__construct($mixValue->format('Y-m-d H:i:s'));
105				else
106					parent::__construct($mixValue->format(DateTime::ISO8601));
107				$this->blnDateNull = $mixValue->IsDateNull();
108				$this->blnTimeNull = $mixValue->IsTimeNull();
109
110			// Subclassing from a PHP DateTime object
111			} else if ($mixValue instanceof DateTime) {
112				if ($objTimeZone)
113					throw new QCallerException('QDateTime subclassing of a DateTime object cannot take in a DateTimeZone parameter');
114				parent::__construct($mixValue->format(DateTime::ISO8601));
115
116				// By definition, a DateTime object doesn't have anything nulled
117				$this->blnDateNull = false;
118				$this->blnTimeNull = false;
119
120			// Using "Now" constant
121			} else if (strtolower($mixValue) == QDateTime::Now) {
122				if ($objTimeZone)
123					parent::__construct('now', $objTimeZone);
124				else
125					parent::__construct('now');
126				$this->blnDateNull = false;
127				$this->blnTimeNull = false;
128
129			// Null or No Value
130			} else if (!$mixValue) {
131				// Set to "null date"
132				// And Do Nothing Else -- Default Values are already set to Nulled out
133				if ($objTimeZone)
134					parent::__construct('2000-01-01 00:00:00', $objTimeZone);
135				else
136					parent::__construct('2000-01-01 00:00:00');
137
138			// Parse the Value string
139			} else {
140				$intTimestamp = null;
141				$blnValid = false;
142				QApplication::SetErrorHandler('QDateTimeErrorHandler');
143				try {
144					if ($objTimeZone)
145						$blnValid = parent::__construct($mixValue, $objTimeZone);
146					else
147						$blnValid = parent::__construct($mixValue);
148				} catch (Exception $objExc) {}
149				if ($blnValid !== false)
150					$intTimestamp = parent::format('U');
151				QApplication::RestoreErrorHandler();
152
153				// Valid Value String
154				if ($intTimestamp) {
155					// To deal with "Tues" and date skipping bug in PHP 5.2
156					parent::__construct(date('Y-m-d H:i:s', parent::format('U')));
157
158					// if $mixValue represent only time string, blnDateNull must be set to true 
159					$objDateTime = (object)date_parse($mixValue); 
160					$this->blnDateNull = ($objDateTime->year && $objDateTime->month && $objDateTime->day)? false : true; 
161
162					// Update Time Null Value if Time was Specified
163					if (strpos($mixValue, ':') !== false)
164						$this->blnTimeNull = false;
165
166				// Timestamp-based Value string
167				} else if (is_numeric($mixValue)) {
168					if ($objTimeZone)
169						parent::__construct(date('Y-m-d H:i:s', $mixValue), $objTimeZone);
170					else
171						parent::__construct(date('Y-m-d H:i:s', $mixValue));
172
173					$this->blnTimeNull = false;
174					$this->blnDateNull = false;
175
176				// Null Date
177				} else {
178					// Set to "null date"
179					// And Do Nothing Else -- Default Values are already set to Nulled out
180					if ($objTimeZone)
181						parent::__construct('2000-01-01 00:00:00', $objTimeZone);
182					else
183						parent::__construct('2000-01-01 00:00:00');
184				}
185			}
186		}
187
188		/* The Following Methods are in place because of a bug in PHP 5.2.0 */
189		protected $strSerializedData;
190		public function __sleep() {
191			$this->strSerializedData = parent::format(DateTime::ISO8601);
192			return array('blnDateNull', 'blnTimeNull', 'strSerializedData');
193		}
194		public function __wakeup() {
195			parent::__construct($this->strSerializedData);
196		}
197
198		/**
199		 * @deprecated since PHP 5.3
200		 * DEPRECATED - DO NOT USE. For PHP 5.3 compatability, this method should not be called with parameters.
201		 * In previous versions of QCubed and QCodo, the way to format a date was to call 
202		 * __toString(), passing the format as a parameter. PHP 5.3 no longer supports this construct. 
203		 * To format a date, call $myDateTimeObject->qFormat($strParameters).
204		 *
205		 * For compatibility with old apps, this method is preserved - and passing parameters to it is
206		 * allowed, through a horrible hack. Please DO NOT use in applications that were written past the
207		 * release of PHP 5.3.
208		 */
209		public function __toString() {
210			$strArgumentArray = func_get_args();
211			
212			if (count($strArgumentArray) >= 1) {
213				$strFormat = $strArgumentArray[0];
214			} else {
215				$strFormat = null;
216			}
217			return $this->qFormat($strFormat);
218		}
219
220		/**
221		 * Outputs the date as a string given the format strFormat.  By default,
222		 * it will return as QDateTime::FormatDisplayDate "MMM DD YYYY", e.g. Mar 20 1977.
223		 *
224		 * Properties of strFormat are (using Sunday, March 2, 1977 at 1:15:35 pm
225		 * in the following examples):
226		 *
227		 *	M - Month as an integer (e.g., 3)
228		 *	MM - Month as an integer with leading zero (e.g., 03)
229		 *	MMM - Month as three-letters (e.g., Mar)
230		 *	MMMM - Month as full name (e.g., March)
231		 *
232		 *	D - Day as an integer (e.g., 2)
233		 *	DD - Day as an integer with leading zero (e.g., 02)
234		 *	DDD - Day of week as three-letters (e.g., Wed)
235		 *	DDDD - Day of week as full name (e.g., Wednesday)
236		 *
237		 *	YY - Year as a two-digit integer (e.g., 77)
238		 *	YYYY - Year as a four-digit integer (e.g., 1977)
239		 *
240		 *	h - Hour as an integer in 12-hour format (e.g., 1)
241		 *	hh - Hour as an integer in 12-hour format with leading zero (e.g., 01)
242		 *	hhh - Hour as an integer in 24-hour format (e.g., 13)
243		 *	hhhh - Hour as an integer in 24-hour format with leading zero (e.g., 13)
244		 *
245		 *	mm - Minute as a two-digit integer
246		 *
247		 *	ss - Second as a two-digit integer
248		 *
249		 *	z - "pm" or "am"
250		 *	zz - "PM" or "AM"
251		 *	zzz - "p.m." or "a.m."
252		 *	zzzz - "P.M." or "A.M."
253		 * 
254		 *  ttt - Timezone Abbreviation as a three-letter code (e.g. PDT, GMT)
255		 *  tttt - Timezone Identifier (e.g. America/Los_Angeles)
256		 *
257		 * @param string $strFormat the format of the date
258		 * @return string the formatted date as a string
259		 */
260		public function qFormat($strFormat = null) {
261			$this->ReinforceNullProperties();
262			if (is_null($strFormat))
263				$strFormat = QDateTime::$DefaultFormat;
264
265			/*
266				(?(?=D)([D]+)|
267					(?(?=M)([M]+)|
268						(?(?=Y)([Y]+)|
269							(?(?=h)([h]+)|
270								(?(?=m)([m]+)|
271									(?(?=s)([s]+)|
272										(?(?=z)([z]+)|
273											(?(?=t)([t]+)|
274				))))))))
275			*/
276
277//			$strArray = preg_split('/([^D^M^Y^h^m^s^z^t])+/', $strFormat);
278			preg_match_all('/(?(?=D)([D]+)|(?(?=M)([M]+)|(?(?=Y)([Y]+)|(?(?=h)([h]+)|(?(?=m)([m]+)|(?(?=s)([s]+)|(?(?=z)([z]+)|(?(?=t)([t]+)|))))))))/', $strFormat, $strArray);
279			$strArray = $strArray[0];
280			$strToReturn = '';
281
282			$intStartPosition = 0;
283			for ($intIndex = 0; $intIndex < count($strArray); $intIndex++) {
284				$strToken = trim($strArray[$intIndex]);
285				if ($strToken) {
286					$intEndPosition = strpos($strFormat, $strArray[$intIndex], $intStartPosition);
287					$strToReturn .= substr($strFormat, $intStartPosition, $intEndPosition - $intStartPosition);
288					$intStartPosition = $intEndPosition + strlen($strArray[$intIndex]);
289
290					switch ($strArray[$intIndex]) {
291						case 'M':
292							$strToReturn .= parent::format('n');
293							break;
294						case 'MM':
295							$strToReturn .= parent::format('m');
296							break;
297						case 'MMM':
298							$strToReturn .= parent::format('M');
299							break;
300						case 'MMMM':
301							$strToReturn .= parent::format('F');
302							break;
303			
304						case 'D':
305							$strToReturn .= parent::format('j');
306							break;
307						case 'DD':
308							$strToReturn .= parent::format('d');
309							break;
310						case 'DDD':
311							$strToReturn .= parent::format('D');
312							break;
313						case 'DDDD':
314							$strToReturn .= parent::format('l');
315							break;
316			
317						case 'YY':
318							$strToReturn .= parent::format('y');
319							break;
320						case 'YYYY':
321							$strToReturn .= parent::format('Y');
322							break;
323			
324						case 'h':
325							$strToReturn .= parent::format('g');
326							break;
327						case 'hh':
328							$strToReturn .= parent::format('h');
329							break;
330						case 'hhh':
331							$strToReturn .= parent::format('G');
332							break;
333						case 'hhhh':
334							$strToReturn .= parent::format('H');
335							break;
336
337						case 'mm':
338							$strToReturn .= parent::format('i');
339							break;
340			
341						case 'ss':
342							$strToReturn .= parent::format('s');
343							break;
344			
345						case 'z':
346							$strToReturn .= parent::format('a');
347							break;
348						case 'zz':
349							$strToReturn .= parent::format('A');
350							break;
351						case 'zzz':
352							$strToReturn .= sprintf('%s.m.', substr(parent::format('a'), 0, 1));
353							break;
354						case 'zzzz':
355							$strToReturn .= sprintf('%s.M.', substr(parent::format('A'), 0, 1));
356							break;
357
358						case 'ttt':
359							$strToReturn .= parent::format('T');
360							break;
361						case 'tttt':
362							$strToReturn .= parent::format('e');
363							break;
364
365						default:
366							$strToReturn .= $strArray[$intIndex];
367					}
368				}
369			}
370
371			if ($intStartPosition < strlen($strFormat))
372				$strToReturn .= substr($strFormat, $intStartPosition);
373
374			return $strToReturn;
375		}
376
377		public function format($strFormat) {
378			$this->ReinforceNullProperties();
379			return parent::format($strFormat);
380		}
381
382		public function setTime($intHour, $intMinute = null, $intSecond = null) {
383			// If HOUR or MINUTE is NULL...
384			if (is_null($intHour) || is_null($intMinute)) {
385				parent::setTime($intHour, $intMinute, $intSecond);
386				$this->blnTimeNull = true;
387				return $this;
388			}
389
390			$intHour = QType::Cast($intHour, QType::Integer);
391			$intMinute = QType::Cast($intMinute, QType::Integer);
392			$intSecond = QType::Cast($intSecond, QType::Integer);
393			$this->blnTimeNull = false;
394			parent::setTime($intHour, $intMinute, $intSecond);
395			return $this;
396		}
397
398		public function setDate($intYear, $intMonth, $intDay) {
399			$intYear = QType::Cast($intYear, QType::Integer);
400			$intMonth = QType::Cast($intMonth, QType::Integer);
401			$intDay = QType::Cast($intDay, QType::Integer);
402			$this->blnDateNull = false;
403			parent::setDate($intYear, $intMonth, $intDay);
404			return $this;
405		}
406
407		protected function ReinforceNullProperties() {
408			if ($this->blnDateNull)
409				parent::setDate(2000, 1, 1);
410			if ($this->blnTimeNull)
411				parent::setTime(0, 0, 0);
412		}
413		
414		/**
415		 * Converts the current QDateTime object to a different TimeZone.
416		 * 
417		 * TimeZone should be passed in as a string-based identifier.
418		 * 
419		 * Note that this is different than the built-in DateTime::SetTimezone() method which expicitly
420		 * takes in a DateTimeZone object.  QDateTime::ConvertToTimezone allows you to specify any
421		 * string-based Timezone identifier.  If none is specified and/or if the specified timezone
422		 * is not a valid identifier, it will simply remain unchanged as opposed to throwing an exeception
423		 * or error.
424		 * 
425		 * @param string $strTimezoneIdentifier a string-based parameter specifying a timezone identifier (e.g. America/Los_Angeles)
426		 * @return void
427		 */
428		public function ConvertToTimezone($strTimezoneIdentifier) {
429			try {
430				$dtzNewTimezone = new DateTimeZone($strTimezoneIdentifier);
431				$this->SetTimezone($dtzNewTimezone);
432			} catch (Exception $objExc) {}
433		}		
434
435		public function IsEqualTo(QDateTime $dttCompare) {
436			// All comparison operations MUST have operands with matching Date Nullstates
437			if ($this->blnDateNull != $dttCompare->blnDateNull)
438				return false;
439
440			// If mismatched Time nullstates, then only compare the Date portions
441			if ($this->blnTimeNull != $dttCompare->blnTimeNull) {
442				// Let's "Null Out" the Time
443				$dttThis = new QDateTime($this);
444				$dttThat = new QDateTime($dttCompare);
445				$dttThis->Hour = null;
446				$dttThat->Hour = null;
447
448				// Return the Result
449				return ($dttThis->Timestamp == $dttThat->Timestamp);
450			} else {
451				// Return the Result for the both Date and Time components
452				return ($this->Timestamp == $dttCompare->Timestamp);
453			}
454		}
455
456		public function IsEarlierThan(QDateTime $dttCompare) {
457			// All comparison operations MUST have operands with matching Date Nullstates
458			if ($this->blnDateNull != $dttCompare->blnDateNull)
459				return false;
460
461			// If mismatched Time nullstates, then only compare the Date portions
462			if ($this->blnTimeNull != $dttCompare->blnTimeNull) {
463				// Let's "Null Out" the Time
464				$dttThis = new QDateTime($this);
465				$dttThat = new QDateTime($dttCompare);
466				$dttThis->Hour = null;
467				$dttThat->Hour = null;
468
469				// Return the Result
470				return ($dttThis->Timestamp < $dttThat->Timestamp);
471			} else {
472				// Return the Result for the both Date and Time components
473				return ($this->Timestamp < $dttCompare->Timestamp);
474			}
475		}
476
477		public function IsEarlierOrEqualTo(QDateTime $dttCompare) {
478			// All comparison operations MUST have operands with matching Date Nullstates
479			if ($this->blnDateNull != $dttCompare->blnDateNull)
480				return false;
481
482			// If mismatched Time nullstates, then only compare the Date portions
483			if ($this->blnTimeNull != $dttCompare->blnTimeNull) {
484				// Let's "Null Out" the Time
485				$dttThis = new QDateTime($this);
486				$dttThat = new QDateTime($dttCompare);
487				$dttThis->Hour = null;
488				$dttThat->Hour = null;
489
490				// Return the Result
491				return ($dttThis->Timestamp <= $dttThat->Timestamp);
492			} else {
493				// Return the Result for the both Date and Time components
494				return ($this->Timestamp <= $dttCompare->Timestamp);
495			}
496		}
497
498		public function IsLaterThan(QDateTime $dttCompare) {
499			// All comparison operations MUST have operands with matching Date Nullstates
500			if ($this->blnDateNull != $dttCompare->blnDateNull)
501				return false;
502
503			// If mismatched Time nullstates, then only compare the Date portions
504			if ($this->blnTimeNull != $dttCompare->blnTimeNull) {
505				// Let's "Null Out" the Time
506				$dttThis = new QDateTime($this);
507				$dttThat = new QDateTime($dttCompare);
508				$dttThis->Hour = null;
509				$dttThat->Hour = null;
510
511				// Return the Result
512				return ($dttThis->Timestamp > $dttThat->Timestamp);
513			} else {
514				// Return the Result for the both Date and Time components
515				return ($this->Timestamp > $dttCompare->Timestamp);
516			}
517		}
518
519		public function IsLaterOrEqualTo(QDateTime $dttCompare) {
520			// All comparison operations MUST have operands with matching Date Nullstates
521			if ($this->blnDateNull != $dttCompare->blnDateNull)
522				return false;
523
524			// If mismatched Time nullstates, then only compare the Date portions
525			if ($this->blnTimeNull != $dttCompare->blnTimeNull) {
526				// Let's "Null Out" the Time
527				$dttThis = new QDateTime($this);
528				$dttThat = new QDateTime($dttCompare);
529				$dttThis->Hour = null;
530				$dttThat->Hour = null;
531
532				// Return the Result
533				return ($dttThis->Timestamp >= $dttThat->Timestamp);
534			} else {
535				// Return the Result for the both Date and Time components
536				return ($this->Timestamp >= $dttCompare->Timestamp);
537			}
538		}
539
540		public function Difference(QDateTime $dttDateTime) {
541			$intDifference = $this->Timestamp - $dttDateTime->Timestamp;
542			return new QDateTimeSpan($intDifference);
543		}
544
545		public function Add($dtsSpan){
546			if (!$dtsSpan instanceof QDateTimeSpan) {
547				throw new QCallerException("Can only add QDateTimeSpan objects");
548			}
549			// Get this DateTime timestamp
550			$intTimestamp = $this->Timestamp;
551
552			// And add the Span Second count to it
553			$this->Timestamp = $this->Timestamp + $dtsSpan->Seconds;
554			return $this;
555		}
556
557		public function AddSeconds($intSeconds){
558			$this->Second += $intSeconds;
559			return $this;
560		}
561
562		public function AddMinutes($intMinutes){
563			$this->Minute += $intMinutes;
564			return $this;
565		}
566
567		public function AddHours($intHours){
568			$this->Hour += $intHours;
569			return $this;
570		}
571
572		public function AddDays($intDays){
573			$this->Day += $intDays;
574			return $this;
575		}
576
577		public function AddMonths($intMonths){
578			$this->Month += $intMonths;
579			return $this;
580		}
581
582		public function AddYears($intYears){
583			$this->Year += $intYears;
584			return $this;
585		}
586		
587		public function Modify($mixValue) {
588			parent::modify($mixValue);
589			return $this;
590		}
591
592		public function __get($strName) {
593			$this->ReinforceNullProperties();
594
595			switch ($strName) {
596				case 'Month':
597					if ($this->blnDateNull)
598						return null;
599					else
600						return (int) parent::format('m');
601
602				case 'Day':
603					if ($this->blnDateNull)
604						return null;
605					else
606						return (int) parent::format('d');
607
608				case 'Year':
609					if ($this->blnDateNull)
610						return null;
611					else
612						return (int) parent::format('Y');
613
614				case 'Hour':
615					if ($this->blnTimeNull)
616						return null;
617					else
618						return (int) parent::format('H');
619
620				case 'Minute':
621					if ($this->blnTimeNull)
622						return null;
623					else
624						return (int) parent::format('i');
625
626				case 'Second':
627					if ($this->blnTimeNull)
628						return null;
629					else
630						return (int) parent::format('s');
631
632				case 'Timestamp':
633					// Until PHP fixes a bug where lowest int is int(-2147483648) but lowest float/double is (-2147529600)
634					// We return as a "double"
635					return (double) parent::format('U');
636
637				case 'Age':
638					// Figure out the Difference from "Now"
639					$dtsFromCurrent = $this->Difference(QDateTime::Now());
640					
641					// It's in the future ('about 2 hours from now')
642					if ($dtsFromCurrent->IsPositive())
643						return $dtsFromCurrent->SimpleDisplay() . ' from now';
644
645					// It's in the past ('about 5 hours ago')
646					else if ($dtsFromCurrent->IsNegative()) {
647						$dtsFromCurrent->Seconds = abs($dtsFromCurrent->Seconds);
648						return $dtsFromCurrent->SimpleDisplay() . ' ago';
649
650					// It's current
651					} else
652						return 'right now';
653
654				default:
655					throw new QUndefinedPropertyException('GET', 'QDateTime', $strName);
656			}
657		}
658
659		public function __set($strName, $mixValue) {
660			try {
661				switch ($strName) {
662					case 'Month':
663						if ($this->blnDateNull && (!is_null($mixValue)))
664							throw new QDateTimeNullException('Cannot set the Month property on a null date.  Use SetDate().');
665						if (is_null($mixValue)) {
666							$this->blnDateNull = true;
667							$this->ReinforceNullProperties();
668							return null;
669						}
670						$mixValue = QType::Cast($mixValue, QType::Integer);
671						parent::setDate(parent::format('Y'), $mixValue, parent::format('d'));
672						return $mixValue;
673
674					case 'Day':
675						if ($this->blnDateNull && (!is_null($mixValue)))
676							throw new QDateTimeNullException('Cannot set the Day property on a null date.  Use SetDate().');
677						if (is_null($mixValue)) {
678							$this->blnDateNull = true;
679							$this->ReinforceNullProperties();
680							return null;
681						}
682						$mixValue = QType::Cast($mixValue, QType::Integer);
683						parent::setDate(parent::format('Y'), parent::format('m'), $mixValue);
684						return $mixValue;
685
686					case 'Year':
687						if ($this->blnDateNull && (!is_null($mixValue)))
688							throw new QDateTimeNullException('Cannot set the Year property on a null date.  Use SetDate().');
689						if (is_null($mixValue)) {
690							$this->blnDateNull = true;
691							$this->ReinforceNullProperties();
692							return null;
693						}
694						$mixValue = QType::Cast($mixValue, QType::Integer);
695						parent::setDate($mixValue, parent::format('m'), parent::format('d'));
696						return $mixValue;
697
698					case 'Hour':
699						if ($this->blnTimeNull && (!is_null($mixValue)))
700							throw new QDateTimeNullException('Cannot set the Hour property on a null time.  Use SetTime().');
701						if (is_null($mixValue)) {
702							$this->blnTimeNull = true;
703							$this->ReinforceNullProperties();
704							return null;
705						}
706						$mixValue = QType::Cast($mixValue, QType::Integer);
707						parent::setTime($mixValue, parent::format('i'), parent::format('s'));
708						return $mixValue;
709
710					case 'Minute':
711						if ($this->blnTimeNull && (!is_null($mixValue)))
712							throw new QDateTimeNullException('Cannot set the Minute property on a null time.  Use SetTime().');
713						if (is_null($mixValue)) {
714							$this->blnTimeNull = true;
715							$this->ReinforceNullProperties();
716							return null;
717						}
718						$mixValue = QType::Cast($mixValue, QType::Integer);
719						parent::setTime(parent::format('H'), $mixValue, parent::format('s'));
720						return $mixValue;
721
722					case 'Second':
723						if ($this->blnTimeNull && (!is_null($mixValue)))
724							throw new QDateTimeNullException('Cannot set the Second property on a null time.  Use SetTime().');
725						if (is_null($mixValue)) {
726							$this->blnTimeNull = true;
727							$this->ReinforceNullProperties();
728							return null;
729						}
730						$mixValue = QType::Cast($mixValue, QType::Integer);
731						parent::setTime(parent::format('H'), parent::format('i'), $mixValue);
732						return $mixValue;
733
734					case 'Timestamp':
735						$mixValue = QType::Cast($mixValue, QType::Integer);
736						$this->blnDateNull = false;
737						$this->blnTimeNull = false;
738
739						$this->SetDate(date('Y', $mixValue), date('m', $mixValue), date('d', $mixValue));
740						$this->SetTime(date('H', $mixValue), date('i', $mixValue), date('s', $mixValue));
741						return $mixValue;
742
743					default:
744						throw new QUndefinedPropertyException('SET', 'QDateTime', $strName);
745				}
746			} catch (QInvalidCastException $objExc) {
747				$objExc->IncrementOffset();
748				throw $objExc;
749			}
750		}
751	}
752
753/*
754	This is a reference to the documentation for hte PHP DateTime classes (as of PHP 5.2)
755
756      DateTime::ATOM
757      DateTime::COOKIE
758      DateTime::ISO8601
759      DateTime::RFC822
760      DateTime::RFC850
761      DateTime::RFC1036
762      DateTime::RFC1123
763      DateTime::RFC2822
764      DateTime::RFC3339
765      DateTime::RSS
766      DateTime::W3C
767
768      DateTime::__construct([string time[, DateTimeZone object]])
769      - Returns new DateTime object
770      
771      string DateTime::format(string format)
772      - Returns date formatted according to given format
773      
774      long DateTime::getOffset()
775      - Returns the DST offset
776      
777      DateTimeZone DateTime::getTimezone()
778      - Return new DateTimeZone object relative to give DateTime
779      
780      void DateTime::modify(string modify)
781      - Alters the timestamp
782      
783      array DateTime::parse(string date)
784      - Returns associative array with detailed info about given date
785      
786      void DateTime::setDate(long year, long month, long day)
787      - Sets the date
788      
789      void DateTime::setISODate(long year, long week[, long day])
790      - Sets the ISO date
791      
792      void DateTime::setTime(long hour, long minute[, long second])
793      - Sets the time
794      
795      void DateTime::setTimezone(DateTimeZone object)
796      - Sets the timezone for the DateTime object
797*/
798
799/* Some quick and dirty test harnesses
800	$dtt1 = new QDateTime();
801	$dtt2 = new QDateTime();
802	printTable($dtt1, $dtt2);
803	$dtt2->setDate(2000, 1, 1);
804	$dtt1->setTime(0,0,3);
805	$dtt2->setTime(0,0,2);
806//	$dtt2->Month++;
807	printTable($dtt1, $dtt2);
808
809	function printTable($dtt1, $dtt2) {
810		print('<table border="1" cellpadding="2"><tr><td>');
811		printDate($dtt1);
812		print('</td><td>');
813		printDate($dtt2);
814		print ('</td></tr>');
815		
816		print ('<tr><td colspan="2" align="center">IsEqualTo: <b>' . (($dtt1->IsEqualTo($dtt2)) ? 'Yes' : 'No') . '</b></td></tr>');
817		print ('<tr><td colspan="2" align="center">IsEarlierThan: <b>' . (($dtt1->IsEarlierThan($dtt2)) ? 'Yes' : 'No') . '</b></td></tr>');
818		print ('<tr><td colspan="2" align="center">IsLaterThan: <b>' . (($dtt1->IsLaterThan($dtt2)) ? 'Yes' : 'No') . '</b></td></tr>');
819		print ('<tr><td colspan="2" align="center">IsEarlierOrEqualTo: <b>' . (($dtt1->IsEarlierOrEqualTo($dtt2)) ? 'Yes' : 'No') . '</b></td></tr>');
820		print ('<tr><td colspan="2" align="center">IsLaterOrEqualTo: <b>' . (($dtt1->IsLaterOrEqualTo($dtt2)) ? 'Yes' : 'No') . '</b></td></tr>');
821		print('</table>');
822	}
823	
824	function printDate($dtt) {
825		print ('Time Null: ' . (($dtt->IsTimeNull()) ? 'Yes' : 'No'));
826		print ('<br/>');
827		print ('Date Null: ' . (($dtt->IsDateNull()) ? 'Yes' : 'No'));
828		print ('<br/>');
829		print ('Date: ' . $dtt->qFormat(QDateTime::FormatDisplayDateTimeFull));
830		print ('<br/>');
831		print ('Month: ' . $dtt->Month . '<br/>');
832		print ('Day: ' . $dtt->Day . '<br/>');
833		print ('Year: ' . $dtt->Year . '<br/>');
834		print ('Hour: ' . $dtt->Hour . '<br/>');
835		print ('Minute: ' . $dtt->Minute . '<br/>');
836		print ('Second: ' . $dtt->Second . '<br/>');
837	}*/
838?>