Skip to content
Mark Story edited this page Apr 10, 2022 · 2 revisions

Background

As we start thinking about what we want to do with CakePHP5 we also need to think about what we're going to do with Chronos. Most of the date & time libraries in Cake are based off of chronos. Over the years several shortcomings in the Chronos library have come up and fixing them requires breaking changes.

Mutable objects are harmful

Chronos started as a fork of carbon which was entirely mutable at the time. Mutable time objects often cause a variety of issues as side-effects accumulate. Using immutable objects avoids side-effects as mutations are explicit and easy to spot. Removing the mutable variants requires a breaking change.

Date is kind of broken

I think the goals behind Date were noble but by inheriting from PHP's DateTime we also inherited a lot of baggage. Instead I think we should break the inheritance chain. Date can continue to implement the ChronosInterface. By decorating a DateTime instance we don't have to do any of the hard date math and instead spend our time validating inputs and clamping range operations. We could also explore building Date from primitives and use ephemeral DateTime instances to do calculations.

There is no Time object

While we have a DateTime and Date variants we lack a 'time only' abstraction. A Time object would provide a better ORM value for TIME type columns. This class is another place we could use the approach suggested for fixing Date. This work could also be done in 2.x compatible releases which gives us the opportunity to get the interfaces we want to use in the future added to 2.x to improve ease of upgrading.

Another approach could be to introduce this class in 3.x as a net new ChronosInterface compatible object. This gives us more time to get the interface right as we can complete the entire solution and have room to adjust afterwards.

The traits are a bit of a mess

The number of methods on Chronos classes is staggering. I think we can rethink how we've structured things and make life better for us and users.

  • RelativeKeywordTrait Why is this a trait? Why isn't it just a bunch of functions?
  • ModifierTrait Contains several static methods that could be implemented separately.
  • FrozenTimeTrait This can be inlined, all times will be frozen.
  • FactoryTrait Many of these methods could be moved into a separate factory class.