As I spend most of my time with php and mysql or pgsql, I will use DateTime as a generic word for the date API. In php there is no "Date", "Time", "DateTime" and "DateTimeOffset"
As I develop web application more and more elaborate, I use DateTime most of time, but sometimes I wonder if it is really what I want.
for example it happens that I just want to display the today's date (for example when I want to store a forum or blog post), there is no calculation, no filter to provide, no iteration to happen... So why do I use \DateTime
over the date()
function?
I saw this topic that provides some simple description of the pros of each technologies.
But it does not really answer to the question. Is it really a loss to throw up 2 more bytes in a DateTime object in PHP and other 2 bytes in my database as it allows me to use the DATE_INTERVAL
API (in php it is DateInterval
) and the IntlDateFormatter.
Moreover, this post says that unix_timestamp is reserved from 1970. But it is not logical and some tests prove it :
echo date('d/m/Y',time(-1));
echoes '31/12/1969' ! And it is logical. A 32 bits unsigned int goes from 0 to 4 294 967 295
and there are only almost 2 billions of seconds in 68 years, so the int is signed and "negative timestamp" must exist !
Another think that is really important to me, and that makes me chose DateTime every time is that I want to deal with dates, not with integers. DateTime is a date, timestamp is not ! The only sense that I found to timestamp was the time I wanted to time-mark a filename because in that cas timestamp is timestamp...
However, ther is still a problem : timezone handling. As MySQL and others does not handle timezone when storing dates as DateTime, for now, I use TimeZone integration as the escape part of "filter in escape out"
$toStoreDate = new \DateTime($_POST['date'],new DateTimeZone('UTC'));
$dao->exec('INSERT INTO mytable(mydate) VALUES (\''.$toStoreDate->format('Y-m-d h:i:s').'\')');
$toDisplayDate =new \DateTime( $dao->query('SELECT mydate FROM mytable')
->fetch(DAO::FETCH_ASSOC)['mydate']);
$toDisplayDate->setTimeZone(new DateTimeZone('myLocal'));
Is it the right way? Wouldn't it be better to store a simple timestamp and then get the good local time?
So, here is a summarise of the question :
- Is the 2 more bytes of DateTime a loss in really simple use of the API (only displaying)
- Is it the time to give up unix_timestamp?
- Wouldn't it be better to store a simple timestamp and then get the good local time?
Not an exact answer to your question, but I would choose
Timestamp
overDateTime
, because I BELIEVE working on anInteger
value is much more cost effective (measuring CPU's processing time), rather processingDateTime
values.I feel much comfortable when I have
Numbers
on aBinary Machine
, rather havingStrings
orObjects
.Human vs. Machine
In terms of Understandability, I'd say when I'm writing a program for a computer, I would consider that I'm making that for a
Machine
to work on that, however if an abstraction over that layer could help the humans to understand that better, why not we don't use that whenPerformance
is not an issue?I can't remember who said or where I heard that, but someone said something like
People hate Computers, but they should hate Programmers
, and I'm totally agree with that. So, as a human I still keep respect of that machine and will try to make programs which are more understandable for computers. :)Update:
To picture it better, imagine we have a program to deal with 'Dates', processing 10,000 times per minute, right?
Let say I've to look at this code for an hour per week, and let say there are 10,000 people that they should deal with that 24/7/365 and of course I'm not gonna handle that, it's a task for a machine.
By the way, I would say again that if
Performance
is not an issue, then why we don't make it more understandable for programmers? If we need to get the most out of that, then let programmers look at the code thatWorks
better, notLooks
! :)As said in a comment I believe this is mostly down to personal preference. In my eyes, the use of a Unix timestamp and "legacy" non-OOP interfaces is not the way to do it going forward in today's world, for instance, we don't (read: shouldn't be) using an
INT
datatype in our database to store dates in Unix Timestamp format, we should instead be using the database's native type which is usually aDATE
orDATETIME
type which cooperates with PHP'sDateTime
object (and other languages') almost natively when it comes to standard conversions.To elaborate a bit on what I mean by standard conversions: When you use MySQL and pull back a value to PHP you get a ISO-formatted date string, of which the
DateTime
class parses in it's constructor giving you an immediately usable object. In contrast, to go the Unix timestamp route you would have to usestrtotime
, thendate
to get it into whatever format you want natively.I mentioned before about interop between our PHP systems and .NET systems. Whilst there are no specific issues caused by using a timestamp it's simply not the practical solution, as again, we use a database that returns a DateTime value which can be sent straight down the pipe. If we were to convert this to a unix timestamp for use internally in PHP we'd also have to then convert it back out if we were to send a response, or send a response to the .NET Application (or should I just say API in this case) that is a timestamp, and convert it at the end. By using
DateTime
across the board, it alleviates the need for any conversions to happen whatsoever and the whole development process is easier.Finally to add to all of this, as you also mentioned in your post, you get to use shiny items such as
DateInterval
, easier timezoning, easier manipulation and easier formatting etc when you useDateTime
and it's related object-oriented partners in crime. It's just an easier development process in my eyes.I don't believe as I initially said that there is a "correct" answer to this, just more of a personal preference based on your own coding style, and the comments above reflect mine.
Yes :)
See comments above on database, it's not "native" to use a Unix Timestamp for this purpose IMO. You can just call
->getTimezone
and store this in the database, then use->setTimezone
when you pull it back out again.