6

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?
Community
  • 1
  • 1
artragis
  • 3,677
  • 1
  • 18
  • 30
  • Probably irrelevant, but `date()` will only work until 2038 year. At that year, `date()` will probably be deprecated ;-) – Glavić Sep 27 '12 at 09:04
  • even if in 2038 64 bits system would be the standard? ANd if not, What is the problem with migrating unix timestamp specification from an int to a long int? – artragis Sep 27 '12 at 09:06
  • Indeed. Javascript even uses milliseconds from 1/1/1970 to measure time. My guess is that the unix timestamp is here to stay ^^ – Johan Sep 27 '12 at 09:14
  • milliseconds are on long int because it takes at least 10 bits more to provide this number for today date. – artragis Sep 27 '12 at 09:16
  • I'd go so far as to say it's whatever you feel most comfortable working with. Our PHP systems have to interop with .NET and so a timestamp isn't so useful when `DateTime` does everything and more through an easier and OOP-based interface. – Rudi Visser Sep 27 '12 at 10:59
  • Could you develop a bit more the interoperability issues please? If you want to post an answer it can be right too. – artragis Sep 27 '12 at 11:01
  • @artragis Done, but it's not so much an answer as personal preference IMO. – Rudi Visser Sep 27 '12 at 11:22

2 Answers2

4

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 a DATE or DATETIME type which cooperates with PHP's DateTime 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 use strtotime, then date 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 use DateTime 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.

Is the 2 more bytes of DateTime a loss in really simple use of the API (only displaying)

  • I do not believe so in any way. Especially with PHP scripts generally being such short running processes anyway.

Is it the time to give up unix_timestamp?

Yes :)

Wouldn't it be better to store a simple timestamp and then get the good local time?

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.

Rudi Visser
  • 21,350
  • 5
  • 71
  • 97
  • I like very much this answer. You follow my point of view in a sense. Apart from, perhaps, that you forgot the fact that DateTime::createFromFormat allows you to create a date from unixtimestamp (and you can also get a unixtimestamp from your DateTime object by format('u') or getTimestamp methods) – artragis Sep 27 '12 at 14:01
  • Of course. I think this problem too stems from the fact that PHP provides a million different ways to perform a single simple task. My main point was of using `DateTime` and it's native constructor to construct an instance straight from the ISO formatted date which you'd get back anyway. This way you're reading/writing straight from the instance. To read it from MySQL as a timestamp, you'd use `createFromFormat`, and then you'd also have to format it back out when you're writing it *to* the database aswell. Unnecessary overhead, IMO. – Rudi Visser Sep 27 '12 at 14:03
1

Not an exact answer to your question, but I would choose Timestamp over DateTime, because I BELIEVE working on an Integer value is much more cost effective (measuring CPU's processing time), rather processing DateTime values.

I feel much comfortable when I have Numbers on a Binary Machine, rather having Strings or Objects.

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 when Performance 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?

// it LOOKS Better
$date = new DateTime();
$date->setDate(1986, 3, 24);   // March 24, 1986
echo $date->format('Y-m-d');

// it WORKS Better
echo date("Y-m-d", mktime(0, 0, 0, 3, 24, 1986));    // March 24, 1986

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 that Works better, not Looks! :)

Mahdi
  • 9,247
  • 9
  • 53
  • 74
  • 1
    thanks for your answer. I would say I prefer the view "writting programs understandable by human" because everyone can write something "understandable by a computer". Moreover, sql queries result in a string so that means conversion each time you deal with date in a php script. And PHP is not known as a very cost effective language (same for Java or .NET) – artragis Sep 27 '12 at 10:16
  • @artragis hey, I've update the answer, regarding your comment. :) – Mahdi Sep 27 '12 at 10:29
  • 1
    upvoted your answer but not accepted it. My problem is that it is *really* a mess to deal with dates, periods and so on with only integer. Compute date intervals with only integers is reinventing the wheel but with less readability – artragis Sep 27 '12 at 10:30
  • @artragis thanks! I've updated again! I'm somehow agree with you, and I know that my answer is not the one that you've been looking for. :) – Mahdi Sep 27 '12 at 10:54
  • your comment is good but avoid completely the problem of database management. When you get your db result you get string. When you push datas inside your query you have strings etc. Using DateTime db format allows you (and it is the **write** way to do it) to deal with date interval and compute everything. So you wil always convert everything instead of keeping a format that means "I'm a date" in every place of your script. – artragis Sep 27 '12 at 11:00
  • I would still say that it's better to convert a `string` to an `integer`, do whatever needed on that and when you totally finished with that, then convert it back to a `string`, show it to the user or store it in the datebase, etc. For me it seems more right to do, but maybe I still couldn't understand your case. – Mahdi Sep 27 '12 at 11:09
  • The problem with "integer dates" is that you can hardly enforce constraints in the database. And checking for valid dates (think February 31st) is much more complex (if not nearly impossible) –  Sep 27 '12 at 11:09
  • @a_horse_with_no_name oh man, we do it always without any problem, how could you think it could be NEARLY IMPOSSIBLE? – Mahdi Sep 27 '12 at 11:11
  • @Mahdi: then show me a check constraint that will prevent putting an invalid integer date into the database. –  Sep 27 '12 at 11:13
  • @a_horse_with_no_name hey, I'm sorry I got your comment wrong. Honestly I never used constraints on a date(timestamp) column. I'll look to see how it could be done easy, but have no idea for that now. sorry again, I really got your thought wrong. – Mahdi Sep 27 '12 at 11:19
  • 2
    Well a date column will itself validate dates (in any sensible database, in MySQL you will need to activate strict mode though). What makes it even harder to validate integers in MySQL is, that it does not support check constraints. So there is hardly any (efficient) way to ensure the data integrity inside the database. –  Sep 27 '12 at 11:23