1 00:00:00,250 --> 00:00:03,230 Time zones can be a very difficult aspect of web development to understand. 2 00:00:03,230 --> 00:00:06,160 There are different time zones all over the world and 3 00:00:06,160 --> 00:00:09,290 most of these time zones are not as logical as you would hope. 4 00:00:09,290 --> 00:00:11,090 Every country has a different time and 5 00:00:11,090 --> 00:00:14,050 you want to make sure that you're showing the user in that country the right time. 6 00:00:14,050 --> 00:00:17,250 There are some tricky caveats. 7 00:00:17,250 --> 00:00:20,190 Not all time zones are exactly one hour plus or minus UTC. 8 00:00:20,190 --> 00:00:22,840 So storing a plus or minus integer doesn't work. 9 00:00:22,840 --> 00:00:25,500 Not all time zones have daylight savings time. 10 00:00:25,500 --> 00:00:28,110 Political events can cause time zones to change their off set. 11 00:00:29,170 --> 00:00:33,550 Many developers approach this by always storing dates in their database’s UTC. 12 00:00:33,550 --> 00:00:39,290 Any date going in is converted to UTC on input, and back from UTC on display. 13 00:00:39,290 --> 00:00:42,660 To calculate times and offsets, many developers store plus 1 or 14 00:00:42,660 --> 00:00:46,650 minus 4 as an offset and put that in their database as an integer. 15 00:00:46,650 --> 00:00:49,090 This means that if the country's offset is minus four and 16 00:00:49,090 --> 00:00:52,360 a half hours, then the numeric representation is minus 4.5. 17 00:00:52,360 --> 00:00:57,340 This is a decimal, and if you try to put decimal numbers into an integer field, 18 00:00:57,340 --> 00:01:00,810 it'll be truncated by MySQL and only the value 4 will be saved. 19 00:01:02,290 --> 00:01:05,480 Even storing a decimal number would not help if DST or 20 00:01:05,480 --> 00:01:07,720 time zone change came into effect. 21 00:01:07,720 --> 00:01:11,000 The time being displayed to the user would still be wrong by as much as an hour. 22 00:01:12,850 --> 00:01:15,580 The more robust way to work with dates and times in PHP, 23 00:01:15,580 --> 00:01:19,420 is to store the actual time zone in the database and not just the offset. 24 00:01:19,420 --> 00:01:24,190 PHP uses IANA time zones which are an internationally recognized body in 25 00:01:24,190 --> 00:01:26,980 charge of handling mapping of these times zones and keeping them up to date. 26 00:01:28,360 --> 00:01:30,240 Let's take a look at some code. 27 00:01:30,240 --> 00:01:33,660 First this might look like a lot of code, but when broken down it's pretty simple. 28 00:01:33,660 --> 00:01:37,990 On line 3 we have a new date/time object just as before, using a supported format. 29 00:01:37,990 --> 00:01:41,310 We've also specified the second argument of the date time class which is 30 00:01:41,310 --> 00:01:43,370 an instance of date time zone. 31 00:01:43,370 --> 00:01:45,810 This accepts a string with a name of a time zone, and 32 00:01:45,810 --> 00:01:47,620 UTC is the one we want here. 33 00:01:47,620 --> 00:01:50,970 Next we clone that date so we can keep a copy of the original. 34 00:01:50,970 --> 00:01:53,740 We do this because date time is a mutable class. 35 00:01:53,740 --> 00:01:57,280 That means the object will change state when we run methods like set time zone. 36 00:01:57,280 --> 00:02:00,190 So that we can keep a copy we have to fully clone the object. 37 00:02:00,190 --> 00:02:02,298 Then work with a brand new version. 38 00:02:02,298 --> 00:02:03,250 On line 7, 39 00:02:03,250 --> 00:02:08,400 we now use the set time zone method on our new copy of the UTC date/time instance. 40 00:02:08,400 --> 00:02:12,900 And the string American New York is a supported IANA time zone name. 41 00:02:12,900 --> 00:02:16,692 This will update the local date/time object to have a new time zone and 42 00:02:16,692 --> 00:02:17,918 therefore a new time. 43 00:02:17,918 --> 00:02:21,564 Finally, at the bottom of the script, we’re outputting two 44 00:02:21,564 --> 00:02:26,137 paragraphs with the date and time for UTC and another for the time in New York. 45 00:02:26,137 --> 00:02:27,450 Let’s have a look at that in the preview. 46 00:02:30,290 --> 00:02:32,440 Great, it looks like that worked. 47 00:02:32,440 --> 00:02:37,010 1314 in UTC is now showing 0914 in New York, which is exactly right. 48 00:02:37,010 --> 00:02:39,730 All dates should be stored as UTC in the database. 49 00:02:39,730 --> 00:02:42,590 The date should always be displayed to the user in their own time zone. 50 00:02:42,590 --> 00:02:43,890 This sounds complicated. 51 00:02:43,890 --> 00:02:46,890 But it simply means you need to convert from UTC to the local time zone 52 00:02:46,890 --> 00:02:47,510 for output. 53 00:02:47,510 --> 00:02:50,600 Then convert from the local time zone to UTC on input. 54 00:02:50,600 --> 00:02:53,520 Let's get back to our workspace and see what that code might look like. 55 00:02:53,520 --> 00:02:55,570 This is basically the same piece of code we had before. 56 00:02:55,570 --> 00:02:56,780 We just swapped things around. 57 00:02:56,780 --> 00:03:00,590 Now it's worth noting that you'll probably take your input from a superglobal such 58 00:03:00,590 --> 00:03:01,890 as a post variable. 59 00:03:01,890 --> 00:03:05,920 But, for the sake of simplicity, we're going to use just a raw variable here. 60 00:03:05,920 --> 00:03:08,624 Now, the rest of this is pretty much the same. 61 00:03:08,624 --> 00:03:13,050 We're creating a local date/time from the American New York timezone. 62 00:03:13,050 --> 00:03:15,870 We're cloning that to make a UTC date time object, and 63 00:03:15,870 --> 00:03:19,620 then we're setting the time zone of that to UTC. 64 00:03:19,620 --> 00:03:22,140 So now if we run this, it should look exactly the same as before. 65 00:03:24,810 --> 00:03:26,930 Perfect. We've still got 13 o'clock and 66 00:03:26,930 --> 00:03:29,190 we have nine o'clock right there. 67 00:03:29,190 --> 00:03:32,070 By storing the time zone name itself the various offsets for 68 00:03:32,070 --> 00:03:35,130 day light savings time or [UNKNOWN] changes are handled for you. 69 00:03:35,130 --> 00:03:39,200 All you then need to do is store all dates in UTC and update the one output. 70 00:03:39,200 --> 00:03:43,020 So, just remember, all dates are stored in a database as UTC. 71 00:03:43,020 --> 00:03:45,920 All users should have a time zone attached to their own account. 72 00:03:45,920 --> 00:03:51,080 That time zone should be a valid IANA name, and whenever you output dates, 73 00:03:51,080 --> 00:03:54,210 you need to set the time zone of that date to match the user's time zone. 74 00:03:54,210 --> 00:03:56,740 Let's try a few questions on UTC and time zones.