I've tried building and placing the while loop in different ways and different locations and looking at $val as the right/wrong variable to be placing in the while loop but I'm just not getting it. I expected output to be: 815 830 845 900....... until reaching 1900.
Instead I got 815 then 1915 1930 1945 up through 0000 then it cycles over starting at 1915. Someone please tell me what i have placed in the wrong location or what variable I've used wrongly.
date_default_timezone_set('America/New_York');
$st='800';
$et='1900';
$frac = 900;
$x = $et;
$val=0;
if (strlen($st) < 4) {$st = "0".$st;}
$current_time = strtotime(date($st));
$r = $current_time % $frac;
$new_time = $current_time + ($frac-$r);
$val = date('Gi', $new_time);
echo $val."<br>";
while ($val !== $et){
if (strlen($val) < 4) {$st = "0".$val;}
$current_time = strtotime('+ 15 minutes',date($val));
$r = $current_time % $frac;
$new_time = $current_time + ($frac-$r);
$val = date('Gi', $new_time);
echo $val."<br>";
}
NOTE TO THE - MARKDOWN PLAYERS -- Edited POST ANSWER: You can bash the question all you want, but the fact is it was a clear question, clear objective trying to be reached and it was a clear attempt (one of several) to code it properly that failed, so bad code, not bad effort. So eventually I asked for help. Your using the markdown system the wrong way and for the wrong reason, but whatever I have little expectation that you care. Thanks to those that made the effort actually be constructive and teach/help.
With unelegant for loop:
for ($i = 800, $t= 1900; $i <= $t; $i += 15) {
printf('%1$3d <br>', $i);
if ($i%100 >= 45) $i += 40;
}
With DatePeriod:
$timezone = new DateTimeZone("America/New_York");
$begin = new DateTime("now", $timezone);
$begin->setTime(8, 0, 0);
$end = new DateTime("now", $timezone);
$end->setTime(19, 0, 0);
$interval = new DateInterval('PT15M');
$end->add($interval);
$daterange = new DatePeriod($begin, $interval ,$end);
foreach($daterange as $date){
echo $date->format("Gi") . "<br>";
}
With generators:
function xmins($start, $end, $step = 15) {
if ($start < $end) {
if (($step <= 0) || ($step >= 40)) {
throw new LogicException('Step must be in range 1-40');
}
for ($i = $start; $i <= $end; $i += $step) {
if (60 <= $temp = $i % 100) {
$i += 40;
}
yield $i;
if ((60-$step) === $temp = $i % 100) {
$i += 100 - $temp - $step;
}
}
}
}
foreach (xmins(800,1900,15) as $i) {
printf('%1$3d<br>', $i);
}
Using DateInterval:
$date = new DateTime('2015-01-01 08:00:00');
$mins = new DateInterval('PT15M');
do {
$date->add($mins);
echo $date->format('Hi')."\n";
} while($date->format('Hi') < 1900);
Related
There is an array of working hours, how to exclude lunch time from it?
$start = strtotime('8:00');
$end = strtotime('18:00');
$step = 1800; // 30 min
for($i = $start; $i <= $end; $i += $step)
{
$arTime[] = date('H:i', $i);
}
print_r($arTime);
A class that allows easy creation / manipulation / comparison of date and time, you can use DateTime to create the desired array.
Set a time-interval that is to be excluded from your results array using $lunchStart and $lunchStop.
$start = new DateTime('8:00');
$end = new DateTime('18:00');
$lunchStart = new DateTime('13:00');
$lunchStop = new DateTime('14:00');
while ($start <= $end) {
$slot = $start->format('H:i');
if ($start <= $lunchStart || $start >= $lunchStop) {
$arTime[] = $slot;
}
$start->add(new DateInterval('PT30M')); // 30 min interval
}
working demo
This is the code I am trying but it stops some time as now the value of i = 21 which is not <= 2. What should be the solution?
$pdts = array();
for($i = ltrim(date('H'), '0'); $i <= ltrim(date('H', time() + 14400), '0') * 2; $i++) {
for ($j = 15; $j <= 45; $j += 15) {
if ($j > ltrim(date('i'), '0') && ltrim(date('H'), '0') == $i) {
$date = date("H.i", strtotime("$i:$j"));
$value = $date."h";
$pdts[$value] = $date;
}
}
if (ltrim(date('i'), '0') != 0 && ltrim(date('H'), '0') != $i) {
$date = date("H.i", strtotime("$i:00"));
$value = $date."h";
$pdts[$value] = $date;
}
for ($k = 15; $k <= 45; $k += 15) {
if (ltrim(date('H'), '0') != $i) {
$date = date("H.i", strtotime("$i:$k"));
$value = $date . "h";
$pdts[$value] = $date;
}
}
}
As far as I understand you're trying to get 15-minutes chunks for the next 4 hours. There is built-in PHP DateTime / DateInterval / DatePeriod classes just for that. You can use them like that:
// current time - beginning of chunks
$begin = new DateTime();
// adjust $begin time for next '15/30/45/00' chunk
$next = $begin->format("i") % 15;
if ($next !== 0) {
$begin->modify('+' . (15 - $next) . 'minutes');
}
// time of last chunk
$end = clone $begin;
$end->modify("+4 hours");
// chunk interval (15 minutes)
$interval = new DateInterval('PT15M');
// date / time period onject
$timeRange = new DatePeriod($begin, $interval, $end);
$pdts = array();
foreach($timeRange as $time){
$pdts[] = $time->format("H:i");
}
Few words about code above:
1.Get current date & time. Current time is the beggining of time period to generate 15-minutes chuncks:
$begin = new DateTime();
2.Adjust current time to one of the 15-minutes chuncks. The easiest way to do it is to devide current amount of minutes by 15. If the reminder of devision is zero - than current time is OK and we can start from it. Otherwise we need to add (15 - reminder) minutes to current time to get valid start time:
$next = $begin->format("i") % 15;
if ($next !== 0) {
$begin->modify('+' . (15 - $next) . 'minutes');
}
3.To get end time of time period we need to add 4 hours to start time:
$end = clone $begin;
$end->modify("+4 hours");
4.We need to create time interval object with chunk duration:
$interval = new DateInterval('PT15M');
5.Create date period object (it will do all job for us)
$timeRange = new DatePeriod($begin, $interval, $end);
6.Iterate through date period object to gett all chunks
$pdts = array();
foreach($timeRange as $time){
$pdts[] = $time->format("H:i");
}
I want a PHP for loop that goes to certain number say "23" and again starts from "0".
Actually I want for the listing of time in 24 hours format and suppose a case is: I have to show time from 9 AM to 2 AM (i.e 9,10,11,12,13,14,...........23,0,1,2)
$i= range(0,23);//it doest work as it creates an array containing a range of elements
$start_time = 9;
$end_time = 2;
for ($i = $start_time ; $i<= $end_time ; $i++)
{
echo $i;
}
Please suggest a way.
Since your use-case mentions time-sensitive information you might be best off learning to use the date and strtotime functions (or the DateTime classes):
$time = strtotime('2013-09-14 02:00');
$endTime = strtotime('2013-09-15 09:00');
while ($time <= $endTime) {
echo date('Y-m-d H:i:s', $time)."\n";
$time = strtotime('+1 hour', $time);
}
// 2013-09-14 02:00:00
// 2013-09-14 03:00:00
// 2013-09-14 04:00:00
// 2013-09-14 05:00:00
// etc.
$start_time = 9;
$end_time = 2;
$end_time += ($end_time < $start_time) ? 24 : 0;
for ($i = $start_time; $i<= $end_time; $i++) {
echo ($i % 24);
}
Reason, the line $end_time += ($end_time < $start_time) ? 24 : 0; checks to see if the end time is less than the start time (which we assume means the next day), and if it is, it adds 24 hours to it. The line $i %24 is the modulus operator which will divide the number and give the remainder, so if it's 25, it will give you 1 back. Note that all hours being worked with will need to be in 24 hour format to use this method.
You can use the modulo to deduct 24 from numbers when they're greater than 23.
$start_time = 9;
$end_time = 2;
for( $i = $start_time; $i % 24 != $end_time; $i++ )
{
echo $i % 24;
}
Note that you need to be careful with this; if $end_time is greater than 23 it will be stuck in an infinite loop.
Try this its working
<?php
$i= range(0,23);//it doest work as it creates an array containing a range of elements
$start_time = 9;
$end_time = 2;
$max_value=23;
if($start_time>=$end_time)
{
for ($i = $start_time ; $i<= $max_value; $i++)
{
echo $i;
}
for($i=0; $i<=$end_time; $i++)
{
echo $i;
}
}
else
{
for ($i = $start_time ; $i<= $max_value; $i++)
{
echo $i;
}
}
?>
Again late to Answer , Try this
<?php
$start_time = 20;
$end_time = 10;
$maxTime=23;
$minTime=0;
for ($i = $minTime ; $i<=$maxTime - abs($start_time-$end_time) ; $i++)
{
$validTime= $start_time + ($i % $maxTime);
$validTime= $validTime>$maxTime?$validTime-$maxTime:$validTime;
echo $validTime;
}
?>
Check this out. Hope this helps
$start_time = 9;
$end_time = 2;
$flag = 1;
while($flag) [
echo $start_time . "<br>";
$start_time++;
if ($start_time == 23) { $start_time = 0; }
if ($start_time == $end_time) {
$flag = 0;
}
}
Does it have to be a for loop?
You can try this
function hours($range, $recurse = true, $end = array())
{
foreach($range as $time)
{
echo $time . "\n";
}
if($recurse && sizeof($end) > 0)
{
$range = range($end['start'], $end['end']);
hours($range, false);
}
}
$range = range(9,23);
$end = array('start' => 0, 'end' => 2);
hours($range, true, $end);
Maybe better to use date:
$hours = 8;
for ($i=1; $i<=8; $i++){
echo 'TIME1 = '.date("Y-m-d H:i:s",mktime (20+$i,15,18,06,05,2013)).'<br>';
}
or better DateTime class:
$date = DateTime::createFromFormat('Y-m-d H:i:s', '2013-06-05 20:15:18');
$hours = 8;
for ($i=0; $i<8; $i++){
$date->add(new DateInterval('PT1H'));
echo 'TIME2 = '.$date->format('Y-m-d H:i:s').'<br>';
}
Thanks everybody for your help, using your ideas I got my work done.
Here is the code that actually worked.
$start_time = some_dynamic_value;
$end_time = some_dynamic_value;
$i= $start_time;
$flag = false;
if($start_time > $end_time)
$flag = true;
while ($i <= $end_time || $flag)
{
echo $i;
if($i == 24)
{
$i= 0;
$flag = false;
}
$i++;
}
I need to get an array of time slots in a day, i.e. 24 hours. Something like:
array (
00:00=>00:00,
00:05=>00:05,
00:10=>00:10,
.................
21:05=>21:05,
.....
23:55=>23:55,
24:00=>24:00
)
I want to get this as a function return value with 5 minute intervals. Sorry for my bad English.
No need for a date function:
$result = array();
for ($n = 0; $n < 24 * 60; $n+=5)
{
$date = sprintf('%02d:%02d', $n / 60, $n % 60);
$result[$date] = $date;
}
BTW: There's no such thing as 24:00 hours.
$result = array();
for ($i = 0; $i < 24; $i++) {
for ($j = 0; $j < 60; $j+=5) {
$time = sprintf('%02d', $i) . ':' . sprintf('%02d', $j);
$result[$time] = $time;
}
}
You know when it's late in the night and your brain is fried? I'm having one of those nights right now, and my function so far is not working as it should, so please take a look at it:
(I should note that I'm using the PHP 5.2.9, and the function / method DateTime:Diff() is not available until PHP 5.3.0.
<?php
function time_diff($ts1, $ts2) {
# Find The Bigger Number
if ($ts1 == $ts2) {
return '0 Seconds';
} else if ($ts1 > $ts2) {
$large = $ts1;
$small = $ts2;
} else {
$small = $ts1;
$large = $ts2;
}
# Get the Diffrence
$diff = $large - $small;
# Setup The Scope of Time
$s = 1; $ss = 0;
$m = $s * 60; $ms = 0;
$h = $m * 60; $hs = 0;
$d = $h * 24; $ds = 0;
$n = $d * 31; $ns = 0;
$y = $n * 365; $ys = 0;
# Find the Scope
while (($diff - $y) > 0) { $ys++; $diff -= $y; }
while (($diff - $n) > 0) { $ms++; $diff -= $n; }
while (($diff - $d) > 0) { $ds++; $diff -= $d; }
while (($diff - $h) > 0) { $hs++; $diff -= $h; }
while (($diff - $m) > 0) { $ms++; $diff -= $m; }
while (($diff - $s) > 0) { $ss++; $diff -= $s; }
# Print the Results
return "$ys Years, $ns Months, $ds Days, $hs Hours, $ms Minutes & $ss Seconds.";
}
// Test the Function:
ediff(strtotime('December 16, 1988'), time());
# Output Should be:
# 20 Years, 11 Months, 8 Days, X Hours, Y Minutes & Z Seconds.
?>
This isn't an answer to your question, but I just wanted to point out...
while (($diff - $y) > 0) { $ys++; $diff -= $y; }
is a very inefficient way of writing
$ys = $diff / $y;
$diff = $diff % $y;
Also, this
else if ($ts1 > $ts2) {
$large = $ts1;
$small = $ts2;
} else {
$small = $ts1;
$large = $ts2;
}
# Get the Diffrence
$diff = $large - $small;
can easily be rewritten as
$diff = abs($ts1 - $ts2);
I have a feeling that the problem in your code would be more apparent if it was less verbose. :)
how about simplifying the first part with a simple
$diff = abs($ts2 - $ts1);
Then, when you do this:
$n = $d * 31; $ns = 0;
$y = $n * 365; $ys = 0;
you are actually saying that a year is composed of 365 31 day long months. which is actually about 36 year long years. Probably not what you want.
Finally, we are all grown ups here. Please use grown up variable names i.e. $YEAR_IN_SECONDS instead of $ys. As you can clearly see, you may write code once, but 20 other schmucks are going to have to read it a lot of times.
In the case of needed all months during the given times-stamp then we have use of the following coding in php :
function MonthsBetweenTimeStamp($t1, $t2) {
$monthsYear = array();
$lastYearMonth = strtotime(gmdate('F-Y', $t2));
$startYearMonth = strtotime(gmdate('F-Y', $t1));
while ($startYearMonth < $lastYearMonth) {
$monthsYear[] = gmdate("F-Y", $startYearMonth);
//Increment of one month directly
$startYearMonth = strtotime(gmdate("F-Y", $startYearMonth) . ' + 1 month');
}
if (empty($monthsYear)) {
$monthsYear = array($startYearMonth));
}
return $monthsYear;
How about this:
function time_diff($t1, $t2)
{
$totalSeconds = abs($t1-$t2);
$date = getdate($totalSeconds);
$firstYear = getdate(0);
$years = $date['year']-$firstYear['year'];
$months = $date['mon'];
$days = $date['mday'];
$hours = $date['hour'];
$minutes = $date['minutes'];
$seconds = $date['seconds'];
return "$years Years, $months Months, $days Days, $hours Hours, $minutes Minutes & $seconds Seconds.";
}
This uses the difference of the given times as a date. Then you can let the "getdate" do all the work for you. The only challenge is the number years - which is simply the getdate year (of the difference) minus the Unix epoch year (1970).
If you don't like using an actual month, you could also divide the "year" day by the number of days in 12 equal months
$months = $date['yday'] / (365/12);
Similarly days could be figured out the remaining days with modulus
$days = $date['yday'] % (365/12);