4

I have 2 unix timestamps, I'm in AsiaPacific/Auckland timezone (GMT+12, DaylightSavings = GMT+13)

I want to calculate the number of days interval between 2 timestamps, where one is inside daylight savings time and one is not.

My example dates are:

7 Feb 2009 (1233925200) to 21 September 2010 (1284985360) (not including 21st) see here it says 591 days: http://www.timeanddate.com/date/durationresult.html?d1=7&m1=2&y1=2009&d2=21&m2=9&y2=2010

Let's calculate, here are my timestamps (both are based on Auckland 00:00 time)

1284985360-1233925200 = 51060160
51060160 / 86400 = 590.974

So yea I need 591. I don't want to use the "round up" solution

Is there any reliable method like strtotime, but for calculating date intervals, preferably that don't need php 5.3+ minimum

EDIT: need to clarify, I'm using STRTOTIME to get these timestamps, I thought that was UTC

EDIT2: I believe I have found the issue. While my end date was 21 September, I was actually using time() to get my end date, and time() was returning the wrong timestamp, perhaps it doesn't account for the GMT+12, regardless I switched time() to strtotime(date('d M Y')) and it returned the correct timestamp! eureka 591 days

Cœur
  • 37,241
  • 25
  • 195
  • 267
samsong
  • 113
  • 1
  • 7
  • Why are you reluctant to use the obvious, simple division solution? – You Sep 20 '10 at 13:06
  • 1
    @You: because it gives a wrong result? – Michael Borgwardt Sep 20 '10 at 13:09
  • @Michael: No, it doesn't. OP states that it works, but he "doesn't want to use that solution". – You Sep 20 '10 at 13:12
  • 1
    @You: Rounding a wrong result to yield the expected one is not my definition of "works". – Michael Borgwardt Sep 20 '10 at 13:31
  • 1
    THere's something wrong with these timestamps. On my system `(strtotime('2010-09-21')-strtotime('2009-02-07'))/86400 == 591`. Remember that Unix timestamp is supposed to be in GMT timezone. – Mchl Sep 20 '10 at 13:42
  • 1
    `date('Y-m-d H:i:s',1284985360) == '2010-09-20 12:22:40'` and `date('Y-m-d H:i:s',1233925200) == '2009-02-06 13:00:00'` so it's understandable you need to round the result. – Mchl Sep 20 '10 at 13:44
  • @Michael: Using UTC times, it will work. Using other timezones (e.g. DST ones) will yield a predictable error, fixed by rounding up. The method works, since it returns the correct answer given correct input. – You Sep 20 '10 at 14:49
  • @Michl you were right I think! After "something is wrong with these timestamps" I tested my timestamps out I copy pasted your strtotime & compared them to the start / end dates my php app was using, and yes indeed the END date was different So I checked how I was retrieving the end date, & I found that when an end date is not specified in my database, I was using time() to generate it.. time() it seems does not give the correct timestamp with regards to timezone difference, so I tried: strtotime(date('d M Y')) and it worked! – samsong Sep 21 '10 at 01:08

4 Answers4

4

Calculate the number of full days for both timestamps before calculating the difference:

floor(1284985360 / 86400) - floor(1233925200 / 86400)

The your result is always an integer.

And since you’re using strtotime to get these timestamps, specify the time 00:00:00+0000 to always get a multiple of 86400:

strtotime($str.' 00:00:00+0000')
Gumbo
  • 643,351
  • 109
  • 780
  • 844
  • 1
    @Gumbo You sir, are a genius. This is finally the way to make the "Days between" calculation using unix timestamps, without the `DateTime` class (for those of us without PHP5.3). – Shackrock Mar 08 '13 at 22:05
2

A correct Unix (POSIX) timestamp is in UTC, so you're starting out with values that are already wrong. You're facing an uphill battle, since APIs will generally assume that timestamps are in UTC. It would be best to fix this, after which the simple division would actually give the correct result.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • i have no idea if its UTC, im just runing STRTOTIME, so if you're saying strtotime generates a GMT instead of UNIX (POSIX) then yea guess i'm screwed. you seem knowledgable, i assume you're sayin there's no reliable way other than the 5.3+ methods??? – samsong Sep 20 '10 at 13:35
  • @fatjoze: To be exact, it's wrong to say that strtotime generates a timestamp in a specific timezone. It always generates UTC, the question is what timezone it uses to interpret the human-readable date parameter. And it looks like that's incorrect in your case because the timestamps you list do not correspond to 00:00 in either UTC or Auckland time. You can set the default timezone via date_default_timezone_set() – Michael Borgwardt Sep 20 '10 at 13:54
  • @fatjoze: At second glance, your timestamps seem to correspond to 00:00 in Sydney - is it possible that that's where your servers are and what they're configured to use as default timezone? – Michael Borgwardt Sep 20 '10 at 13:57
  • thank you very very much Michael, very knowledgeable support, my timestamps SHOULD be Auckland New Zealand, i have used set_default_date_timezone (forgot the actual name) to set my timezone accordingly, so yea not sure why its showing sydney time. Do you live in sydney? lol. none the less I followed Gumbos solution to divide both numbers by 86400 then floor each, THEN subtract. It appears to work so far.. – samsong Sep 20 '10 at 14:58
0

Dividing by 86400 is reliable and easy. I don't know any special functions and i don't see a reason for them to exist.

Māris Kiseļovs
  • 16,957
  • 5
  • 41
  • 48
0

One should use the DateTime library instead:

date_default_timezone_set('NZ');

$dateStart = DateTime::createFromFormat('U', '1233925200');
$dateEnd   = DateTime::createFromFormat('U', '1284985360');

$diff = $dateEnd->diff($dateStart);

Remember: the day is not (always) 86400 seconds long.

echo $diff->days;
Mike Doe
  • 16,349
  • 11
  • 65
  • 88