tags:

views:

232

answers:

5

Hey everybody,

In my web application, I have users input a date in a simple textbox. That input (after being sanitized, of course), is run through strtotime(), and 86399 is added to it, to make that timestamp the end of the day written (11:59:59). This is for due date purposes (so if the date passes, the application raises a flag)

For the days I tested, it worked...

January 5th saved as january 5th, at the end of the day.

March 13th saved as March 13th

March 15th saved as March 15th

March 14th, for whatever reason, saved itself as March 15th.

Is March 14th mysteriously a couple seconds short or something??


Update: Thanks to oezi for the solution - worked like a charm. Code as requested:

Old code:

if ($_POST['dateto'] != '') {
    $dateto = strtotime(mysql_real_escape_string($_POST['dateto'])) + 86399;
}

New code:

# Offset to "end of day"
list($y,$m,$d) = explode('-',date("Y-m-d",strtotime($_POST['dateto'])));
$d++;
$dateto = strtotime($y . '-' . $m . '-' . $d) - 1;
+17  A: 

March 14, 2010 is the day Daylight Saving Time begins in the United States. So if you're doing math in the local time zone, March 14 is only 23 hours long.

Daniel Pryden
Thanks for the heads-up... it's not mission-critical, so I suppose this bug in my code can sod off for now ;)
Julian H. Lam
A: 

http://tycho.usno.navy.mil/leapsec.html

Not all days are 86400 seconds long.

This is a rare event. And (historically) never scheduled in March.

S.Lott
According to Wikipedia, leap seconds are "typically scheduled either at the end of June 30 or December 31 (though leap seconds can be applied at the end of any month)". Source: http://en.wikipedia.org/wiki/Leap_second
Daniel Pryden
True, but it should be noted that the POSIX time-related library functions (mktime, gmtime, etc.) are required to disregard leap seconds -- so the time_t values for 23:59:59 and 00:00:00 the next day will always differ by exactly 1 second, even if there was an intervening leap second at 23:59:60. (Shakes fist...)
Jim Lewis
Besides, most computing systems doesn't take leap seconds in consideration
Pablo Cabrera
This is actually what I'd thought at first... so I tried subtracting a second to compensate, with the same result... and as noted above, unix timestamps don't take leap seconds into account. Good guess, though.
Julian H. Lam
+3  A: 

I would assume because this is the beginning of daylight savings time

rerun
Please sir, may I save a little more daylight?
Michael Myers
Very Good I can't spell at all and yes i am a native English speaker
rerun
+2  A: 

Like others said, this is because of daylight saving time. To solve this problem, you could do this:

<?php
list($y,$m,$d) = explode('-',date("Y-m-d",strtotime($date_from_user)));
$h = 23;
$i = 59;
$s = 59;
$mytimestamp = "$y-$m-$d $h:$i:$s";
?>
oezi
+1  A: 

What database are you using? there has to be a better way to do this (most date manipulation commands are database specific). In SQL Server, I'd just add 1 day to the date and then subtract 1 second:

DECLARE @YourDate datetime
SET @YourDate='2010-03-14'

SELECT DATEADD(ss,-1,@YourDate+1)

OUTPUT:

-----------------------
2010-03-14 23:59:59.000

(1 row(s) affected)

for what it is worth, I'd much prefer to have a condition: < NextDay than <=CurrentDay12_59_59

KM
I'm storing the dates as a unix timestamp in the database, which is a ten-digit integer... I suppose it would probably be better to use the datetime type, but what's done is done...Interesting point about date+1-1second... I'll look into it.
Julian H. Lam