In programming, we are always working with abstractions and representations:
- The text string
2021-02-09 12:47:14 UTC is a representation of a particular point in time.
- The integer
1612874834 is a different representation of that same point in time.
- Both of those will ultimately be represented in binary form; a text string and a written numeral are already abstractions that saves us thinking about that fact.
We can convert between those and many other representations relatively easily, but we also want to be able to perform operations on them: take input, display output, sort dates, find the number of days between two dates, etc.
For those, we want to use appropriate abstractions - we don't want to code a bunch of binary logic for every operation, we want to build up readable code.
- For user input and output, the abstraction of "a date is a text string that matches some pattern" is a useful one.
- However, there may be many such patterns, depending on the context - a user in the USA will want to see and enter dates in "month / day / year" format, users elsewhere in the world will want "day / month / year". So we immediately need a neutral abstraction which represents the date rather than just storing the user's input directly.
- For finding the number of days between two dates, we want a higher-level abstraction that is not about what the date looks like but what it represents.
Using the wrong abstraction for the job leads to unnecessarily complex code. It can also lead to bugs, e.g. if you pass all your dates around as strings, and accidentally pass in something incorrectly formatted, you'll probably get "garbage in, garbage out" rather than a clear error.
So, wherever possible, you should represent everything with higher-level abstractions. With date-time values, that means
DateTimeImmutable objects in PHP, and
DateTime columns in MySQL.
There is one unfortunate hurdle: when sending data to or from the database, you need it to be in a representation that both sides understand. Most database drivers use a "lowest-common denominator" approach, where that representation is a text string. As soon as you have that string from the database, though, you can and should convert it to PHP's
DateTimeImmutable type, so you have the best abstraction for working with it.