/**
  * Construct a QDateTime. Does a few things differently than the php version:
  * - Always stores timestamps in local or given timezone, so time extraction is easy
  * - Has settings to determine if you want a date only or time only type
  * - Will NOT throw exceptions. Errors simply result in a null datetime.
  *
  * @param null|integer|string|QDateTime|DateTime $mixValue
  * @param DateTimeZone                           $objTimeZone
  * @param int                                    $intType
  *
  * @throws QCallerException
  */
 public function __construct($mixValue = null, DateTimeZone $objTimeZone = null, $intType = QDateTime::UnknownType)
 {
     if ($mixValue instanceof QDateTime) {
         // Cloning from another QDateTime object
         if ($objTimeZone) {
             throw new QCallerException('QDateTime cloning cannot take in a DateTimeZone parameter');
         }
         parent::__construct($mixValue->format('Y-m-d H:i:s'), $mixValue->GetTimeZone());
         $this->blnDateNull = $mixValue->IsDateNull();
         $this->blnTimeNull = $mixValue->IsTimeNull();
         $this->ReinforceNullProperties();
     } else {
         if ($mixValue instanceof DateTime) {
             // Subclassing from a PHP DateTime object
             if ($objTimeZone) {
                 throw new QCallerException('QDateTime subclassing of a DateTime object cannot take in a DateTimeZone parameter');
             }
             parent::__construct($mixValue->format('Y-m-d H:i:s'), $mixValue->getTimezone());
             // By definition, a DateTime object doesn't have anything nulled
             $this->blnDateNull = false;
             $this->blnTimeNull = false;
         } else {
             if (!$mixValue) {
                 // Set to "null date"
                 // And Do Nothing Else -- Default Values are already set to Nulled out
                 parent::__construct('2000-01-01 00:00:00', $objTimeZone);
             } else {
                 if (strtolower($mixValue) == QDateTime::Now) {
                     // very common, so quickly deal with now string
                     parent::__construct('now', $objTimeZone);
                     $this->blnDateNull = false;
                     $this->blnTimeNull = false;
                 } else {
                     if (substr($mixValue, 0, 1) == '@') {
                         // unix timestamp. PHP superclass will always store ts in UTC. Our class will store in given timezone, or local tz
                         parent::__construct(date('Y-m-d H:i:s', substr($mixValue, 1)), $objTimeZone);
                         $this->blnDateNull = false;
                         $this->blnTimeNull = false;
                     } else {
                         // string relative date or time
                         if ($intTime = strtotime($mixValue)) {
                             // The documentation states that:
                             // The valid range of a timestamp is typically from
                             // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT.
                             // (These are the dates that correspond to the minimum and maximum values
                             // for a 32-bit signed integer).
                             //
                             // But experimentally, 0000-01-01 00:00:00 is the least date displayed correctly
                             if ($intTime < -62167241486) {
                                 // Set to "null date"
                                 // And Do Nothing Else -- Default Values are already set to Nulled out
                                 parent::__construct('2000-01-01 00:00:00', $objTimeZone);
                             } else {
                                 parent::__construct(date('Y-m-d H:i:s', $intTime), $objTimeZone);
                                 $this->blnDateNull = false;
                                 $this->blnTimeNull = false;
                             }
                         } else {
                             // error
                             parent::__construct();
                             $this->blnDateNull = true;
                             $this->blnTimeNull = true;
                         }
                     }
                 }
             }
         }
     }
     // User is requesting to force a particular type.
     switch ($intType) {
         case QDateTime::DateOnlyType:
             $this->blnTimeNull = true;
             $this->ReinforceNullProperties();
             return;
         case QDateTime::TimeOnlyType:
             $this->blnDateNull = true;
             $this->ReinforceNullProperties();
             return;
         case QDateTime::DateAndTimeType:
             // forcing both a date and time type to not be null
             $this->blnDateNull = false;
             $this->blnTimeNull = false;
             break;
         default:
             break;
     }
 }