views:

368

answers:

6

I read a mysql timestamp can only hold a value from 19700101000000 to sometime in the year 2037. I seriously doubt my app will be around then, well i'm sure it wont but any idea what will people use then for a timestamp, a text field?

Below is an example of how I currently insert a mysql record with a datetime mysql field and you can see I use now() in the PHP below, now I am re-coding my site and I am going to offer timezone support for showing correct times to users so I needd to save date and time as a UTC timestamp.

<?PHP
$sql = "INSERT INTO online_users 
    (user_id,
    online_id,
    ip,
    datetime,
    location,
    gender) 
    values ('$cache->userid,$unid,$LOCALIP,NOW(),$location,$g)";
executeQuery($sql);
?>

Based on my code above and my information above, how would I format this code to insert the time and date into UTC and should I use a timestamp field or a text field in MySQL? I will need to modify the time in my php when showing it often, for example on some posts I calculate the time that has passed since the mysql time (2 days and 4 hours and 34 seconds ago). I also need to use time to query for things like users in the past week to sign on. I am not asking how to do that stuff I just posted it to show what I will be using time for just in case that would help determine the best method I should be saving it as.

A: 

I would use the timestamp field for dates, since it will make sorting/filtering faster than it would be on a text field. In 26 years, you can check back with us to figure out what you need to do to get past Y2K37.

;-)

md5sum
+2  A: 

The best column for storing datetimes is a DATETIME. It simplifies your code and queries, as you don't have to convert back and forth to integer timestamps all the time, and MySQL handles all the date comparison logic for you.

You can use the MySQL UTC_DATE(), UTC_TIME() and UTC_TIMESTAMP() functions in place of NOW() to get the current UTC timestamps inside MySQL.

zombat
+1 for the additional relevant PHP functions.
md5sum
If you'd use a TIMESTAMP column, MySQL would automatically convert all dates to UTC, without the need of special UTC_* functions.
Tatu Ulmanen
Now I am really confused, I know you are a reliable source but I have read over and over that I should not be using DATETIME anymore if I would like to convert timezones. I do love how simple it is to do conversions with DATETIME but will date_default_timezone_set($_SESSION['time_zone']); stil convert properly, I was pretty sure that for date_default_timezone_set to do it's magic that I had to be using a UTC timestamp?
jasondavis
@jasondavis - There is no reason you can't use DATETIMEs. TIMESTAMP columns have a few special caveats - they are converted to UTC for storage, but they are also converted back to the system timezone when you SELECT them. TIMESTAMPS can only store a limited range of dates, and if you're not careful creating them, *they will automatically update when you update any part of a record*. Since you're going to be converting your dates into your user's time zones anyway, the auto-conversion of TIMESTAMPS have no benefit. You can just as easily store a hard UTC date.
zombat
@jason - See this thread as well: http://stackoverflow.com/questions/409286/datetime-vs-timestamp
zombat
thanks, I was also just looking over the facebook API documentation and they list most of the mysql tables in the FQL section of there development area, for example on a comments table they used this: int A Unix timestamp associated with the creation time of a comment. SO instead of any timestamp or datetime it appears they store it as an "integer". I then looked at other dates and times in other tables they have, for a birthdate which the timestamp would give an issue for some people they store it as a "string" and for something like profle update time they use "time" which I assume is a..
jasondavis
continued... I assume it is a timestamp for that. I will read up on the links you provided thanks
jasondavis
They might store it as an integer for disk reasons. Storing a timestamp as an integer saves you a few bytes of space, but it means that you can no longer compare the values directly in the database using date functions or comparisons. Facebook might do it because the way FQL is abstracted out, date comparisons aren't done directly by the user, and the data savings could be worth it. On the other hand, it might just be that it's the API that is simply returning an int rather than a date string. Hard to say. I wouldn't recommend using an INT field though, unless you had a really good reason.
zombat
ok thanks for the info!
jasondavis
A: 

If you need to support different timezones, the wisest choise for dates would be the TIMESTAMP column type, even though it only has a range up to 2038-01-19 03:14:07. That would still give you 28 years to think about how to fix that problem.

The benefit of using a TIMESTAMP column type is that all dates are saved as UTC and converted to the required timezone on request. This way you don't have to worry so much about timezones. It doesn't solve all your problems, though.

Tatu Ulmanen
TIMESTAMPS are saved as UTC, but SELECT statements pull them out as whatever timezone your system is set at. So unless you're setting your system time to UTC, you're not getting a UTC timestamp from the database. You're still going to have to convert it in PHP.
zombat
when you say my system time are you referring to where my server and mysql server are set to or to my system/pc at home? if you mean server, maybe it would be a good idea for me to set server to UTC since it's in a different timezone then I am anyways
jasondavis
The MySQL timezone used for conversion (including SELECT) can be set per connection http://stackoverflow.com/questions/409286/datetime-vs-timestamp/602038#602038 - therefore, you don't necessarily have to convert it on the PHP side.
micahwittman
A: 

You can also use ON UPDATE CURRENT_TIMESTAMP to update the field whenerevr the row is updated

Xian
thats good to know but for many of my tables that would have a bad affect when user edits stuff
jasondavis
+1  A: 

I tried everything mention in this question/answer but nothing worked correctly, in the end the only way I was able to get php timezones date_default_timezone_set() function to work correctly with my date and times from mysql was to store them as an integer and then it works perfect. There is no problem of slower sorting for me because I sort by ID number instead of date but to sort by a date I don't think would be too difficult once I figure out how many seconds are in between.

When I use an integer field in mysql, I can store a UTC timestamp as this 1262658989. When you use a timestamp or datetime field in mysql, it automaticly convert it to this style 2003-04-14 00:00:00 which then makes it much hard to work with timezones for some reason.

Using an interger instead I can get the UTC timestamp in PHP using this code:

gmdate('U', time())
jasondavis
NOTE: The MySQL UNIX_TIMESTAMP() function will return the actual integer value from a TIMESTAMP column, with no conversion. (That gives you the same result set, returning an INTEGER value from the database.) As you note, the issue you have to deal with using a TIMESTAMP (vs. INTEGER) datatype in the database is the implicit timezone conversions.
spencer7593
A: 

I have always stored epoch/unix time as a signed integer in database fields. MySQL has UNIX_TIMESTAMP() & FROM_UNIXTIME() functions. I have and will continue to receive flak for this, but the date maths are easy, the application language support for this date format is nearly ubiquitous and I can maintain operational systems (e.g. airline scheduling info) regardless of political whims about DST corrections without fear of system/runtime updates.

A few websites don't even bother to do date conversion and allow the client's JavaScript to project it in their local time.

The time deltas that you mention (i.e. how long between last view) can be facilitated with ease as you immediately have the number of elapsed seconds.

Xepoch