1

I know there a lot of questions and answers of this already, but unfortunately I think my situation may be unique? For some reason, the time-change seems to be making the day calculate as one day less than it should be calculating.

Here is my PHP that I was using and it was working great, until it started to overlap a start and end date that was BEFORE daylight savings, and AFTER daylight savings, respectively (FYI, this is a recent issue, since daylight savings time starts this weekend!):

//$lastDate and $firstDate are 2 unix timestamps with valid month, day, and year values.
//The times are irrelevant at this point, they are only meant to represent a day.

//I start by making sure these have the same time values.
$lastDate = mktime(23, 59, 59, date("m", $lastDate), date("j", $lastDate), date("Y", $lastDate));
$firstDate = mktime(23, 59, 59, date("m", $firstDate), date("j", $firstDate), date("Y", $firstDate));

//Then calculate the total number of days in between.
$totalDays = abs(floor(($firstDate - $lastDate)/(60*60*24)));

So again, to be clear, the above works if i'm not overlapping the daylight savings time change...

For reference:

How to find the dates between two specified date?

Actual days between two unix timestamps in PHP

Finding days between 2 unix timestamps in php

And, I'm still on PHP 5.2 right now.

EDIT/UPDATE:
I've found the following on this links:

How to find the dates between two specified date?

and

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

//$lastDate and $firstDate are 2 unix timestamps with valid month, day, and year values.
//The times are irrelevant at this point, they are only meant to represent a day.

//I start by making sure these have the same time values.
$lastDate = mktime(10, 00, 00, date("m", $lastDate), date("j", $lastDate), date("Y", $lastDate));
$firstDate = mktime(10, 00, 00, date("m", $firstDate), date("j", $firstDate), date("Y", $firstDate));

//Then calculate the total number of days in between. 
$totalDays = floor($firstDate / 86400) - floor($lastDate/ 86400);

And it seems to work right now for the crossover of DST. Anyone see any issues with this?

Community
  • 1
  • 1
Shackrock
  • 4,601
  • 10
  • 48
  • 74
  • http://stackoverflow.com/questions/2674918/is-mktime-using-date-daylight-saving-aware I would use new [dateTime](http://php.net/manual/en/class.datetime.php) and get off 5.2 when you can. Otherwise be sure to see `is_dst` argument of `mktime`. – ficuscr Mar 08 '13 at 20:13
  • @ficuscr hmmm, so DateTime is in 5.2 afterall, for some reason I thought it was only in 5.3. – Shackrock Mar 08 '13 at 20:16
  • A number of [fixes and improvements](http://php.net/ChangeLog-5.php) came in 5.3 I think. `DateInterval ` class for example. But it is there. – ficuscr Mar 08 '13 at 20:17
  • @ficuscr do i need to set the timezone/object on every page load, i.e. i could do this at the same place i'm calling session_start on all these pages? – Shackrock Mar 08 '13 at 20:25
  • @ficuscr ok so this isn't working out well for me =). is_dst is depreciated as of 5.1. I can't use the DateTime class because the diff function isn't available in 5.2. Any ideas here? – Shackrock Mar 08 '13 at 21:38
  • @ficuscr I added an update, check that one out. – Shackrock Mar 08 '13 at 22:08

1 Answers1

2

Are you running on PHP 5.3+? A DateInterval fits the problem nicely.
http://www.php.net/manual/en/datetime.diff.php

<?php
$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-13');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%R%a days');
landons
  • 9,502
  • 3
  • 33
  • 46
  • Here's the question... I have unix timestamps to start with. Can I use the timestamps as the argument to DateTime, i.e. `DateTime($timeStamp1)`? – Shackrock Mar 08 '13 at 20:26
  • @Shackrock Yes, using `DateTime('@' . $timestamp)` (notice the @ sign) – Colin M Mar 08 '13 at 20:27
  • @ColinMorelli ok now you're confusing me a bit. My timestamp should be an absolute date and time, right? So what would 28 days have to do with anything, unless i happened to randomly be inside of the month of February? – Shackrock Mar 08 '13 at 20:30
  • @ColinMorelli not if you use %a in the format. It returns total number of days. – landons Mar 08 '13 at 20:30
  • @landons Touche, I have removed my comment. – Colin M Mar 08 '13 at 20:31
  • @landons Also, I'm still on PHP 5.2 at the moment =(. – Shackrock Mar 08 '13 at 20:32
  • How about this to set the date and time correctly with timestamps: `$date = new DateTime(); $date->setTimestamp($timeStamp);` But without PHP5.3, how can I accurately count the days between? – Shackrock Mar 08 '13 at 20:35
  • @landons I added an update to the question, please take a gander. – Shackrock Mar 08 '13 at 22:08
  • @Shackrock Hmm.. I don't know how that change accounts for DST. `mktime()` should automatically factor it in if your server is setup correctly. Did that fix it somehow?! – landons Mar 08 '13 at 22:17
  • @landons UNIX timestamps are _always_ GMT. Therefore DST is not relevant. You need only worry about them when converting from a date/time to a timestamp, or back – Colin M Mar 09 '13 at 11:42
  • @landons yea, that seemed to fix it. It correctly calculates the days now (it was always 1 day short before, when crossing over this sunday, which is the time change). – Shackrock Mar 09 '13 at 12:06
  • @ColinMorelli well I'm starting with unix timestamps here. They are in the DB that way. I'm basically trying to find the most correct way to count the days _without_ the `DateTime` class. – Shackrock Mar 09 '13 at 12:07
  • @landons you know what, it was because of my mktime statement in conjunction with the floor on each timestamp. Somehow, setting that time to `10,00,00` for each that are being calculated seems to do the trick... That was found in this thread: http://stackoverflow.com/questions/2736784/how-to-find-the-dates-between-two-specified-date - although I don't completely understand why... – Shackrock Mar 09 '13 at 12:25