CHAPTER 9 – DATE HANDLING – ISO 8601 Week Numbers
This example shows that the ISO 8601 year format option (%V) might differ from the normal year format option (%Y) if a year has less than four days: <?php for ($i = 27; $i <= 31; $i++) { echo gmstrftime( "%Y-%m-%d (%V %G, %A)n", gmmktime(0, 0, 0, 12, $i, 2004) ); } for ($i = 1; $i <= 6; $i++) { echo gmstrftime( "%Y-%m-%d (%V %G, %A)n", gmmktime(0, 0, 0, 1, $i, 2005) ); } ?> The script outputs 2004-12-27 (53 2004, Monday) 2004-12-28 (53 2004, Tuesday) 2004-12-29 (53 2004, Wednesday) 2004-12-30 (53 2004, Thursday) 2004-12-31 (53 2004, Friday) 2005-01-01 (53 2004, Saturday) 2005-01-02 (53 2004, Sunday) 2005-01-03 (01 2005, Monday) 2005-01-04 (01 2005, Tuesday) 2005-01-05 (01 2005, Wednesday) 2005-01-06 (01 2005, Thursday) As you can see, the ISO year is different for January 1 and 2, 2005, because the first week (Monday to Sunday) only has two days.
Example 2: DST Issues Every year around October, at least 1025 bugs are reported when a day is listed twice in somebody's overview. Actually, the day listed twice is the date on which DST ends, as you can see in this example: <?php /* Start date for the loop is October 31th, 2004 */ $ts = mktime(0, 0, 0, 10, 31, 2004);
/* We loop for 4 days */ for ($i = 0; $i < 4; $i++) { echo date ("Y-m-d (H:i:s)n", $ts); $ts += (24 * 60 * 60); /* 24 hours */ } ?> When this script is run, you see the following output: 2004-10-31 (00:00:00) 2004-10-31 (23:00:00) 2004-11-01 (23:00:00) 2004-11-02 (23:00:00) The 31st is listed twice because there are actually 25 hours between mid- night, October 31 and November 1, not the 24 hours that were added in our loop. You can solve the problem in one of two ways. If you pick a different time of day, such as noon, the script will always have the correct date: <?php /* Start date for the loop is October 29th, 2004 */ $ts = mktime(12, 0, 0, 10, 29, 2004);
/* We loop for 4 days */ for ($i = 0; $i < 4; $i++) { echo date ("Y-m-d (H:i:s)n", $ts); $ts += (24 * 60 * 60); } ?> Its output is 2004-10-29 (12:00:00) 2004-10-30 (12:00:00) 2004-10-31 (11:00:00) 2004-11-01 (11:00:00) However, there is still a difference in the time. A better solution is to abuse the mktime() function a little: <?php /* We loop for 6 days */ for ($i = 0; $i < 6; $i++) { $ts = mktime(0, 0, 0, 10, 30 + $i, 2004); echo date ("Y-m-d (H:i:s) Tn", $ts); } ?> Its output is 2004-10-30 (00:00:00) CEST 2004-10-31 (00:00:00) CEST 2004-11-01 (00:00:00) CET 2004-11-02 (00:00:00) CET 2004-11-03 (00:00:00) CET 2004-11-04 (00:00:00) CET We add the day offset to the mktime() parameter that describes the day of month. mktime() then correctly wraps into the next months and years and takes care of the DST hours, as you can see in the previous output.