brick/date-time
Immutable, ISO-8601–focused date/time API for PHP 8.2+ built on top of native DateTime, adding missing types like LocalDate, LocalTime, YearMonth, and MonthDay. Inspired by Java’s JSR-310, well-tested, production-ready, Composer installable.
💥 Breaking changes
final:
YearMonthRangeZonedDateTimeParser\DateTimeParseException✨ Compatibility improvements
+01 equivalent to +01:00 (#123 by @antonkomarev):
IsoParsers:timeZoneOffset()TimeZoneOffset::parse()ZonedDateTime::parse()💥 Breaking changes
Duration::toISOString() and __toString() now output negative durations as -P... (#122 by @BastienClement)-PT2H21M instead of PT-2H-21M.🐛 Bug fixes
ZoneDateTime incorrectly handled DST Transitions with relative time addition (#115)✨ New features
LocalDate::getQuarter() and getQuarterValue() return the quarter of the year (#114 by @pscheit)💥 Breaking changes
DayOfWeek:
of() has been removed, use DayOfWeek::from() insteadDayOfWeek::monday() → DayOfWeek::MONDAYDayOfWeek::tuesday() → DayOfWeek::TUESDAYDayOfWeek::wednesday() → DayOfWeek::WEDNESDAYDayOfWeek::thursday() → DayOfWeek::THURSDAYDayOfWeek::friday() → DayOfWeek::FRIDAYDayOfWeek::saturday() → DayOfWeek::SATURDAYDayOfWeek::sunday() → DayOfWeek::SUNDAYgetValue() has been removed, use $dayOfWeek->value insteadis() has been removed, compare values with $dayOfWeek or $dayOfWeek->value insteadisEqualTo() has been removed, use strict equality === between DayOfWeek instances instead.DefaultClock:
travel() has been removed, use travelTo() insteadLocalDate:
getDay() has been removed, use getDayOfMonth() insteadgetMonth() now returns a Month enum; use getMonthValue() if you want the month numberLocalDateTime:
getDay() has been removed, use getDayOfMonth() insteadgetMonth() now returns a Month enum; use getMonthValue() if you want the month numberMonth:
of() has been removed, use Month::from() insteadgetAll() has been removed, use Month::cases() insteadgetValue() has been removed, use $month->value insteadis() has been removed, compare values with $month or $month->value insteadisEqualTo() has been removed, use strict equality === between Month instances insteadMonthDay:
getDay() has been removed, use getDayOfMonth() insteadgetMonth() now returns a Month enum; use getMonthValue() if you want the month numberYearMonth:
getMonth() now returns a Month enum; use getMonthValue() if you want the month numberZonedDateTime:
getDay() has been removed, use getDayOfMonth() insteadgetMonth() now returns a Month enum; use getMonthValue() if you want the month number🔧 Improvements
int are now type-annotated with int ranges✨ New methods
LocalDate::previousDayOfWeek()LocalDate::previousOrSameDayOfWeek()LocalDate::nextDayOfWeek()LocalDate::nextOrSameDayOfWeek()✨ New features
DefaultClock::travelBy() travels in time by a duration (#92)💩 Deprecations
DefaultClock::travel() is now deprecated in favour of travelTo() (#92)Thanks to [@francislavoie](https://github.com/francislavoie)!
✨ New features
Stopwatch::stop() now returns the lap duration (#98)Thanks to [@rodnaph](https://github.com/rodnaph)!
✨ New features
MonthDay::of() and MonthDay::withMonth() now accept a Month enum as parameter (#106)LocalDate::of() and LocalDate::withMonth() now accept a Month enum as parameter (#106)LocalDateTime::of() and LocalDateTime::withMonth() now accept a Month enum as parameter (#106)ZonedDateTime::withMonth() now accepts a Month enum as parameter (#106)✨ Undeprecations
int to Year::atMonth() is un-deprecated, and now valid again (#103)int to YearMonth::of() and YearMonth::withMonth() is un-deprecated, and now valid again (#103)int to YearWeek::atDay() is un-deprecated, and now valid again (#103)Thanks to [@gnutix](https://github.com/gnutix)!
✨ New features
Year::atMonth() now accepts a Month enum as parameter (#95)YearMonth::of() and YearMonth::withMonth() now accept a Month enum as parameter (#96)🔧 Improvements
compareTo(), __toString(), toISOString(), jsonSerialize() methods (#97)💩 Deprecations
int to Year::atMonth() is now deprecated, pass a Month enum instead (#95)int to YearMonth::of() and YearMonth::withMonth() is now deprecated, pass a Month enum instead (#96)Thanks to [@gnutix](https://github.com/gnutix)!
💥 Breaking changes
DayOfWeek:
DayOfWeek is now an enum: constants MONDAY, TUESDAY, etc. are now DayOfWeek instances, not integers__toString() method is removed, use toString() instead (enums disallow magic methods)all() method does not accept null anymore, and defaults to DayOfWeek::MONDAYMonth:
Monthis now an enum: constants JANUARY, FEBRUARY, etc. are now Month instances, not integers__toString() method is removed, use toString() instead (enums disallow magic methods)💩 Deprecations
DayOfWeek:
of() method is deprecated, use DayOfWeek::from() insteadDayOfWeek::monday() → DayOfWeek::MONDAYDayOfWeek::tuesday() → DayOfWeek::TUESDAYDayOfWeek::wednesday() → DayOfWeek::WEDNESDAYDayOfWeek::thursday() → DayOfWeek::THURSDAYDayOfWeek::friday() → DayOfWeek::FRIDAYDayOfWeek::saturday() → DayOfWeek::SATURDAYDayOfWeek::sunday() → DayOfWeek::SUNDAYgetValue() method is deprecated, use $dayOfWeek->value insteadis() method is deprecated, compare values with $dayOfWeek->value insteadisEqualTo() method is deprecated, use strict equality === between DayOfWeek instances instead.LocalDate:
getDay() is deprecated, use getDayOfMonth() insteadgetMonth() is deprecated, use getMonthValue() instead (getMonth() will be repurposed to return a Month instance in a future release)LocalDateTime:
getDay() is deprecated, use getDayOfMonth() insteadgetMonth() is deprecated, use getMonthValue() instead (getMonth() will be repurposed to return a Month instance in a future release)Month:
of() method is deprecated, use Month::from() insteadgetAll() method is deprecated, use Month::cases() insteadgetValue() method is deprecated, use $month->value insteadis() method is deprecated, compare values with $month->value insteadisEqualTo() method is deprecated, use strict equality === between Month instances insteadMonthDay:
getDay() is deprecated, use getDayOfMonth() insteadgetMonth() is deprecated, use getMonthValue() instead (getMonth() will be repurposed to return a Month instance in a future release)YearMonth:
getMonth() is deprecated, use getMonthValue() instead (getMonth() will be repurposed to return a Month instance in a future release)YearWeek:
atDay() method now accepts a DayOfWeek instance, passing an integer is deprecatedZonedDateTime:
getDay() is deprecated, use getDayOfMonth() insteadgetMonth() is deprecated, use getMonthValue() instead (getMonth() will be repurposed to return a Month instance in a future release)🐛 Bug fixes
Year::toISOString() / __toString() did not respect ISO 8601; years with less than 4 digits are now left-padded with zeros (#90)Thanks to [@andreaswolf](https://github.com/andreaswolf)!
🐛 Bug fixes
YearMonth::__toString() would return an invalid string for years < 1000 (#87)✨ New methods
Year::parse() and Year::from() (#86)YearWeek::parse() and YearWeek::from() (#86)toISOString() method: (#87)
DurationInstantIntervalLocalDateLocalDateRangeLocalDateTimeLocalTimeMonthDayPeriodYearYearMonthYearMonthRangeYearWeekZonedDateTimeThe toISOString() methods return the same result as __toString(), but are better suited for the nullsafe operator:
$date?->toISOString();
⚡️ Performance optimizations
__toString() methods got a small performance boost (#85)Thanks to [@gnutix](https://github.com/gnutix)!
✨ New methods
Thanks to [@solodkiy](https://github.com/solodkiy)!
⚡️ Performance optimizations
Local(Date|Time|DateTime) minOf()/maxOf() (#76)LocalDate::plusDays(1) is now much faster (#79)Thanks to [@gnutix](https://github.com/gnutix) and [@BastienClement](https://github.com/BastienClement)!
✨ New methods
ZonedDateTime::getDurationTo() (#71) ([@solodkiy](https://github.com/solodkiy))💥 Breaking changes
Deprecated Interval constructor is now private; please use Interval::of() instead
The following deprecated methods have been removed, please use the new names:
| Class Name | Old Method Name | New Method Name |
|---|---|---|
LocalDate |
fromDateTime() |
fromNativeDateTime() |
LocalDate |
toDateTime() |
toNativeDateTime() |
LocalDate |
toDateTimeImmutable() |
toNativeDateTimeImmutable() |
LocalDateRange |
toDatePeriod() |
toNativeDatePeriod() |
LocalDateTime |
fromDateTime() |
fromNativeDateTime() |
LocalDateTime |
toDateTime() |
toNativeDateTime() |
LocalDateTime |
toDateTimeImmutable() |
toNativeDateTimeImmutable() |
LocalTime |
fromDateTime() |
fromNativeDateTime() |
LocalTime |
toDateTime() |
toNativeDateTime() |
LocalTime |
toDateTimeImmutable() |
toNativeDateTimeImmutable() |
Period |
fromDateInterval() |
fromNativeDateInterval() |
Period |
toDateInterval() |
toNativeDateInterval() |
TimeZone |
fromDateTimeZone() |
fromNativeDateTimeZone() |
TimeZone |
toDateTimeZone() |
toNativeDateTimeZone() |
ZonedDateTime |
fromDateTime() |
fromNativeDateTime() |
ZonedDateTime |
toDateTime() |
toNativeDateTime() |
ZonedDateTime |
toDateTimeImmutable() |
toNativeDateTimeImmutable() |
🔧 Improvements
TimeZoneOffset::parse() return type has been narrowed to TimeZoneOffsetTimeZoneOffset has been added back (#60) (@jiripudil)🐛 Bug fixes
ZonedDateTime due to sub-minute timezone offsets (#44)✨ New methods
Duration::isGreaterThanOrEqualTo() (#50)Duration::isLessThanOrEqualTo() (#50)Interval::of() (#64)Interval::contains() (#64)Interval::intersectsWith() (#64)Interval::getIntersectionWith() (#64)Interval::isEqualTo() (#64)💩 Deprecations
Interval constructor is deprecated in favour of Interval::of() (#64)✨ New methods
LocalDateRange::toPeriod() (#51)Year::toLocalDateRange() (#46)YearMonth::toLocalDateRange() (#46)YearMonthRange::toLocalDateRange() (#46)YearWeek::toLocalDateRange() (#46)💩 Deprecations
The following methods have been deprecated in favour of new names (#47):
Period::fromDateInterval() → fromNativeDateInterval()Period::toDateInterval() → toNativeDateInterval()TimeZone::fromDateTimeZone() → fromNativeDateTimeZone()TimeZone::toDateTimeZone() → toNativeDateTimeZone()LocalTime::fromDateTime() → fromNativeDateTime()LocalTime::toDateTime() → toNativeDateTime()LocalTime::toDateTimeImmutable() → toNativeDateTimeImmutable()LocalDateRange::toDatePeriod() → toNativeDatePeriod()LocalDate::fromDateTime() → fromNativeDateTime()LocalDate::toDateTime() → toNativeDateTime()LocalDate::toDateTimeImmutable() → toNativeDateTimeImmutable()ZonedDateTime::fromDateTime() → fromNativeDateTime()ZonedDateTime::toDateTime() → toNativeDateTime()ZonedDateTime::toDateTimeImmutable() → toNativeDateTimeImmutable()LocalDateTime::fromDateTime() → fromNativeDateTime()LocalDateTime::toDateTime() → toNativeDateTime()LocalDateTime::toDateTimeImmutable() → toNativeDateTimeImmutable()💥 Breaking changes
TimeZoneOffset does not allow seconds anymore (#35):
TimeZoneOffset::of()'s $seconds parameter is removedTimeZoneOffset::ofTotalSeconds() now throws if the number of seconds is not a multiple of 60IsoParsers::timeZoneOffset() does not allow seconds in timezone offset anymore; this affects not only TimeZoneOffset:parse() but also ZonedDateTime::parse()🔧 Fix
TimeZoneRegion::parse() (#38) Thanks to @adrianguenter✨ New methods
Period::fromDateInterval() converts a native DateInterval object to Period✨ New methods
DayOfWeek::isWeekday()DayOfWeek::isWeekend()LocalDate::plusWeekdays()LocalDate::minusWeekDays()✨ New methods
LocalDateRange::withStart()LocalDateRange::withEnd()💥 Breaking changes
Brick\DateTime\DayOfWeek::monday() through sunday()Brick\DateTime\DayOfWeek::__toString()Brick\DateTime\Month::__toString()✨ New method
LocalDateRange::toDatePeriod() (#31) Thanks to @morrislaptop🔧 Fix
ext-json requirement in composer.json🐛 Bug fix
LocalDateTime::plusDuration() and LocalDateTime::minusDuration() could return the wrong day. (#25)
Thanks @JodyLognoul!
✨ New methods
LocalDateRange::intersectsWith()LocalDateRange::getIntersectionWith()Thanks @solodkiy!
💥 Breaking changes
final (#8)LocalDateRange::getStartDate() - use getStart() instead (#13)LocalDateRange::getEndDate() - use getEnd() instead (#13)Duration::ofMilliseconds() - use ofMillis() instead✨ New methods
LocalDateRange::getStart() - deprecates getStartDate()LocalDateRange::getEnd() - deprecates getEndDate()💩 Deprecations
LocalDateRange::getStartDate() is now deprecated and will be removed in 0.2.0.LocalDateRange::getEndDate() is now deprecated and will be removed in 0.2.0.This makes LocalDateRange consistent with YearMonthRange.
🛠 Improvement
The following classes now implement JsonSerializable (#19):
DayOfWeekDurationInstantIntervalLocalDateLocalDateRangeLocalDateTimeLocalTimeMonthMonthDayPeriodYearYearMonthYearMonthRangeYearWeekZonedDateTimeThanks to @kagmole!
New method: LocalDate::daysUntil()
This allows to get the number of days between two dates.
New methods to convert objects to native DateTimeImmutable objects:
LocalDate::toDateTimeImmutable()LocalTime::toDateTimeImmutable()LocalDateTime::toDateTimeImmutable()ZonedDateTime::toDateTimeImmutable()New methods to convert to native DateTime objects:
LocalDate::toDateTime()LocalTime::toDateTime()LocalDateTime::toDateTime()This makes these methods in line with their fromDateTime() counterparts.
Note: even though these classes represent partial date-time concepts, PHP merges all these concepts into a single DateTime class, so it is relevant to be able to easily export them as native PHP date-times, with sensible defaults.
New method:
ZonedDateTime::toDateTime() : converts the ZonedDateTime to a native DateTime object.
New factory method:
Duration::ofMilliseconds()New methods available to create objects from native DateTime or DateTimeImmutable objects:
LocalDate::fromDateTime()LocalTime::fromDateTime()LocalDateTime::fromDateTime()ZonedDateTime::fromDateTime()This release adds support for YearWeek.
Bug fix:
Duration::multipliedBy() could return an invalid Duration with negative nanosNew methods:
Instant::toDecimal() returns a decimal timestamp such as 123456789.123456FixedClock::move() allows to move the clock by a number of seconds and/or nanosNew clock implementation:
ScaleClock makes the time move at a given paceNew feature:
now() now use the clock returned by DefaultClock. By default, this clock is still SystemClock, but it can now be overridden in tests. DefaultClock offers the freeze(), travel() and scale() methods inspired by timecop.✨ New methods
Duration::toDays()Duration::toDaysPart()Duration::toHours()Duration::toHoursPart()Duration::toMinutes()Duration::toMinutesPart()Duration::toSeconds()Duration::toSecondsPart()Duration::toMillis()Duration::toMillisPart()Duration::toNanos()Duration::toNanosPart()Duration::ofNanos()See #15 for more information.
💩 Deprecations
Duration::ofMilliseconds() is now ofMillis(); ofMilliseconds() is now deprecated and will be removed in 0.2.0.New methods
LocalDateTime::isFuture()LocalDateTime::isPast()These methods return whether a local date-time is in the future or in the past, in a given time-zone.
New methods
Instant::withEpochSecond() returns a copy of the Instant with the epoch second alteredInstant::withNano() returns a copy of the Instant with the nano-of-second alteredNew class: YearMonthRange.
LocalDateRange::getIterator() is now type-hinted as LocalDate[] to allow static code analysis in IDEs.
ZonedDateTime::isPast() and isFuture() now accept an optional Clock parameter.
First beta release.
How can I help you explore Laravel packages today?