I am trying to create a duration time.
I have a user option to enter a time duration in any of these formats: 0.5, 1, 1.5, 2, 2.5 ect.
I have a WordPress post date (used as a start time) and the finish time is calculated with the above user inputs. Together they build a duration time.
Example:
A user enters 1 - Example Out: Duration: 16:30 - 17:30
Problem:
This currently cannot output the correct end time if a user enters anything other then a whole number.
So, 1,2,3 ect would work fine, but 0.5, 1.5, 2.5 will all error and show the wrong end time.
I am need of a second pair of eyes, I cannot see the error of my ways.
// Get user duration option - 0.5, 1, 1.5, 2 ect
$course_hours = floatval(get_field('hours'));
$course_minutes = ($course_hours % 1) * 60;
$end_hour = intval(get_the_date('H'));
$end_minute = intval(get_the_date('i'));
$end_ampm = get_the_date('a');
if($course_minutes != 0 && $course_minutes + $end_minute <= 59){
$end_minute += $course_minutes;
$end_hour += floor($course_hours);
}
elseif($course_minutes != 0 && $course_minutes + $end_minute > 59){
$end_minute = ($course_minutes + $end_minute) % 60;
$end_hour += floor($course_hours) + 1;
}
elseif($course_minutes == 0){
$end_hour += floor($course_hours);
if ($end_minute == 0){$end_minute = '00';}
}
$end_time = $end_hour.':'.$end_minute;
$safe_post_status = get_post_status();
//Demo output
echo the_date('d F Y G:i');
echo ' - '.$end_time;
Thanks!
Writing logic for your question. Change the date format as per your requirement.
seems like you are using wordpress.
$course_hours = (get_field('hours'));
$course_minutes = ($course_hours) * 60;
$formatter = [];
$increment = 0.5;
$h = $increment * 60;
while ($h < $course_minutes ) {
$key = date('H:i', strtotime(date('Y-m-d') . ' + ' . $h . ' minutes'));
$value = date('h:i', strtotime(date('Y-m-d') . ' + ' . $h . ' minutes'));
$formatter[$key] = $value;
$h = $h + ($increment * 60 );
}
echo $output = implode(" - ",$formatter);
// 12:30 - 01:00 - 01:30 - 02:00
Related
This question already has answers here:
How do I find the hour difference between two dates in PHP?
(10 answers)
Closed 5 years ago.
I have datetimes in the following format:
Start: 2017-07-16 20:00
End: 2017-07-16 23:30
Start: 2017-07-18 21:30
End: 2017-07-19 00:30
I need to tell from these intervals how many hours (in 0,5 increments) are spent between 18:00-22:00 and 22:00-06:00 in total for a month.
Thanks in advance for any hint.
The current code I have is this, but I'm not sure if it is covering all timeframe possibilities:
<?php
date_default_timezone_set("UTC");
$start = array(
"2017-07-16 21:30:00",
"2017-07-16 18:00:00"
);
$end = array(
"2017-07-17 00:30:00",
"2017-07-16 18:30:00"
);
$amount_low = 0;
$amount_high = 0;
for($i = 0; $i < sizeof($start); $i++) {
$start_time = date("H:i:s", strtotime($start[$i]));
$end_time = date("H:i:s", strtotime($end[$i]));
$start_date = date("Ymd", strtotime($start[$i]));
$end_date = date("Ymd", strtotime($end[$i]));
// getting chunk before 22:00 if
if(
(strtotime($start[$i]) >= strtotime($start_date . " 18:00") && strtotime($start[$i]) < strtotime($start_date . " 22:00"))
&&
$start_date < $end_date
) {
$interval_low = strtotime($start_date . " 22:00") - strtotime($start[$i]);
$amount_low += ceil($interval_low / 1800) / 2;
}
//amount_high
if(strtotime($start[$i]) > strtotime($start_date . " 22:00") && strtotime($start[$i]) < strtotime($start_date . " 06:00")) {
$interval_high = strtotime($end[$i]) - strtotime($start[$i]); //needs further things
$amount_high += ceil($interval_high / 1800) / 2;
} elseif (strtotime($start[$i]) < strtotime($start_date . " 22:00") && strtotime($end[$i]) > strtotime($start_date . " 22:00")) {
$interval_high = strtotime($end[$i]) - strtotime($start_date . " 22:00");
$amount_high += ceil($interval_high / 1800) / 2;
} else {
$interval_low = strtotime($end[$i]) - strtotime($start[$i]);
$amount_low += ceil($interval_low / 1800) / 2;
}
}
echo $amount_low;
echo "\n$amount_high";
?>
Would this work for you?
$start = strtotime('2017-07-16 20:00');
$end = strtotime('2017-07-16 23:30');
$interval = $end - $start;
$hours = floor($interval / 1800)/2;
echo($hours);
This will display the total hours (in 0,5 increments) between the two dates (rounding down, so if it's 55 minutes, it's 0,5 hours; replace 'floor' with 'ceil' for the opposite).
I believe a part of your solution is found here from Aillyn
You can convert them to timestamps and go from there:
$hourdiff = round((strtotime($time1) - strtotime($time2))/3600, 1);
Dividing by 3600 because there are 3600 seconds in one hour and using round()
to avoid having a lot of decimal places.
$hourdiff = round((strtotime($time1) - strtotime($time2))/3600, 1);
This will give you a rounded hour difference between the two times. You could do something similar, just apply it for each interval for which ever month and adjust your math. There's not really going to be a single PHP function you can call to solve this.
I will get random number of seconds the number may greater than 86400 which is greater than 24hours (when converts to hours) so php gmdate() won't get my required output. So I created the following code.
$ts = mt_rand(36000,99999);
echo floor($ts/3600)."Hr ".floor(($ts/3600 - floor($ts/3600))*60)."min ".round(((($ts/3600 - floor($ts/3600))*60) - floor(($ts/3600 - floor($ts/3600))*60))*60)."sec";
I am getting the output like 22Hr 29min 4sec for $ts = 80944;
Everything is fine but for $ts = 39540; the output came is 10Hr 58min 60sec here 60sec came which is wrong. it should get like 10Hr 59min 0sec. What's wrong in my code?
I didn't break your code apart to find out what was wrong, but I believe this solves the problem.
$ts = mt_rand(36000,99999);
$h = floor($ts / 3600);
$m = floor(($ts - 3600 * $h) / 60);
$s = $ts - ($h * 3600) - ($m * 60);
echo $h . "Hr " . $m . "Min " . $s . "s";
I have modified the code to check if the value of secs is 60, as It is already being caluculated due to round while calculating minutes
$ts = 80944; //mt_rand(36000,99999);
echo floor($ts/3600)."Hr ". round(($ts/3600 - floor($ts/3600))*60)."min ";
echo (round(((($ts/3600 - floor($ts/3600))*60) - floor(($ts/3600 - floor($ts/3600))*60))*60) == 60) ? '0' : round(((($ts/3600 - floor($ts/3600))*60) - floor(($ts/3600 - floor($ts/3600))*60))*60)."sec";
Hey you can do it with a modulo calculation :
$secondsGiven = 1036899;
$outputSeconds = $secondsGiven % 60;
$minutes = ($secondsGiven-$outputSeconds) / 60 ;
$outputMinutes = $minutes % 60;
$hours = ($minutes - $outputMinutes) / 60;
$outputHours= $hours % 24;
$outputDays = $outputHours / 24;
echo $outputDays . 'Days ' . $outputHours . 'HR ' . $outputMinutes . 'min ' . $outputSeconds . 'sec';
this example would output : 12Days 0Hr 1min 39sec
echo gmdate("H:i:s", 39540);
use this
This is a php implementation of Josh r code to calculate the position of the sun for a given date and time :
This is the corrected code after MvG help :
function getSunPosition($lat, $long, $year, $month, $day, $hour, $min) {
// From https://stackoverflow.com/questions/8708048/position-of-the-sun-given-time-of-day-latitude-and-longitude?rq=1
// Get Julian date for date at noon
$jd = gregoriantojd($month,$day,$year);
//correct for half-day offset
$dayfrac = $hour / 24 - .5;
//now set the fraction of a day
$frac = $dayfrac + $min / 60 / 24;
$jd = $jd + $frac;
// The input to the Atronomer's almanach is the difference between
// the Julian date and JD 2451545.0 (noon, 1 January 2000)
$time = ($jd - 2451545);
// Ecliptic coordinates
// Mean longitude
$mnlong = (280.460 + 0.9856474 * $time);
$mnlong = fmod($mnlong,360);
if ($mnlong < 0) $mnlong = ($mnlong + 360);
// Mean anomaly
$mnanom = (357.528 + 0.9856003 * $time);
$mnanom = fmod($mnanom,360);
if ($mnanom < 0) $mnanom = ($mnanom + 360);
$mnanom = deg2rad($mnanom);
// Ecliptic longitude and obliquity of ecliptic
$eclong = ($mnlong + 1.915 * sin($mnanom) + 0.020 * sin(2 * $mnanom));
$eclong = fmod($eclong,360);
if ($eclong < 0) $eclong = ($eclong + 360);
$oblqec = (23.439 - 0.0000004 * $time);
$eclong = deg2rad($eclong);
$oblqec = deg2rad($oblqec);
// Celestial coordinates
// Right ascension and declination
$num = (cos($oblqec) * sin($eclong));
$den = (cos($eclong));
$ra = (atan($num / $den));
if ($den < 0) $ra = ($ra + pi());
if ($den >= 0 && $num <0) $ra = ($ra + 2*pi());
$dec = (asin(sin($oblqec) * sin($eclong)));
// Local coordinates
// Greenwich mean sidereal time
//$h = $hour + $min / 60 + $sec / 3600;
$h = $hour + $min / 60;
$gmst = (6.697375 + .0657098242 * $time + $h);
$gmst = fmod($gmst,24);
if ($gmst < 0) $gmst = ($gmst + 24);
// Local mean sidereal time
$lmst = ($gmst + $long / 15);
$lmst = fmod($lmst,24);
if ($lmst < 0) $lmst = ($lmst + 24);
$lmst = deg2rad($lmst * 15);
// Hour angle
$ha = ($lmst - $ra);
if ($ha < pi()) $ha = ($ha + 2*pi());
if ($ha > pi()) $ha = ($ha - 2*pi());
// Latitude to radians
$lat = deg2rad($lat);
// Azimuth and elevation
$el = (asin(sin($dec) * sin($lat) + cos($dec) * cos($lat) * cos($ha)));
$az = (asin(-cos($dec) * sin($ha) / cos($el)));
// For logic and names, see Spencer, J.W. 1989. Solar Energy. 42(4):353
if ((sin($dec) - sin($el) * sin($lat)) >00) {
if(sin($az) < 0) $az = ($az + 2*pi());
} else {
$az = (pi() - $az);
}
$el = rad2deg($el);
$az = rad2deg($az);
$lat = rad2deg($lat);
return array(number_format($el,2),number_format($az,2));
}
This has been tested with Congo (near Equateur) lat/long : -4.77867 / 11.86364 for date Sept 1st 2013 at 10h00. In this case, the correct answer is :
elevation = 67.77503
azimuth = 54.51532
Thanks for your help debuging this php code !
Greg Fabre.
I believe the line
if ($dayfrac < 0) $dayfrac += 1;
is in error. If you are before noon, you don't want to refer to the same time one day later, but instead you want to specify a time before noon, i.e. subtract from the julian date which represents noon.
Removing that line, your example date corresponds to the one computed using http://www.imcce.fr/en/grandpublic/temps/jour_julien.php, namely 2456536.9166666665. The resulting
$el = 67.775028608168
$az = 54.515316112281
looks pretty good to me. In particular, it agrees with the R run
elevation = 67.77503
azimuth = 54.51532
and also with what Stellarium says (although I quoted this incorrectly in a comment above):
Alt = 67°46'30" = 67.775
Az = 54°30'60" = 45.5167
It also (almost) agrees with sunearthtools.com, so I guess you made a mistake when first entering the data there:
So I'd say that solves the problem.
I have a big problem for getting/computing the minutes.
Scenario:
I have a form which is the user can input the seconds [5s, 10s, 25s, 30s, 60s]. I called the table "Duration"
I already have "Duration" [compose of minutes:seconds], in my database which is "1:5" [the last input]. Then I insert again another seconds "10s"...
*the format is minutes:seconds
The correct output should be: 1:15
The current result is : 0:15
AS we see. I have a problem in computing the minutes. The codes I will show is good for subtracting the seconds. But now I need to revised it to adding the seconds.
Here's my code:
$duration = $_POST["duration"];
if(sizeof($bldg) == 1)
{
$total = sizeof($bldg)-1;
}
else
{
$total = sizeof($bldg)%2;
}
for($i=0; $i<sizeof($bldg);$i++)
{
$result = mysql_query("SELECT fldTotalDuration FROM tbldata WHERE fldNetname = '".$network."' AND fldBldgName = '".$bldg[$i]."' AND fldWeek = '".$week."' AND fldMonth = '".$month."' ");
if(mysql_num_rows($result)==0)
{
$totalduration = "";
$seconds = 0;
$minutes = 0;
$computeSecMin = $seconds * $minutes;
$subSecMin = $computeSecMin + $duration;
$getMin = floor($subSecMin/60);
$getSec = $subSecMin%60;
$totalduration = $getMin .":". $getSec;
}
else{
$row = mysql_fetch_array($result);
$time = explode(":",$row['fldTotalDuration']);
$dur = explode(" ",$duration);
$computeSecMin = 60 * $time[0];
$subSecMin = $computeSecMin + $time[1] + $dur[0];
$getMin = floor($subSecMin/60);
$getSec = $subSecMin%60;
$totalduration = $getMin .":". $getSec;
}
}
$query = "INSERT INTO tbldata(fldNetname,fldBldgName,fldPlaylist,fldMonth,fldWeek,fldDuration,fldFrom,fldTo,fldTotalDuration) VALUES ('".$network."','".$bldg[$i]."','".$AdName."','".$month."','".$week."','".$duration."','".$from."','".$to."', '".$totalduration."')";
mysql_query($query) or die (mysql_error());
$duration = is came from another form where its a combobox/dropdown that is consists of 5s, 10s, 25s, 30s, 60s.
Currently, for adding the seconds is okay but for minutes is not good.
my problem for the computation is this "$getMin = floor($subSecMin/60); " .The result of this is "0" but it should be "1" because this computation is for "minutes".
Thanks for helping me with this problem.
Actually, what you got is what you should get.
If
$time = [0, 5]
and
$dur = [10, s]
then
$computeSecMin = 60 * $time[0] = 60*0 = 0
and
$subSecMin = $computeSecMin + $time[1] + $dur[0] = 0 + 5 + 10 = 15
Thus
$getMin = floor($subSecMin/60) = floor(15/60) = floor(0.25) = 0
It seems to me that you are computing it right, and the result is indeed 0 minutes.
The problem is your duration variable. It seems to me that your program is getting the wrong value. If I understand, it should be [1, 5] and not [0,5]. Check the function that is getting this value.
Here is what you are trying to do (sorry, I changed variables names, yours were not obvious):
$time = array(1,5);
$time_plus = '10s';
$time_plus = preg_replace('#\D#', '', $time_plus);
$minutes = $time [0] + (($time_plus + $time[1] >= 60) ? 1 : 0);
$seconds = ($time[1] + $time_plus) % 60;
echo $new_time = $minutes . ":" . $seconds;
Demo: http://codepad.org/eOBNeHrq
You may find using mysql for time manipulations will be cleaner for your application. AddTime() lets you do what you want with only seconds and minutes.
SELECT ADDTIME('00:32.50','1:27.50');
gives the result of:
01:59:01.000000
So, this adds 32.5 seconds to 1 minute 27.50 seconds = 1 minutes 59 seconds and .01 milliseconds.
Say I have the following 2 dates, a start date and end date:
Year-Month-Day Hours:Minutes:Seconds
Start Date: 2010-12-03 14:04:41
Expiry Date: 2010-12-06 12:59:59
How could I, using PHP subtract the two dates and be left with something like:
Difference: -3 days, 2 minutes and 18 seconds (If expiry date is past 3 days for example).
http://www.php.net/manual/en/datetime.diff.php
<?php
$datetime1 = date_create('2009-10-11');
$datetime2 = date_create('2009-10-13');
$interval = date_diff($datetime1, $datetime2);
echo $interval->format('%R%d days');
//result will be +2 days
?>
I hope that is what you are looking for.
This is based on numerous online examples; you'll see similar code all around if you get your google on.
function timeSince($dateFrom, $dateTo) {
// array of time period chunks
$chunks = array(
array(60 * 60 * 24 * 365 , 'year'),
array(60 * 60 * 24 * 30 , 'month'),
array(60 * 60 * 24 * 7, 'week'),
array(60 * 60 * 24 , 'day'),
array(60 * 60 , 'hour'),
array(60 , 'minute'),
);
$original = strtotime($dateFrom);
$now = strtotime($dateTo);
$since = $now - $original;
$message = ($now < $original) ? '-' : null;
// If the difference is less than 60, we will show the seconds difference as well
if ($since < 60) {
$chunks[] = array(1 , 'second');
}
// $j saves performing the count function each time around the loop
for ($i = 0, $j = count($chunks); $i < $j; $i++) {
$seconds = $chunks[$i][0];
$name = $chunks[$i][1];
// finding the biggest chunk (if the chunk fits, break)
if (($count = floor($since / $seconds)) != 0) {
break;
}
}
$print = ($count == 1) ? '1 ' . $name : $count . ' ' . $name . 's';
if ($i + 1 < $j) {
// now getting the second item
$seconds2 = $chunks[$i + 1][0];
$name2 = $chunks[$i + 1][1];
// add second item if it's greater than 0
if (($count2 = floor(($since - ($seconds * $count)) / $seconds2)) != 0) {
$print .= ($count2 == 1) ? ', 1 ' . $name2 : ', ' . $count2 . ' ' . $name2 . 's';
}
}
return $message . $print;
}
It was intended to show the difference between a given time and the current time, but I've made slight changes to show the difference between two times instead. You may wish to change the output from a postfix of ' ago' to a prefix of 'Difference: '.