. */ require_once(ROOT_DIR . 'lib/Common/namespace.php'); class DateTests extends TestBase { private $tz; private $datestring; public function setUp(): void { parent::setup(); $this->datestring = date(DATE_W3C, time()); $this->tz = new DateTimeZone('UTC'); } public function testCanGetNow() { $format = 'd m y H:i:s'; Date::_ResetNow(); $now = Date::Now(); $datenow = new DateTime(date(Date::SHORT_FORMAT, time())); $this->assertEquals($datenow->format($format), $now->Format($format)); } public function testCanAddDays() { $format = 'd m y H:i:s'; $hour = 11; $minute = 40; $second = 22; $month = 3; $day = 21; $year = 2007; $string = "$year-$month-$day $hour:$minute:$second"; $now = new Date($string); $expectedTS = mktime($hour, $minute, $second, $month, $day + 20, $year); $twentyDaysDate = $now->AddDays(20); $this->assertEquals($expectedTS, $twentyDaysDate->Timestamp()); } public function testCanSubtractDays() { $format = 'd m y H:i:s'; $hour = 11; $minute = 40; $second = 22; $month = 3; $day = 21; $year = 2007; $now = new Date("$year-$month-$day $hour:$minute:$second"); $expectedTS = mktime($hour, $minute, $second, $month, $day - 20, $year); $twentyDaysDate = $now->AddDays(-20); $this->assertEquals($expectedTS, $twentyDaysDate->Timestamp()); } public function testCanGetAsDateTime() { $now = new Date($this->datestring); $datenow = new DateTime($this->datestring); $parts = date_parse($datenow->format(DATE_W3C)); $exptected = mktime( $parts['hour'], $parts['minute'], $parts['second'], $parts['month'], $parts['day'], $parts['year'] ); $this->assertEquals($exptected, $now->Timestamp()); } public function testCanConvertToTimezone() { $format = 'd m y H:i:s'; $now = new Date($this->datestring); $datetime = new DateTime($this->datestring); $datetime->setTimezone(new DateTimeZone('US/Eastern')); $expected = $datetime->format($format); $adjusted = $now->ToTimezone("US/Eastern"); $this->assertEquals($expected, $adjusted->Format($format)); } public function testDateGetsAdjustedIntoProvidedTimezone() { $format = 'd m y H:i:s'; $tzName = 'US/Eastern'; $baseTz = new DateTimeZone($tzName); $actual = new Date($this->datestring, $tzName); $datetime = new DateTime($this->datestring, $baseTz); $expected = $datetime->format($format); $this->assertEquals($expected, $actual->Format($format)); } public function testGmtConvertsDateToGMT() { $format = 'd m y H:i:s'; $date = new Date($this->datestring); $datetime = new DateTime($this->datestring); $datetime->setTimezone(new DateTimeZone('UTC')); $expected = $datetime->format($format); $this->assertEquals($expected, $date->ToUtc()->Format($format)); } public function testDatePartsAreParsedCorrectly() { $hour = 11; $minute = 40; $second = 22; $month = 3; $day = 21; $year = 2007; $date = new Date("$year-$month-$day $hour:$minute:$second", 'US/Central'); $this->assertEquals($hour, $date->Hour()); $this->assertEquals($minute, $date->Minute()); $this->assertEquals($second, $date->Second()); $this->assertEquals($month, $date->Month()); $this->assertEquals($day, $date->Day()); $this->assertEquals($year, $date->Year()); $adjusted = $date->ToTimezone('US/Eastern'); $this->assertEquals($hour + 1, $adjusted->Hour()); $this->assertEquals($minute, $adjusted->Minute()); $this->assertEquals($second, $adjusted->Second()); $this->assertEquals($month, $adjusted->Month()); $this->assertEquals($day, $adjusted->Day()); $this->assertEquals($year, $adjusted->Year()); } public function testToDatabaseConvertsToGmtThenFormats() { $databaseformat = 'Y-m-d H:i:s'; $date = new Date($this->datestring); $datetime = new DateTime($this->datestring); $datetime->setTimezone(new DateTimeZone('UTC')); $expected = $datetime->format($databaseformat); $this->assertEquals($expected, $date->ToDatabase()); } public function testCanCreateTimeInServerTimezone() { $hour = 10; $min = 22; $sec = 21; $time = new Time($hour, $min, $sec); $this->assertEquals("$hour:$min:$sec", $time->ToString()); $this->assertEquals($hour, $time->Hour()); $this->assertEquals($min, $time->Minute()); $this->assertEquals($sec, $time->Second()); $time = new Time($hour, $min); $this->assertEquals("$hour:$min:00", $time->ToString()); $this->assertEquals($hour, $time->Hour()); $this->assertEquals($min, $time->Minute()); $this->assertEquals(0, $time->Second()); } public function testTimeCreatedInEasternCanBeConvertedToCentral() { $east = 'America/New_York'; $central = 'America/Chicago'; $hour = 10; $min = 10; $sec = 10; $time = Date::Create(2001, 1, 1, $hour, $min, $sec, $east); $converted = $time->ToTimezone($central); $this->assertEquals($hour - 1, $converted->Hour()); $this->assertEquals($min, $converted->Minute()); $this->assertEquals($sec, $converted->Second()); $time = Date::Create(2001, 1, 1, 0, $min, $sec, $east); $converted = $time->ToTimezone($central); $this->assertEquals(23, $converted->Hour()); $time = Date::Create(2001, 1, 1, 1, $min, $sec, $east); $converted = $time->ToTimezone($central); $this->assertEquals(0, $converted->Hour()); } public function testCanParseTimeFromString() { $time = Time::Parse('10:11:12', 'UTC'); $this->assertEquals(10, $time->Hour()); $this->assertEquals(11, $time->Minute()); $this->assertEquals(12, $time->Second()); $this->assertEquals('UTC', $time->Timezone()); $time = Time::Parse('13:11:12', 'UTC'); $this->assertEquals(13, $time->Hour()); $this->assertEquals(11, $time->Minute()); $this->assertEquals(12, $time->Second()); $this->assertEquals('UTC', $time->Timezone()); $time = Time::Parse('10:11:12 PM', 'UTC'); $this->assertEquals(22, $time->Hour()); $this->assertEquals(11, $time->Minute()); $this->assertEquals(12, $time->Second()); $this->assertEquals('UTC', $time->Timezone()); $time = Time::Parse('10:11:12 AM', 'UTC'); $this->assertEquals(10, $time->Hour()); $this->assertEquals(11, $time->Minute()); $this->assertEquals(12, $time->Second()); $this->assertEquals('UTC', $time->Timezone()); $time = Time::Parse('10:11 AM', 'UTC'); $this->assertEquals(10, $time->Hour()); $this->assertEquals(11, $time->Minute()); $this->assertEquals(00, $time->Second()); $this->assertEquals('UTC', $time->Timezone()); } public function testTimesCanBeCompared() { $date = Date::Parse('2010-01-01'); $early = Time::Parse('10:11'); $late = Time::Parse('12:11'); $this->assertEquals(-1, $early->Compare($late, $date)); $this->assertEquals(1, $late->Compare($early, $date)); $early2 = Time::Parse('10:11', 'US/Central'); $late2 = Time::Parse('10:11', 'US/Pacific'); $this->assertEquals(-1, $early2->Compare($late2, $date)); } public function testCanCompareDateOnlyEquality() { $date1 = Date::Parse('2008-01-01 11:00:00', 'US/Central'); $date2 = Date::Parse('2008-01-01 11:00:00', 'US/Eastern'); $this->assertTrue($date1->DateEquals($date2)); $date1 = Date::Parse('2008-01-01 00:00:00', 'US/Central'); $date2 = Date::Parse('2008-01-01 00:00:00', 'US/Eastern'); $this->assertFalse($date1->DateEquals($date2)); } public function testCreateBuildsDateObjectCorectly() { $date = Date::Create(2008, 10, 9, 8, 7, 6, 'US/Central'); $this->assertEquals(2008, $date->Year()); $this->assertEquals(10, $date->Month()); $this->assertEquals(9, $date->Day()); $this->assertEquals(8, $date->Hour()); $this->assertEquals(7, $date->Minute()); $this->assertEquals(6, $date->Second()); $this->assertEquals('US/Central', $date->Timezone()); } public function testCanCompareDateRelativity() { $date1 = Date::Parse('2008-01-01 11:00:00', 'US/Central'); $date2 = Date::Parse('2008-01-01 11:00:00', 'US/Eastern'); $this->assertEquals(0, $date1->DateCompare($date2)); $date1 = Date::Parse('2008-01-01 00:00:00', 'US/Central'); $date2 = Date::Parse('2008-01-01 00:00:00', 'US/Eastern'); $this->assertEquals(1, $date1->DateCompare($date2), 'midnight eastern is 11pm central'); $date1 = Date::Parse('2008-01-01 00:00:00', 'US/Central'); $date2 = Date::Parse('2008-01-01 22:00:00', 'US/Pacific'); $this->assertEquals(-1, $date1->DateCompare($date2), 'midnight pacific is 2 am central'); } public function GetDateReturnsDateAsOfMidnight() { $date = new Date('2009-10-10 10:10:10'); $onlyDate = $date->GetDate(); $this->assertEquals(0, $onlyDate->Hour()); $this->assertEquals(0, $onlyDate->Minute()); $this->assertEquals(0, $onlyDate->Second()); } public function testDateIsWithinRange() { $begin = Date::Create(2008, 9, 9, 10, 11, 12, 'UTC'); $end = Date::Create(2008, 10, 9, 10, 11, 12, 'UTC'); $range = new DateRange($begin, $end); $within = $begin->AddDays(10); $notWithin = $begin->AddDays(-10); $exactStart = $begin; $exactEnd = $end; $this->assertTrue($range->Contains($within)); $this->assertTrue($range->Contains($exactStart)); $this->assertTrue($range->Contains($exactEnd)); $this->assertFalse($range->Contains($notWithin)); } public function testDateRangeIsWithinRange() { $begin = Date::Create(2008, 9, 9, 10, 11, 12, 'UTC'); $end = Date::Create(2008, 10, 9, 10, 11, 12, 'UTC'); $range = new DateRange($begin, $end); $within = new DateRange($begin->AddDays(10), $end->AddDays(-10)); $notWithin = new DateRange($begin->AddDays(-10), $end->AddDays(-1)); $exact = new DateRange($begin, $end); $this->assertTrue($range->ContainsRange($within)); $this->assertTrue($range->ContainsRange($exact)); $this->assertFalse($range->ContainsRange($notWithin)); } public function testDateRangeReturnsAllDatesForRangeWithoutTime() { $begin = Date::Create(2008, 9, 9, 10, 11, 12, 'UTC'); $end = Date::Create(2008, 9, 12, 10, 11, 12, 'UTC'); $range = new DateRange($begin, $end); $expected[] = $begin->GetDate(); $expected[] = $begin->AddDays(1)->GetDate(); $expected[] = $begin->AddDays(2)->GetDate(); $expected[] = $begin->AddDays(3)->GetDate(); $actual = $range->Dates(); // foreach ($expected as $d) // { // echo $d->ToString(); // echo "\n"; // } // // echo "\n"; // // foreach ($actual as $d) // { // echo $d->ToString(); // echo "\n"; // } // $this->assertEquals($expected, $actual); $this->assertEquals(count($expected), count($actual)); $this->assertTrue($expected[0]->Equals($actual[0]), "Dates[0] are not equal"); $this->assertTrue($expected[1]->Equals($actual[1]), "Dates[1] are not equal"); $this->assertTrue($expected[2]->Equals($actual[2]), "Dates[2] are not equal"); $this->assertTrue($expected[3]->Equals($actual[3]), "Dates[3] are not equal"); } public function testCanGetDifferenceBetweenTwoDates() { $date1 = Date::Parse('2011-01-01 12:15:45', 'UTC'); $date2 = $date1->AddDays(1); $diff = $date1->GetDifference($date2); $secondsInOneDay = 60 * 60 * 24; $this->assertEquals($diff->TotalSeconds(), $secondsInOneDay, '2nd date is one day greater than 1st date'); $this->assertEquals(1, $diff->Days()); $this->assertEquals(0, $diff->Hours()); $this->assertEquals(0, $diff->Minutes()); $newDate = $date1->ApplyDifference($diff); $this->assertTrue($date2->Equals($newDate)); $laterDate = Date::Parse('2011-07-26 05:30:00', 'America/New_York'); $earlierDate = Date::Parse('2011-07-22 17:40:41', 'America/Chicago'); $diff = $laterDate->GetDifference($earlierDate); $shouldBeEarlier = $laterDate->ApplyDifference($diff); $this->assertTrue($earlierDate->Equals($shouldBeEarlier)); } public function testCanGetDifferenceBetweenTwoTimes() { $date1 = Date::Parse('2011-01-01 12:15:45', 'utc'); $date2 = Date::Parse('2011-01-01 13:16:46', 'utc'); $diff = $date1->GetDifference($date2); $this->assertEquals(0, $diff->Days()); $this->assertEquals(1, $diff->Hours()); $this->assertEquals(1, $diff->Minutes()); } public function testCanGetDifferenceFromTime() { $seconds = (12 * 60 * 60) + (60 * 35); $str1 = "0d12h35m"; $diff1 = DateDiff::FromTimeString($str1); $this->assertEquals($seconds, $diff1->TotalSeconds()); $this->assertEquals(12, $diff1->Hours()); $this->assertEquals(35, $diff1->Minutes()); $this->assertEquals(0, $diff1->Days()); $this->assertEquals("12 hours 35 minutes", $diff1->__toString()); $seconds2 = (4 * 24 * 60 * 60) + (12 * 60 * 60) + (60 * 35); $str2 = "4d12h35m"; $diff2 = DateDiff::FromTimeString($str2); $this->assertEquals($seconds2, $diff2->TotalSeconds()); $this->assertEquals(12, $diff2->Hours()); $this->assertEquals(35, $diff2->Minutes()); $this->assertEquals(4, $diff2->Days()); $this->assertEquals("4 days 12 hours 35 minutes", $diff2->__toString()); $diff3 = DateDiff::FromTimeString("25h0m"); $this->assertEquals((25 * 60 * 60), $diff3->TotalSeconds()); $this->assertEquals(0, DateDiff::FromTimeString("dhm")->TotalSeconds()); $this->assertEquals(0, DateDiff::FromTimeString("hm")->TotalSeconds()); $this->assertEquals(0, DateDiff::FromTimeString("dm")->TotalSeconds()); } public function testDateRangeOverlapsIfStartsWithinOrEndsWithin() { $dr1 = DateRange::Create('2011-01-01 12:00:00', '2011-01-02 11:00:00', 'UTC'); $dr2 = DateRange::Create('2011-01-01 12:00:00', '2011-01-02 10:00:00', 'UTC'); $this->assertTrue($dr1->Overlaps($dr2)); } public function testDateRangeOverlapsIfStartsAndEndsExactlyTheSameTimes() { $dr1 = DateRange::Create('2011-01-01 12:00:00', '2011-01-02 11:00:00', 'UTC'); $dr2 = DateRange::Create('2011-01-01 12:00:00', '2011-01-02 11:00:00', 'UTC'); $this->assertTrue($dr1->Overlaps($dr2)); } public function testDateRangeDoesNotOverlapIfStartsAtEnd() { $dr1 = DateRange::Create('2011-01-01 12:00:00', '2011-01-02 11:00:00', 'UTC'); $dr2 = DateRange::Create('2011-01-02 11:00:00', '2011-01-04 10:00:00', 'UTC'); $this->assertFalse($dr1->Overlaps($dr2)); } public function testDateRangeOccursOnDateIfAnyDateStartsOrEnds() { $range = DateRange::Create('2011-01-01 12:00:00', '2011-01-03 00:00:00', 'UTC'); $d1 = Date::Parse('2011-01-02 02:02:02', 'UTC'); $d2 = Date::Parse('2011-01-01 23:59:59', 'UTC'); $d3 = Date::Parse('2011-01-03 00:00:00', 'UTC'); $this->assertTrue($range->OccursOn($d1)); $this->assertTrue($range->OccursOn($d2)); $this->assertFalse($range->OccursOn($d3)); } public function testNullDateTests() { $null = NullDate::Instance(); $this->assertNull($null->ToDatabase()); $this->assertEquals($null, $null->ToTimezone('anything')); } public function testCanParseExactWithTimezone() { $d = Date::Parse('2012-04-06 12:02:03', 'America/New_York'); $iso = $d->ToIso(); $d2 = Date::ParseExact($iso, 'America/New_York'); $this->assertTrue($d->Equals($d2), $d->ToUtc()->ToString() . ' ' . $d2->ToString()); } public function testJan31Bug() { $d = new Date('2013-01-31', 'America/Chicago'); $this->assertEquals(31, $d->Day()); $this->assertEquals(1, $d->Month()); $this->assertEquals(2013, $d->Year()); } public function testTimeIntervalParsesEmptyValue() { $interval = TimeInterval::Parse('dhm'); $this->assertEquals(0, $interval->TotalSeconds()); } public function testWhenComparingDatePartOnly_UseTimeOfSourceDate() { $d1 = new Date('2014-09-14 02:00:00', 'America/Chicago'); $d2 = new Date('2014-09-14 00:00:00', 'Europe/Berlin'); $this->assertFalse($d1->DateEquals($d2)); $d1 = new Date('2014-09-14 00:00:00', 'America/Chicago'); $d2 = new Date('2014-09-14 07:00:00', 'Europe/Berlin'); $this->assertTrue($d1->DateEquals($d2)); $d1 = new Date('2014-09-14 02:00:00', 'America/Chicago'); $d2 = new Date('2014-09-15 00:00:00', 'Europe/Berlin'); $this->assertTrue($d1->DateEquals($d2)); // $d1 = new Date('2014-09-14 02:00:00', 'America/Chicago'); // $d2 = new Date('2014-09-14 22:00:00', 'Europe/Berlin'); // // $this->assertFalse($d1->DateEquals($d2)); } public function testCountsWeekdaysAndWeekends() { $timezone = 'America/Chicago'; $begin = Date::Parse('2014-11-01 12:00', $timezone); $end = Date::Parse('2014-11-20 08:00', $timezone); $range = new DateRange($begin, $end, $timezone); $this->assertEquals(14, $range->NumberOfWeekdays()); $this->assertEquals(6, $range->NumberOfWeekendDays()); } public function testOneWeekday() { $timezone = 'America/Chicago'; $begin = Date::Parse('2014-11-03 12:00', $timezone); $end = Date::Parse('2014-11-03 13:00', $timezone); $range = new DateRange($begin, $end, $timezone); $this->assertEquals(1, $range->NumberOfWeekdays()); $this->assertEquals(0, $range->NumberOfWeekendDays()); } public function testOneWeekendDay() { $timezone = 'America/Chicago'; $begin = Date::Parse('2014-11-01 12:00', $timezone); $end = Date::Parse('2014-11-01 13:00', $timezone); $range = new DateRange($begin, $end, $timezone); $this->assertEquals(0, $range->NumberOfWeekdays()); $this->assertEquals(1, $range->NumberOfWeekendDays()); } public function testWhenEndDateIsAtMidnight_DoNotCountIt() { $timezone = 'America/Chicago'; $begin = Date::Parse('2014-11-01 12:00', $timezone); $end = Date::Parse('2014-11-02 00:00', $timezone); $range = new DateRange($begin, $end, $timezone); $this->assertEquals(0, $range->NumberOfWeekdays()); $this->assertEquals(1, $range->NumberOfWeekendDays()); } public function testWebServiceDateDropsUsesIfSetTimezoneOffset() { $date = WebServiceDate::GetDate('2014-09-14T06:00:00-0000', $this->fakeUser); $this->assertEquals($date->Hour(), 6); $this->assertEquals($date->Timezone(), 'UTC'); } public function testWebServiceParsesJustDate() { $date = WebServiceDate::GetDate('2014-09-14', $this->fakeUser); $this->assertEquals($date->Hour(), 0); $this->assertEquals($date->Timezone(), $this->fakeUser->Timezone); } public function testWebServiceParsesJustDateAndTime() { $date = WebServiceDate::GetDate('2014-09-14 06:00:00', $this->fakeUser); $this->assertEquals($date->Hour(), 6); $this->assertEquals($date->Timezone(), $this->fakeUser->Timezone); } public function testDateRangeReturnsAllDatesTimesForRange() { $begin = Date::Create(2008, 9, 9, 10, 11, 12, 'UTC'); $end = Date::Create(2008, 9, 12, 10, 11, 12, 'UTC'); $range = new DateRange($begin, $end); $expected[] = $begin; $expected[] = $begin->AddDays(1)->GetDate(); $expected[] = $begin->AddDays(2)->GetDate(); $expected[] = $end; $actual = $range->DateTimes(); $this->assertEquals(count($expected), count($actual)); $this->assertTrue($expected[0]->Equals($actual[0]), "Dates[0] are not equal"); $this->assertTrue($expected[1]->Equals($actual[1]), "Dates[1] are not equal"); $this->assertTrue($expected[2]->Equals($actual[2]), "Dates[2] are not equal"); $this->assertTrue($expected[3]->Equals($actual[3]), "Dates[3] are not equal"); } }