public function testTimeZoneIssues()
 {
     $tz = new DateTimeZone('America/Los_Angeles');
     $dt1 = new QDateTime('11/02/14', $tz);
     // dst boundary date
     $this->assertEquals('America/Los_Angeles', $dt1->getTimezone()->getName());
     $dt2 = new QDateTime($dt1, null, QDateTime::DateOnlyType);
     $this->assertEquals('America/Los_Angeles', $dt2->getTimezone()->getName());
     $this->assertTrue($dt2->IsTimeNull());
     $dt2->setTime(7, 0, 0);
     $this->assertEquals(7, $dt2->Hour);
     $this->assertEquals('America/Los_Angeles', $dt2->getTimezone()->getName());
     // Test a specific PHP 'bug'. Not sure if it is a bug, or just a way things work.
     $dt2 = new QDateTime($dt1->format(DateTime::ISO8601), null, QDateTime::DateOnlyType);
     $dt2->setTime(7, 0, 0);
     $this->assertEquals(7, $dt2->Hour);
     $dt2 = new QDateTime('1/1/14', new DateTimeZone('America/Los_Angeles'));
     $dt2->Timestamp = 1288486753;
     $this->assertEquals('America/Los_Angeles', $dt2->getTimezone()->getName());
     // make sure timezone isn't changed
     $this->assertEquals(1288486753, $dt2->Timestamp);
     // this isn't always true. If this is a dst boundary, it will not be true. Just making sure it is true when its supposed to be
 }
 /**
  * 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;
     }
 }