0

I know there might be different ways using timestamps and stuff but I'm having trouble converting number of hours into something that human would understand. I do not have power to change anything in the database.

There is a column that holds number of hours, so it can be something like 134.37 hours. Now I can not display that and tell user that something will happen in 134.37 hours I need to convert it into months, days, hours, minutes, seconds.

For example:

Given Hours: 23.33

Desired Result: 0 Months, 0 Days, 23 Hours, 19 Minutes, 48 seconds (dont care about seconds)

Now I need months and days since number of hours might be large. The code I started with does give me number of hours, minutes and seconds but i cant get days and months.

$months = $days = $hour = $min = $sec = 0;

$decimalHours = 23.33;

//convert to hours
$hour = (int)$decimalHours;
$decimalHours -= $hour;

//convert to minutes and subtract minutes
$decimalHours *= 60;
$min = (int)$decimalHours;
$decimalHours -= $min;
$decimalHours = number_format($decimalHours, 10);

//convert to seconds
$decimalHours *= 60;
$sec = (int)$decimalHours;

echo $hour . ' hours, ' . $min . ' minutes, ' . $sec . ' seconds';

Please help if you know a function that does it or an easier way.

GGio
  • 7,563
  • 11
  • 44
  • 81

4 Answers4

3

How long is a month? 30 days? 31 days? 30.5 days? 365.24 / 12 ?

Skipping that, you can do:

$hours = 23.33;
$days = floor($hours / 24);
$remaining_hours = $hours - $days * 24;
$hours = floor($remaining_hours);
$minutes = round(($remaining_hours - $hours) * 60);
echo $days . " days " . $hours . " hours " . $minutes . " minutes";
// 0 days 23 hours 20 minutes
Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • thank you I guess I can ignore months and display days + hours + minutes is better than just hours – GGio Jan 03 '14 at 15:48
3

You can achieve this with DateTime extension:

$hours   = 23.33;
$zero    = new DateTime('@0');
$offset  = new DateTime('@' . $hours * 3600);
$diff    = $zero->diff($offset);
echo $diff->format('%m Months, %d Days, %h Hours, %i Minutes');

demo

Code new DateTime('@0'); creates DateTime object with timestamp 0, which is January 1 1970 00:00:00 GMT. Timestamp 0 is zero number of seconds since the Unix Epoch.
In this example it basically doesn't matter how you create DateTime object, I just wanted it to be in UTC offset and to ignore DST. You can also create DateTime object like new DateTime('UTC'); (which is current datetime in UTC timezone) or something familar.

Edit:

I guess I can ignore months and display days + hours + minutes is better than just hours

In that case just use echo $diff->format('%a Days, %h Hours, %i Minutes');. See the difference where I replaced format of days from %d to %a. Read the DateInterval::format() what this characters mean. You can also access parameters directly on DateInterval objects as echo $diff->days; echo $diff->h; // etc. (use print_r($diff); to see those parameters).

Glavić
  • 42,781
  • 13
  • 77
  • 107
  • 1
    Interesting approach. +1 (the `@0` timestamp thing might not be easy to understand for a new user, so I think it'd be better to have some explanation of the code, too) :) – Amal Murali Jan 03 '14 at 15:58
  • This solved it. Thank you very much will read more about DateTime extension. – GGio Jan 03 '14 at 16:03
0

First off the hours thing is bonkers. I'm assuming they are always adjusted to be current (ie 10 hours to something happening... 9 hours.. 8 hours)

But have you tried a simple php strtotime() approach? Format your output to a date/time/countdown using timestamp?

$dateFromToday = strtotime('+23.33 hours'); // get unixtimestamp from today + hours
echo date('l jS \of F Y h:i:s A', $dateFromToday); // format my date output

Maybe I am oversimplifying it tho.

Jakub
  • 20,418
  • 8
  • 65
  • 92
  • `strtotime()` doesn't work with decimal numbers, so this example will not work. Check what does `date_parse('+23.33 hours');` return, and you will see that it is not what you expected. – Glavić Jan 03 '14 at 16:48
0

If you populate the $datetime variable (sorry for unconventional variable names), the following code applies.

This:

$original = 23.33;

$hours = floor($original);
$minutes = floor(60 * ($original - $hours));

echo sprintf('Total: %s hours, %s minutes', $hours, $minutes);
echo '<br />';

$datetime = new \DateTime('-2 hours 15 minutes');
$destined = new \DateTime(sprintf('+ %s hours %s minutes', $hours, $minutes));

echo sprintf('Scheduled Time: %s', $destined->format('Y-m-d sH:i:s'));
echo '<br />';

$interval = $destined->diff($datetime);
echo sprintf('Time Remaining: %s months, %s days, %s hours, %s minutes', 
    $interval->m, $interval->d, $interval->h, $interval->i);

Outputs:

Total: 23 hours, 19 minutes
Scheduled Time: 2014-01-04 1915:15:19
Time Remaining: 0 months, 1 days, 1 hours, 4 minutes
Flosculus
  • 6,880
  • 3
  • 18
  • 42