How to calculate the interval between 2 unix timestamps in php WITHOUT dividing by 86400 (60*60*24)
Asked Answered
S

4

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

Simmon answered 20/9, 2010 at 13:3 Comment(8)
Why are you reluctant to use the obvious, simple division solution?Barbarous
@You: because it gives a wrong result?Kamila
@Michael: No, it doesn't. OP states that it works, but he "doesn't want to use that solution".Barbarous
@You: Rounding a wrong result to yield the expected one is not my definition of "works".Kamila
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.Ilmenite
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.Ilmenite
@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.Barbarous
@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!Simmon
U
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')
Underpay answered 20/9, 2010 at 13:54 Comment(1)
@Underpay 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).Gaza
K
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.

Kamila answered 20/9, 2010 at 13:29 Comment(4)
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???Simmon
@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()Kamila
@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?Kamila
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..Simmon
O
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.

Owlet answered 20/9, 2010 at 13:7 Comment(5)
In 5.3, new DateTime($t1)->diff(new DateTime($t2)) is easy and clear. But the OP asked for pre 5.3 a solution.Beutner
Which is why one should save timestamps in UTC.Barbarous
dude im using STRTOTIME to get these timestamps, isn't that UTCSimmon
STRTOTIME has nothing to do with timezones.Carpi
@mizipzor: strtotime has very much to do with timezones - it converts a human readable date to a timestamp, and it has to use a specific timezone to interpret the date.Kamila
P
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;
Paba answered 5/8, 2022 at 10:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.