Calculating Time difference between two times in hh:mm format - PHP - php

I am trying to calculate the time difference in hours between to times in format hh:mm. The problem is the data is in both 12 hour and 24 hour.
eg. 23:55 - 00:10 , 12:10 - 01:02, 10:50 - 11:10 etc..
I tried the method given here PHP - hours difference (HH:MM format)
I need a function with all conditions to handle the 24h, 12h to calculate the time difference in hours.
Many thanks.

The code in linked solution is fine except over midnight case. If you assume positive difference (start before end) - you may add 1 day (in seconds) when it appears to be negative. Just change return statement to:
return ($timeDiff > 0) ? $timeDiff : $timeDiff + 24*60*60;

Related

PHP - time minus time to minutes

In php i have two times - 11:00:00 and 12:45:00. I want to get the difference between them in minutes, in this case 105 minutes. Whats the best way that can be done?
Thank you!
Here you go:
( strtotime('12:45:00') - strtotime('11:00:00') ) / 60
strtotime() is a very useful function. It returns the Unix timestamp for a wide variety of times and dates. So, if you take the two timestamps, and subtract them, then you have the difference in seconds. Divide by 60 to get the minutes.
$time_diff = strtotime('2013-03-13 12:45:00') - strtotime('2013-03-13 11:00:00');
echo $time_diff/60;
I just kept dates as not sure if I keep the time part only it would return the correct diff or not.
EDIT
I just tested it works without date too ...
$time_diff = strtotime('12:45:00') - strtotime('11:00:00');
echo $time_diff/60;
So to answer you question - strtotime() returns a timestamp (the number of seconds since January 1 1970 00:00:00 UTC) so you simply divide it by 60 to convert it result into minutes.

Error on strtotime()

$dateTime="2011-10-12 00:00:00";
echo $newDateTime =date("Y-m-d H:i:s", strtotime($dateTime.' -1 hours 30 minutes'));
The result of above code is '2011-10-11 23:30:00'. However, the correct answer should be
2011-10-11 22:30:00.
Is there anying wrong in the code and can anyone help me?
Many thanks
23:30 is the expected result (once you know what is happening).
The relative parts of the string (-1 hours 30 minutes) are processed separately as -1 hours and 30 minutes. They are two instances of the number space? (unit | 'week') format as described in the Relative Formats documentation.
Because of this the cumulative relative change in the time is only -30 minutes, which from midnight gives 23:30.
To get the effect that you desire, either:
use a single relative statement (e.g. -90 minutes)
make your original minutes statement negative as -1 hours -30 minutes
or, use the special ago format as 1 hours 30 minutes ago
See http://php.net/datetime.formats.relative for more details.
date functions aren't fully daylight savings aware. Try using dateTime objects instead

php date subtraction using strtotime function not returning correct length of time

I am converting PHP (v 5.2.17)-based reports to SSRS.
I'm trying to write a query that subtracts dates like the php file does.
The date calculation either matches exactly, or it differs by exactly 3600 seconds
$timediff=strtotime(date("Y-m-d"))-strtotime("03/29/2007");
print $timediff; // 137635200
select (trunc(sysdate) - to_date('03/29/2007','MM/DD/YYYY'))*60*60*24 from dual
-- returns 137635200 - matches
$timediff=strtotime(date("Y-m-d"))-strtotime("11/23/2009");
print $timediff; // 53823600
select (trunc(sysdate) - to_date('11/23/2009','MM/DD/YYYY'))*60*60*24 from dual
-- returns 53827200 - doesnt match - off by 3600
I've searched stackoverflow and found the following example which sounds like it (11/23/2009 is a monday, and so is today 8/8, but it doesnt differ in the same way) PHP Strtotime erratic function
My assumption is that the php calculation is wrong, and the oracle is correct.
What say you? ;-)
Thanks!
Without seeing the exact values I suspect its because one of them is adjusting for daylight savings and the other is not. Most parts of the world change to/from daylight savings time during march. So in your first example both dates are in the same GMT offset, but in the second (November) they're not.
So one of your platforms (probably Oracle) is taking this one hour shift into account and the other is not.
3600 = an hour so could be timezone differences?
53827200 = ( 623 * 60*60*24 )
So 53827200 is exactly 623 days of 24 hours.
53823600 is 622.958333 days or 622 days (of 24 hours) plus 23 hours.
Both are right, for a given definition of right.

Trouble getting age in hours

I am trying to calculate the age of something in hours.
$data['record'] is a mysql NOW() timestamp in a DATETIME field.
$data['record'] is 20 minutes old, when I do :
$minutes= date('i',(strtotime("now")-strtotime($data['record'])));
$minutes returns 20 properly, however for some reason when I try $hours it returns '5'.
$hours = date('g',(strtotime("now")-strtotime($data['record'])));
This does not make sense, as $hours should be returning 0 as the record is less than 60 minutes old...
When I checked the value of "strtotime("now")-strtotime($data['record'])" it is equal to '980'. Help!
Please compare the output of strtotime("now") of php and select now(); in sql. I think there is a timezone problem hidden here.
As you said, strtotime("now")-strtotime($data['record']) returns 980, which should be in minutes. 960 is divideable by 60 and comes out at 16 hours, so 980 is 16 hours 20 minutes - the 20 minutes are exactly what you are looking for. You'll need to adjust either instance to use the time of the other - I would go with always using UTC. If you need to display it, parse it appropiately and output the local time.
Please See: http://php.net/manual/en/function.date.php
When the $format parameter="g", it returns a value 1-12.
Date will not quite work like you're expecting it to.
Date takes a time stamp (# of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)), and converts that into a legible time format. Essentially, with a value of 980, you are going to get January First at midnight + 980 seconds (roughly January 1 1970 00:16:20 GMT. When you convert for the time zone difference, (chances are, about 5 hours difference) that's how you get five.
To fix this, simply take 980, and divide by 60 to get minutes, then divide by 60 again to get hours, so:
$hours = ((strtotime("now")-strtotime($data['record'])) / 60) / 60;
There's no need for date, as you need a relative time, not an absolute time.

How do I calculate the number of seconds in a month in PHP?

How do I accurately determine the number of seconds in a month using PHP? Is the best way to take the number of seconds in a year and divide by 12?
Multiply the number of days in the month by 60 * 60 * 24.
Due to daylights savings... take a good datetime library in your language and calculate the difference between the first day of the month 0:00:00 and the first day of the next month 0:00:00 and extract the number of seconds.
How accurate do you need to be?
60 seconds * 60 minutes * 24 hours * Z days in the month gives you an accurate number for a given month.
If you need an average month go for number of seconds in the year and divide by twelve.
In some domains, such as billing or legal domains a 'month' might actually be exactly 30 days.
If you are working across multiple years or doing tight integration between disperse systems, you'll need to consult resource to determine leap seconds. For historical data this could be a table, but otherwise you'd be better suited by synchronizing to a trusted time source.
http://en.wikipedia.org/wiki/Leap_second
60 (seconds) * 60 (minutes) * 24 (hours) * ## (days in the month)
Given that there are 86,400 seconds in a day, you can multiply this number by the result of the DateTime.DaysInMonth function (in C#). The following function does just that:
public double SecondsInMonth(int year, int month)
{
return DateTime.DaysInMonth(year, month) * 86400;
}
E.g., find the seconds in the current month:
double secondsInCurrentMonth = SecondsInMonth(DateTime.Now.Year, DateTime.Now.Month);
Number of days in the given month * hours/day * minutes/hour * seconds/minute
is the best way.
If you're doing this in pure math it would be 60 * 60 * 24 * <number of days in month>.
What's the use case?
No, use the date API available for a particular lannguage and determine the number of days in the current month. Then calculate the number of seconds. Also take into account leap years.
Depends on if you want an average month or a specific month....your way gets an average. For a specific month count days and multiply by 86400 (seconds per 24.0 hour day)
This isn't really a programming question. Months have different lengths, so dividing the number of seconds in a year by 12 will give you nothing useful. It's easy to determine the days in a month - a simple lookup table plus a calcualation of leap years will do it. Then just multiply by the number of seconds in a day.
If you are being really precise you might need to include calculations of leap seconds, but since they are unpredictably assigned based on astronimical calculations, and not predictable in advance, I would probably ignore them.
Number of days vary in each month.Proper algorithm for this is to get number of days in moth and multiply it with 86400 (number of seconds in a day).You might also need average count or leap years calculation ...
The trivial answer is to find the number of days in the month and then multiply by 86400. That will work perfectly if you are dealing with dates and times in UTC. However, if you are using a local time zone then this approach yields a slightly incorrect result if that time zone observes daylight saving time. The error is somewhat small over a one month period, but will magnify if you need to make similiar calculation over short periods like a day. I definitely recommend doing all processing and storage in UTC, but depending on the application you will have to convert your UTC times to the local time zone that the end user is expecting. And it might even be plausible that you have to calculate durations using the local time zone. Again, use UTC as much as possible so that you avoid most of the problems.
I came up with this solution in C#. It is compatible with UTC and local time zones alike. You just have to tell the GetNumberOfSecondsInMonth which time zone you want the calculation to be based on. In my example I chose November of 2010 because here in Missouri we observe DST and there was one extra hour this month. Daylight saving time rules change so I used an API that pulls the DST information from the operating system so that the calculation will be correct for years prior to 2007 (that is when the United States expanded DST for most regions).
I should point out that my solution does not handle leap seconds in UTC. For me that is never an issue. But it would be easy to account for that by using a lookup table if you really needed ultra high precision timing.
public class Program
{
static void Main(string[] args)
{
int seconds = GetNumberOfSecondsInMonth(2010, 11, DateTimeKind.Local);
}
public static int GetNumberOfSecondsInMonth(int year, int month, DateTimeKind kind)
{
DateTime start = new DateTime(year, month, 1);
DateTime end = start.AddMonths(1);
int seconds = (int)(end - start).TotalSeconds;
if (kind == DateTimeKind.Local)
{
DaylightTime dt = TimeZone.CurrentTimeZone.GetDaylightChanges(year);
seconds = (dt.Start > start) ? seconds - 3600 : seconds;
seconds = (dt.End < end) ? seconds + 3600 : seconds;
}
return seconds;
}
}
It's a problem with years ang months as there is not a fixed number of days in them. But after a lot of thought I have figured out how to do it. It was not a good idea to calculate months with either 30 or 31 days in them, because it looks bad, for example converting from 1 year to months would give an answer of 11 months and 25 days if I had 30 days in each month, or 12 months and 5 days if I have 31 days in each month.
Instead I loop through a series of days per month: 30,30,31,30,31,30,31,30,31,30,31,30 which makes a total of 365 days in a year. So if I want the number of days in 4 months I add 30+30+31+30. And if I start with 23 months it would go through the loop almost twice (23 times 30 or 31). It's done in a while/until loop. For every 4 years I add 1 day, making it 366 days (the first 30 is changed to 31 in the list). It's rather complex but it works and the result looks better.

Categories