Skip to content

Commit 7e334b2

Browse files
committed
Time comparison functions
1 parent 5eef935 commit 7e334b2

2 files changed

Lines changed: 234 additions & 0 deletions

File tree

system/I18n/Time.php

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,10 +980,146 @@ public function toLocalizedString(string $format = null)
980980
return IntlDateFormatter::formatObject($this->toDateTime(), $format, $this->locale);
981981
}
982982

983+
//--------------------------------------------------------------------
984+
985+
//--------------------------------------------------------------------
986+
// Comparison
987+
//--------------------------------------------------------------------
988+
989+
/**
990+
* Determines if the datetime passed in is equal to the current instance.
991+
* Equal in this case means that they represent the same moment in time,
992+
* and are not required to be in the same timezone, as both times are
993+
* converted to UTC and compared that way.
994+
*
995+
* @param Time|DateTime|string $testTime
996+
* @param string|null $timezone
997+
*
998+
* @return bool
999+
*/
1000+
public function equals($testTime, string $timezone = null): bool
1001+
{
1002+
$testTime = $this->getUTCObject($testTime, $timezone);
1003+
1004+
$ourTime = $this->toDateTime()
1005+
->setTimezone(new DateTimeZone('UTC'))
1006+
->format('Y-m-d H:i:s');
1007+
1008+
return $testTime->format('Y-m-d H:i:s') === $ourTime;
1009+
}
1010+
1011+
//--------------------------------------------------------------------
1012+
1013+
/**
1014+
* Ensures that the times are identical, taking timezone into account.
1015+
*
1016+
* @param Time|DateTime|string $testTime
1017+
* @param string|null $timezone
1018+
*
1019+
* @return bool
1020+
*/
1021+
public function sameAs($testTime, string $timezone = null): bool
1022+
{
1023+
if ($testTime instanceof DateTime)
1024+
{
1025+
$testTime = $testTime->format('Y-m-d H:i:s');
1026+
}
1027+
else if (is_string($testTime))
1028+
{
1029+
$timezone = $timezone ?: $this->timezone;
1030+
$timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone);
1031+
$testTime = new DateTime($testTime, $timezone);
1032+
$testTime = $testTime->format('Y-m-d H:i:s');
1033+
}
1034+
1035+
$ourTime = $this->toDateTimeString();
1036+
1037+
return $testTime === $ourTime;
1038+
}
1039+
1040+
//--------------------------------------------------------------------
1041+
1042+
/**
1043+
*
1044+
*
1045+
* @param $testTime
1046+
* @param string|null $timezone
1047+
*
1048+
* @return bool
1049+
*/
1050+
public function before($testTime, string $timezone = null): bool
1051+
{
1052+
$testTime = $this->getUTCObject($testTime, $timezone)->getTimestamp();
1053+
$ourTime = $this->getTimestamp();
1054+
1055+
return $ourTime < $testTime;
1056+
}
1057+
1058+
//--------------------------------------------------------------------
1059+
1060+
/**
1061+
* Determines if the current instance's time is after $testTime,
1062+
* after comparing in UTC.
1063+
*
1064+
* @param $testTime
1065+
* @param string|null $timezone
1066+
*
1067+
* @return bool
1068+
*/
1069+
public function after($testTime, string $timezone = null): bool
1070+
{
1071+
$testTime = $this->getUTCObject($testTime, $timezone)->getTimestamp();
1072+
$ourTime = $this->getTimestamp();
1073+
1074+
return $ourTime > $testTime;
1075+
}
1076+
1077+
//--------------------------------------------------------------------
1078+
9831079
//--------------------------------------------------------------------
9841080
// Utilities
9851081
//--------------------------------------------------------------------
9861082

1083+
public function getUTCObject($time, string $timezone=null)
1084+
{
1085+
if ($time instanceof Time)
1086+
{
1087+
$time = $time->toDateTime()
1088+
->setTimezone(new DateTimeZone('UTC'));
1089+
}
1090+
else if ($time instanceof \DateTime)
1091+
{
1092+
$time = $time->setTimezone(new DateTimeZone('UTC'));
1093+
}
1094+
else if (is_string($time))
1095+
{
1096+
$timezone = $timezone ?: $this->timezone;
1097+
$timezone = $timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone);
1098+
$time = new DateTime($time, $timezone);
1099+
$time = $time->setTimezone(new DateTimeZone('UTC'));
1100+
}
1101+
1102+
return $time;
1103+
}
1104+
1105+
//--------------------------------------------------------------------
1106+
1107+
/**
1108+
* Returns the IntlCalendar object used for this object,
1109+
* taking into account the locale, date, etc.
1110+
*
1111+
* Primarily used internally to provide the difference and comparison functions,
1112+
* but available for public consumption if they need it.
1113+
*
1114+
* @return \IntlCalendar
1115+
*/
1116+
public function getCalendar()
1117+
{
1118+
return \IntlCalendar::fromDateTime($this->toDateTime());
1119+
}
1120+
1121+
//--------------------------------------------------------------------
1122+
9871123
/**
9881124
* Check a time string to see if it includes a relative date (like 'next Tuesday').
9891125
*

tests/system/I18n/TimeTest.php

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,4 +679,102 @@ public function testCanSubtractYears()
679679
$this->assertEquals('2017-01-10 13:20:33', $time->toDateTimeString());
680680
$this->assertEquals('2014-01-10 13:20:33', $newTime->toDateTimeString());
681681
}
682+
683+
//--------------------------------------------------------------------
684+
// Comparison
685+
//--------------------------------------------------------------------
686+
687+
public function testEqualWithDifferent()
688+
{
689+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
690+
$time2 = Time::parse('January 11, 2017 03:50:00', 'Europe/London');
691+
692+
$this->assertTrue($time1->equals($time2));
693+
}
694+
695+
public function testEqualWithSame()
696+
{
697+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
698+
$time2 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
699+
700+
$this->assertTrue($time1->equals($time2));
701+
}
702+
703+
public function testEqualWithDateTime()
704+
{
705+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
706+
$time2 = new \DateTime('January 11, 2017 03:50:00', new \DateTimeZone('Europe/London'));
707+
708+
$this->assertTrue($time1->equals($time2));
709+
}
710+
711+
public function testEqualWithSameDateTime()
712+
{
713+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
714+
$time2 = new \DateTime('January 10, 2017 21:50:00', new \DateTimeZone('America/Chicago'));
715+
716+
$this->assertTrue($time1->equals($time2));
717+
}
718+
719+
public function testEqualWithString()
720+
{
721+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
722+
723+
$this->assertTrue($time1->equals('January 11, 2017 03:50:00', 'Europe/London'));
724+
}
725+
726+
public function testEqualWithStringAndNotimezone()
727+
{
728+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
729+
730+
$this->assertTrue($time1->equals('January 10, 2017 21:50:00'));
731+
}
732+
733+
public function testSameSuccess()
734+
{
735+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
736+
$time2 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
737+
738+
$this->assertTrue($time1->sameAs($time2));
739+
}
740+
741+
public function testSameFailure()
742+
{
743+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
744+
$time2 = Time::parse('January 11, 2017 03:50:00', 'Europe/London');
745+
746+
$this->assertFalse($time1->sameAs($time2));
747+
}
748+
749+
public function testSameSuccessAsString()
750+
{
751+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
752+
753+
$this->assertTrue($time1->sameAs('January 10, 2017 21:50:00', 'America/Chicago'));
754+
}
755+
756+
public function testSameFailAsString()
757+
{
758+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
759+
760+
$this->assertFalse($time1->sameAs('January 11, 2017 03:50:00', 'Europe/London'));
761+
}
762+
763+
public function testBefore()
764+
{
765+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
766+
$time2 = Time::parse('January 11, 2017 03:50:00', 'America/Chicago');
767+
768+
$this->assertTrue($time1->before($time2));
769+
$this->assertFalse($time2->before($time1));
770+
}
771+
772+
public function testAfter()
773+
{
774+
$time1 = Time::parse('January 10, 2017 21:50:00', 'America/Chicago');
775+
$time2 = Time::parse('January 11, 2017 03:50:00', 'America/Chicago');
776+
777+
$this->assertFalse($time1->after($time2));
778+
$this->assertTrue($time2->after($time1));
779+
}
682780
}

0 commit comments

Comments
 (0)