KBD

Keith Devens .com

Friday, July 4, 2008 Flag waving
I think I was basically a victim of what I like to call 'dumb people' -- people who are never going... – Joss Whedon (on the cancellation of Firefly)
← 'Show' function for debugging in PHPPowerpuff girls e-mail address? →

Daily link icon Thursday, July 15, 2004

Storing times in MySQL

Starting principle: Because MySQL doesn't support time-zones in its time formats, you should never only store time/date data in a timezone other than GMT (UTC). If you do, you actually lose information about what time it really was.

There are a few options for storing dates and times in MySQL while respecting time zones:

  1. You can store the GMT time and an offset from it in seconds to represent the time zone.
    1. The date/time being MySQL's "datetime" type, and the timezone offset in "seconds from GMT". This takes 8 bytes for the datetime type and 3 bytes for the mediumint you'll need to be able to store all possible timezone offsets. Unfortunately, it just misses being able to be stored in a smallint (smallint range is -32768 to 32767, but time offsets from GMT can be ±43200 (there are 86400 seconds in a day)). (11 bytes total per row)
    2. You can store the date/time using normal unix timestamps. This should be fine for most things, and takes 4 bytes for the int to represent the time and 3 bytes for the mediumint timezone offset. (7 bytes total per row)
  2. You can store both the localtime and GMT time:
    1. Each one being a MySQL datetime (16 bytes total per row) (WordPress does this, incidentally)
    2. Each one being a unix timestamp (8 bytes total per row)

I mentioned the total size requirements not because that's a very important issue but just because it's something worth keeping track of. What's most significant in the choice is what type of burden you put on your application by what you choose.

If you need to store "normal" dates (where "normal" means "in between 1901 and 2038") I think my preferred solution is option 1B. By storing the date in GMT and storing the offset in seconds you're going to need to do some date math anyway, so it's better to just have everything in the DB be in the same "units". Your application will then have to take care of all your date logic, but that seems better than having some in your DB and some in your code and having to constantly convert between timestamps and MySQL's datetime format.

However, I'm honestly not sure if that's feasible. For instance, I use some of MySQL's date math in my code, and it's not immediately obvious to me how I'd replace it. For instance, if you want to get rows grouped by the day, how would you do this in MySQL if you were using unix timestamps? Ultimately, what WordPress goes for might be the simplest and best, though it feels like duplication of data to me.

Update (Jul 28, '04): See this update for my conclusions and recommendations.

← 'Show' function for debugging in PHPPowerpuff girls e-mail address? →

Comments XML gif

jason wrote:

I wouldn't bother storing the timezone unless there was a good reason. Store the UTC time, and then apply the timezone of the user viewing the dates/times.

If you wrote something at 3pm localtime, do I care. If I am 3hours ahead it might be nicer to see that you wrote it at 6pm my localtime. If I was comparing lots of different events by people in different timezones, having things in my local timezone would be nicer than seeing what time each individual did things in their timezone.

∴ jason | 15-Jul-2004 6:40pm est | #5011

Keith (http://keithdevens.com/) wrote:

Well, here's one reason. I'd like to know what time things were done in my localtime. Given daylight savings time, if I only store GMT, I won't really know what time, localtime, things were done unless I also check to see if DST was in effect in code.

Another example is that if I move to a different time zone I'd like to have my new blog times change to my new localtime but leave the old ones the same.

One of the things that's kind of freaking me out is this: my permalinks are based on my localtime posting. The official date for this post is July 15 and that's the date in the permalink. If I was in Sri Lanka (or wherever), my post might have been on July 16th. What if it's May 1 here and I travel to a different time zone and post something on April 30 (their) localtime? It makes me want to organize my weblog only according to GMT to avoid stuff like that, but then it won't reflect what time I'm actually living in.

Being able to treat MySQL dates as dates and storing them in datetime format like WordPress does is looking more and more attractive.

Keith | 15-Jul-2004 7:42pm est | http://keithdevens.com/ | #5020

Keith (http://keithdevens.com/) wrote:

Here's someone else thinking along these lines:
http://www.gyford.com/phil/writing/2003/08/21/movable_type_tim.php

Daylight savings time is another, smaller, issue.

Keith | 15-Jul-2004 7:55pm est | http://keithdevens.com/ | #5021

Keith (http://keithdevens.com/) wrote:

Here's a neat post that seems worth mentioning.

Keith | 15-Jul-2004 9:23pm est | http://keithdevens.com/ | #5024

Matt (http://photomatt.net/) wrote:

We struggled with this quite a bit and had a couple of failed attempts before we came up with the current method in WP. I'm pretty happy with the robustness of the data and the way it makes it easy to work with things. However our reliance on the MySQL date functions makes the WordPress application very hard to port to other databases.

∴ Matt | 18-Jul-2004 6:37pm est | http://photomatt.net/ | #5028

Keith (http://keithdevens.com/) wrote:

Thanks Matt. I'm most likely going to follow your lead here. I probably wouldn't have thought of doing it that way if I hadn't seen WordPress do it first. Incidentally, when I was writing this post I looked back on your reply to the e-mail I sent you asking about this. Thanks for all the insight.

And, portability is much more of a concern for you with WP because it's software that other people use. My software's just for me so I have the luxury of not worrying about hassles like portability if I don't want to. Smiley

Keith | 18-Jul-2004 11:08pm est | http://keithdevens.com/ | #5029

Keith (http://keithdevens.com/) wrote:

It appears Dunstan has used the same scheme in the new version of his weblog (search for "Post times").

Keith | 19-Jul-2004 10:11am est | http://keithdevens.com/ | #5032

161.142.148.211 wrote:

I'm hosting mysql outside of my country and my question how do I store date into database for current date + date into the database but using my country current time, and my country localtime is GMT+8

∴ 161.142.148.211 | 4-Feb-2005 4:47am est | #6964

Feel free to post a comment below. Please see my comment policy.

Formatting Rules (No HTML):

  • **bold**, *italic*, _underlined_, --strikeout--
  • "text"="url" creates a link, and URLs are auto-highlighted
  • Blockquote: Like e-mail, begin paragraph with > (greater-than sign)
  • Lists: begin paragraph with *,-, or + (unordered), or # (ordered)
  • Code block: ?!code:language=perl|php|sql|javascript|etc.{\n}...{\n}?!/code

:
(will be your IP address if blank)
: (optional)
(Will not be shown on site)

: (optional)
:

July 2008
SunMonTueWedThuFriSat
 12345
6789101112
13141516171819
20212223242526
2728293031 



RSS feed RSS feed for Keith's Weblog
Atom feed Atom feed for Keith's Weblog
Weblog archive
Recent comments
  on 5 posts

Recent comments XML

Girls, please don't get breast implants

> And no, you will not be receiving​a picture.

:-(...

Keith: Jul 2, 6:05am

Javascript clone function

This is a clever way to clone an​object if you are using YAHOO UI.​Same tec...

Antonio: Jul 1, 12:47pm

I hate Norton Antivirus

Oh just one other thing norton is​great at keeping people out of your​compu...

kevin.sands: Jul 1, 12:50am

Terminator 3 was awful

I think the biggest reason why T3​totally blew was because Edward​Furlong g...

76.167.172.64: Jun 29, 3:06am

Generated in about 0.122s.

(Used 8 db queries)

mobile phone