PHP select closest to variable - php

Just wondering how I would select the closest variable.
I have a set list of military times, i.e:
0030
0100
0130
0200
etc...
All in half hour increments. How would I select the closest time to now.
For example.
User clicks on the button, php gets the time it is now, and selects the closest time variable. So if it's 0144, it would pick 0130. and if it's 0146, it would pick 0200.

Since you always store times at 30 minutes interval, subtract the last 2 digits (minutes) from the current time from 30.
For example:
If current time is 0146,
strip out 46 (minutes)
Take absolute difference from 30
If difference > 15, take the next available time slot for 0146
(which is 0200 here)
If difference <= 15, take the previous available time before 0146
(which is 0130 here)
Hope this helps.

I believe this should do it:
function military_time() {
$hour = (int) date('G');
$minute = (int) date('i');
$rounded_minute = round($minute / 30);
switch ($rounded_minute) {
case 0:
$minute = '00';
break;
case 1:
$minute = '30';
break;
case 2:
$minute = '00';
$hour = (int) $hour + 1;
break;
}
// 2400 should become 0000
if ($hour > 23) $hour = 0;
// leading zero
if ($hour < 10) $hour = '0' . $hour;
return $hour . $minute;
}
echo military_time();
Could probably be improved though.

For ease, in your calculations treat them as integers, ignoring the leading zeroes as they're not useful to your calculations.
You have 144 and you want to round down to 130, or 146, up to 200. Similarly 14 (0014) would go to 0 (0000) and 15 (0015) up to 30.
Simple if/thens would suffice to complete this.

You can try
$times = array("0030","0100","0130","0200");
echo "<pre>";
echo militaryTime($times, "0020"), PHP_EOL;
echo militaryTime($times, "0050"), PHP_EOL;
echo militaryTime($times, "0144"), PHP_EOL;
echo militaryTime($times, "0146"), PHP_EOL;
echo militaryTime($times, "0220"), PHP_EOL;
Output
0030
0100
0130
0200
0200
Function Used
function militaryTime($times, $selected) {
if (empty($times))
trigger_error("Empty array not supported ");
$times[] = $selected;
sort($times);
$position = array_search($selected, $times, true);
$current = DateTime::createFromFormat("Hi", $times[$position]);
$previous = isset($times[$position - 1]) ? DateTime::createFromFormat("Hi", $times[$position - 1]) : null;
$next = isset($times[$position + 1]) ? DateTime::createFromFormat("Hi", $times[$position + 1]) : null;
if ($previous != null && $next == null) {
return $previous->format("Hi");
}
if ($previous == null && $next != null) {
return $next->format("Hi");
}
$closest = ($current->diff($previous)->format("%i") - $current->diff($next)->format("%i") <= 0) ? $previous : $next;
return $closest->format("Hi");
}

Related

How to convert h:m:s to float and float to h:m:s php

I want to convert time value with second to float and than do some calculation on it and convert it again to time value using php
I have used the function describe below but it has only hour and minute calculation it display wrong amount if second value is there.
i found this function from time conversion to float
I have used function for convert time to float is
function hours_tofloat($val){
if (empty($val)) {
return 0;
}
$parts = explode(':', $val);
return $parts[0] + floor(($parts[1]/60)*100) / 100;
}
hours_tofloat("00:02:37");
if i use above function for 00:02:37 time value it gives me wrong float no 0.03 because above function dose not have option for second. so help me and guide how to calculate it
Modify your code as follows. It will return the time in seconds.
$val = '00:02:37';
function hours_tofloat($val){
if (empty($val)) {
return 0;
}
$parts = explode(':', $val);
return (int) (($parts[0] * 60 *60) + $parts[1]*60 + $parts[2]);
}
echo hours_tofloat($val);
Output: 00:02:37 = 157
It returns
157
Why don't you use EPOCH time routines? Epoch time is an integer representing seconds based on 1 Jan 1970. You don't need the date part so you can have the following approach:
<?php
$time = '00:02:37';
$date = new DateTime("1970-01-01T$time+00:00");
echo 'Seconds = '.$date->format('U');
?>
Output
Seconds = 157
$val = "00:02:37";
/* function converts time value to float */
function time_to_float($val){
$parts = explode(':', $val);
$hour_val = 0;
$hour_val = $parts[0];
$min_val = $parts[1];
$second_val = $parts[2];
return ($hour_val +(($min_val* 1/60))+($second_val * 1/3600));
}
$value = time_to_float($val);// 0.043611111111111
/* function to convert float to time */
$res = float_to_time($value);//00:02:37
function float_to_time($value){
$value1 = explode('.',$value);
$hours = $value1[0];
$min_in_float = ($value - $hours) * 60/1;
$min_val = explode('.',$min_in_float);
$min_val = $min_val[0];
$min_in_float = $min_in_float - $min_val;
$second_val = $min_in_float * 60/1;
$second_val = round($second_val);
if($hours < 10){
$hours = "0".$hours;
}
if($min_val < 10){
$min_val = "0".$min_val;
}
if($second_val < 10){
$second_val = "0".$second_val;
}
return $hours.":".$min_val.":".$second_val;
}
I got reference about the calculation from
https://www.calculatorsoup.com/calculators/time/time-to-decimal-calculator.php
https://www.calculatorsoup.com/calculators/time/decimal-to-time-calculator.php
With strtotime I get the seconds immediately. UTC must be used as the time zone.
$time = '00:02:37';
$seconds = strtotime('1970-01-01 '.$time.' UTC'); //157
gmdate can be used to convert an integer into a time H:i:s.
$seconds = 157;
$timeHis = gmdate('H:i:s',strtotime('1970-01-01 UTC +'.$seconds.' Seconds'));
//'00:02:37'
The number of hours must not exceed 23 and the number of seconds $seconds must be less than 86400 (= 1 Day). Negative times are also not supported.

Inserting double zeros (00) in a php variable for mailchimp

Ok so I am trying to schedule a campaign with mailchimp API and so far everything works fine except for the last else if that doesn't put 00 in my variable. I know php will put only 1 zero in the array and can't think of a work around for this. Help ! The code below is used to take a date, put it in iso 8601 format and then I use substr_replace() to schedule the campaign to the next time lapse available for mailchimp (15, 30, 45, 00).
I tried to change it for a string "00" instead but mailchimp does not schedule it.
$date_temp = new DateTime($date_debut);
$date_debut_iso = $date_temp->format('c');
$test = explode(':', $date_debut_iso);
//campaign has to be scheduled on :00, :15, :30, :45
if($test[1] >= 0 && $test[1] <= 15){
$test[1] = 15;
}else if($test[1] >= 16 && $test[1] <= 30){
$test[1] = 30;
}else if($test[1] >= 31 && $test[1] <= 45){
$test[1] = 45;
}else if($test[1] >= 46 && $test[1] <= 59){
$test[1] = 00;
}
$new_date = substr_replace($date_debut_iso, $test[1], 14, 2);
i need the last else if to store 00 in my array $test[1] instead of 0. String doesn't work.
My only guess as to why setting $test[1] = '00'; wouldn't have worked is that all the other cases increase the time (or leave it the same), while that case decreases it because you're setting the minute to zero without changing the hour.
You don't really need to do all the string manipulation though. You can just get the minutes from the DateTime object and do a little math, then output the final result with ->format().
$date_temp = new DateTime($date_debut);
if ($offset = $date_temp->format('i') % 15) {
$date_temp->modify('+' . (15 - $offset) . ' minutes');
};
$new_date = $date_temp->format('c');
The calculation is basically: if the remainder of the minutes divided by 15 is non-zero, increase the time by 15 - remainder minutes. This will also increment the hour appropriately for the > 45 case.

PHP round minutes when hour ends

I'm looking for a posibility to set minutes to "00" instead of "60". I have following code:
$minute = date('i');
$minutesround = round($minute / 10) * 10;
$hour = date('H');
$minutesround = str_pad($minutesround, 2, 0, STR_PAD_LEFT);
$time = $hour . $minutesround;
echo $time;
My problem: If it is eg. 4:56pm the output should like this: 1700
but in my case, I get this 1660
Someone has an idea, how to realize this?
Thank you!
This works well:
$myRoundedTime = round(time()/600) * 600; // round time to nearest 6th of an hour
$time = date('Hi', $myRoundedTime);
echo $time;
A working example: http://sandbox.onlinephpfunctions.com/code/b2b595683d9adf8e5273cbdef775bf69b6c036d4
A simple if statement should do the trick
$hour = date('H');
if($minutesround == 60) {
$minutesround = 0;
$hour++;
if($hour == 24) $hour = '00';
}

PHP Check if current time is before specified time

I need to check in PHP if the current time is before 2pm that day.
I've done this with strtotime on dates before, however this time it's with a time only, so obviously at 0.00 each day the time will reset, and the boolean will reset from false to true.
if (current_time < 2pm) {
// do this
}
if (date('H') < 14) {
$pre2pm = true;
}
For more information about the date function please see the PHP manual. I have used the following time formatter:
H = 24-hour format of an hour (00 to 23)
Try:
if(date("Hi") < "1400") {
}
See: http://php.net/manual/en/function.date.php
H 24-hour format of an hour with leading zeros 00 through 23
i Minutes with leading zeros 00 to 59
You could just pass in the time
if (time() < strtotime('2 pm')) {
//not yet 2 pm
}
Or pass in the date explicitly as well
if (time() < strtotime('2 pm ' . date('d-m-Y'))) {
//not yet 2 pm
}
Use 24 hour time to get round the problem like so:
$time = 1400;
$current_time = (int) date('Hi');
if($current_time < $time) {
// do stuff
}
So 2PM equates to 14:00 in 24 hour time. If we remove the colon from the time then we can evaluate it as an integer in our comparison.
For more information about the date function please see the PHP manual. I have used the following time formatters:
H = 24-hour format of an hour (00 to 23)
i = Minutes with leading zeros (00 to 59)
You haven't told us which version of PHP you're running, although, assuming it's PHP 5.2.2+ than you should be able do it like:
$now = new DateTime();
$twoPm = new DateTime();
$twoPm->setTime(14,0); // 2:00 PM
then just ask:
if ( $now < $twoPm ){ // such comparison exists in PHP >= 5.2.2
// do this
}
otherwise, if you're using one of older version (say, 5.0) this should do the trick (and is much simplier):
$now = time();
$twoPm = mktime(14); // first argument is HOUR
if ( $now < $twoPm ){
// do this
}
If you want to check whether the time is before 2.30 pm ,you can try the following code segment .
if (date('H') < 14.30) {
$pre2pm = true;
}else{
$pre2pm = false;
}
Try with
if( time() < mktime(14, 0, 0, date("n"), date("j"), date("Y")) ) {
// do this
}
This function will check if it's between hours in EST by accepting 2 params, arrays with the hour and am/pm...
/**
* Check if between hours array(12,'pm'), array(2,'pm')
*/
function is_between_hours($h1 = array(), $h2 = array())
{
date_default_timezone_set('US/Eastern');
$est_hour = date('H');
$h1 = ($h1[1] == 'am') ? $h1[0] : $h1[0]+12;
$h1 = ($h1 === 24) ? 12 : $h1;
$h2 = ($h2[1] == 'am') ? $h2[0] : $h2[0]+12;
$h2 = ($h2 === 24) ? 12 : $h2;
if ( $est_hour >= $h1 && $est_hour <= ($h2-1) )
return true;
return false;
}
Use time(), date() and strtotime() functions:
if(time() > strtotime(date('Y-m-d').' 14:00') {
//...
}

Easy way to get day number of current quarter?

PHP provides ways to get the number of the current day of the month (date('j')) as well as the number of the current day of the year (date('z')). Is there a way to get the number of the current day of the current quarter?
So right now, August 5, it is day 36 of the third quarter.
If there is no standard way of calculating this, does anyone have a (prefereably PHP-based) algorithm handy?
How about:
$curMonth = date("m", time());
$curQuarter = ceil($curMonth/3);
I wrote a class with the following methods. Enjoy.
public static function getQuarterByMonth($monthNumber) {
return floor(($monthNumber - 1) / 3) + 1;
}
public static function getQuarterDay($monthNumber, $dayNumber, $yearNumber) {
$quarterDayNumber = 0;
$dayCountByMonth = array();
$startMonthNumber = ((self::getQuarterByMonth($monthNumber) - 1) * 3) + 1;
// Calculate the number of days in each month.
for ($i=1; $i<=12; $i++) {
$dayCountByMonth[$i] = date("t", strtotime($yearNumber . "-" . $i . "-01"));
}
for ($i=$startMonthNumber; $i<=$monthNumber-1; $i++) {
$quarterDayNumber += $dayCountByMonth[$i];
}
$quarterDayNumber += $dayNumber;
return $quarterDayNumber;
}
public static function getCurrentQuarterDay() {
return self::getQuarterDay(date('n'), date('j'), date('Y'));
}
function date_quarter()
{
return ceil(date('n', time()) / 3);
}
or
function date_quarter()
{
$month = date('n');
if ($month <= 3) return 1;
if ($month <= 6) return 2;
if ($month <= 9) return 3;
return 4;
}
You can use Carbon it has easy modifiers for getFirstOf{Month,Year,Quarter}()
<?php
//take current date
$now = Carbon\Carbon::now();
//modify a copy of it to the first day of the current quarter
$firstOfQuarter = $now->copy()->firstOfQuarter();
//calculate the difference in days and add 1 to correct the index
$dayOfQuarter = $now->diffInDays($firstOfQuarter) + 1;
Assuming you mean a calendar-quarter (because a company fiscal year can start in any month of the year), you could rely on the date('z') to determine the day-of-year, and then keep a simple array of the day each quarter starts on:
$quarterStartDays = array( 1 /* Jan 1 */, 90 /* Mar 1, non leap-year */, ... );
Then with the current day-of-year you can first locate the largest start-day that's less than or equal to the day-of-year, then subtract.
Note that you need different numbers depending on the leap year.
<?php
function day_of_quarter($ts=null) {
if( is_null($ts) ) $ts=time();
$d=date('d', $ts);
$m=date('m', $ts)-1;
while($m%3!=0) {
$lastmonth=mktime(0, 0, 0, $m, date("d", $ts), date("Y",$ts));
$d += date('t', $lastmonth);
$m--;
}
return $d;
}
echo day_of_quarter(mktime(0, 0, 0, 1, 1,2009));
echo "\n";
echo day_of_quarter(time());
echo "\n";
?>
We need to calculate the date of the first quarter first
$current_month = date('m');
// Get first month of quarter
$new_month = (3 * floor(($current_month - 1 ) / 3)) + 1;
// Add prefix zero if needed
$new_month = substr('0' . $new_month, -2);
$first_quarter_day_date = date('Y') . '-' . $new_month . '-01';
next we calculate the http://php.net/manual/en/datetime.diff.php
$datetime1 = new DateTime($first_quarter_day_date);
$datetime2 = new DateTime();
$interval = $datetime1->diff($datetime2);
echo $interval->format('%a days');
<?php
function quarter_day($time = "") {
$time = $time ? strtotime($time) : time();
$date = intval(date("j", $time));
$month = intval(date("n", $time));
$year = intval(date("Y", $time));
// get selected quarter as number between 1 and 4
$quarter = ceil($month / 3);
// get first month of current quarter as number between 1 and 12
$fmonth = $quarter + (($quarter - 1) * 2);
// map days in a year by month
$map = [31,28,31,30,31,30,31,31,30,31,30,31];
// check if year is leap
if (((($year % 4) == 0) && ((($year % 100) != 0) || (($year % 400) == 0)))) $map[1] = 29;
// get total number of days in selected quarter, by summing the relative portion of $map array
$total = array_sum(array_slice($map, ($fmonth - 1), 3));
// get number of days passed in selected quarter, by summing the relative portion of $map array
$map[$month-1] = $date;
$day = array_sum(array_slice($map, ($fmonth - 1), ($month - $fmonth + 1)));
return "Day $day on $total of quarter $quarter, $year.";
}
print(quarter_day("2017-01-01")) . "\n"; // prints Day 1 on 90 of quarter 1, 2017.
print(quarter_day("2017-04-01")) . "\n"; // prints Day 1 on 91 of quarter 2, 2017.
print(quarter_day("2017-08-15")) . "\n"; // prints Day 46 on 92 of quarter 3, 2017.
print(quarter_day("2017-12-31")) . "\n"; // prints Day 92 on 92 of quarter 4, 2017.
I've noticed that this thread went a bit beyond the question, and it's the first response to many google searches with "Quarter" & "PHP" in them.
If you're working with the ISO standards of organization, which you should if you're doing a business app, then
$curMonth = date("m", time());
$curQuarter = ceil($curMonth/3);
Is NOT correct, because the first day of a year in the ISO standards, can be 30, or 31 December.
Instead, you should use this :
$current_yearly_cycle_year_number = 2019;
$current_yearly_cycle_start->setISODate( $current_yearly_cycle_year_number, 1, 1 );
$current_yearly_cycle_end->setISODate( $current_yearly_cycle_year_number, 53, 1 );
if( $current_yearly_cycle_end->format("W") !== "53" )
$current_yearly_cycle_end->setISODate( $current_yearly_cycle_year_number, 52, 1 );
$week_number_start = intval( $current_yearly_cycle_start->format( "W" ) );
$timestamp_start_quarter = ( $week_number_start === 1 ? 1 : intval( ceil( $current_yearly_cycle_start->format( "m" ) / 3 ) ) );
var_dump( $timestamp_start_quarter );

Categories