loop with time math is incorrectly showing AM/PM - php

In this case hours_start will be 08:00:00 and hours_end will be 14:00:00
here's the code i'm using to generate a list of 30 minute time slots between start and end
while($row = $q->fetch()){
$hours = $row['hours_end'] - $row['hours_start']; //amount of hours working in day
for($i = 0; $i < $hours * 2; $i++){ // double hours for 30 minute increments
$minutes_to_add = 1800 * $i; // add 30 - 60 - 90 etc.
$timeslot = date('h:i:s', strtotime($row['hours_start'])+$minutes_to_add);
echo "
<tr>
<td>" . date('h:i A', strtotime($timeslot)) . "</td>
</tr>";
}
}
this is producing:
08:00 AM
08:30 AM
09:00 AM
09:30 AM
10:00 AM
10:30 AM
11:00 AM
11:30 AM
12:00 PM
12:30 PM
01:00 AM
01:30 AM
as you can see, it is functioning as (i) expected until it gets to (what should be) 1 PM then it switches back to AM. not sure whats going on here.

Its because you are setting $timeslot using h which is only a 12 hour format without appending am or pm. Then taking that 12 hour format and running it through strtotime which expects 24 hour format if am or pm is not present. Hence anything after 12 becomes am again.
You need to use:
$timeslot = date('H:i:s', strtotime($row['hours_start'])+$minutes_to_add);
OR
$timeslot = date('h:i:s a', strtotime($row['hours_start'])+$minutes_to_add);

Your date format is using h instead of H. The lowercase h is 12 hour format
Use a capital H instead for 24 hours.
date('H:i A', strtotime($timeslot))

Related

PHP strtotime is missing a day during leap year

I'm trying to generate a list of consecutive date periods by using strtotime to add 13 days to the first date like this:
$start = strtotime(date('2020-06-01'));
for($x = 1; $x<=10; $x++) // increment $x until 10
{
$period = $start - ($x * 1209600); // 1209600 is equivalent to 14 days. Multiply by $x
$period_end = date('Y-m-d', strtotime(date('Y-m-d', $period). ' + 13 days'));
echo date('Y-m-d', $period) . " - " . $period_end ."<br>";
}
The output looks like this:
2020-05-18 - 20-05-31
2020-05-04 - 20-05-17
2020-04-20 - 20-05-03
2020-04-06 - 20-04-19
2020-03-23 - 20-04-05
2020-03-09 - 20-03-22
2020-02-23 - 20-03-07
2020-02-09 - 20-02-22
2020-01-26 - 20-02-08
2020-01-12 - 20-01-25
Everything works as expected until it hits the '2020-02-23 - 20-03-07' range. It should report '2020-02-24 - 2020-03-08'
Why the shift by 1 day? Is this a bug in PHP strtotime in relation to a leap year?
Edit: This was not a leap year issue. It turned out to be a daylight savings time issue in my timezone. When DST occurred on 3/8 the time in seconds from epoch changed by an hour. This shifted my date to 1 hour earlier which ends up being a previous day.
If we add H:i to your date()'s it all becomes clear.
$start = strtotime(date('2020-06-01'));
for($x = 1; $x<=10; $x++) // increment $x until 10
{
$period = $start - ($x * 1209600); // 1209600 is equivalent to 14 days. Multiply by $x
$period_end = date('Y-m-d H:i', strtotime(date('Y-m-d H:i', $period). ' + 13 days'));
echo date('Y-m-d H:i', $period) . " - " . $period_end ."<br>\n";
}
Output:
2020-05-18 00:00 - 2020-05-31 00:00<br>
2020-05-04 00:00 - 2020-05-17 00:00<br>
2020-04-20 00:00 - 2020-05-03 00:00<br>
2020-04-06 00:00 - 2020-04-19 00:00<br>
2020-03-22 23:00 - 2020-04-04 23:00<br>
2020-03-08 23:00 - 2020-03-21 23:00<br>
2020-02-23 23:00 - 2020-03-07 23:00<br>
2020-02-09 23:00 - 2020-02-22 23:00<br>
2020-01-26 23:00 - 2020-02-08 23:00<br>
2020-01-12 23:00 - 2020-01-25 23:00<br>
r3mainer comment is correct. Add 12:00 to the start and the problem will go away.
Because of the daylight savings you remove one hour too much, it's not the leap year.
$start = strtotime(date('2020-06-01 12:00'));
https://3v4l.org/Uj2CA

Php Date Function with complexity

My question: if the date is on Monday then my timer should start from 8:30 am and should calculate the time difference from 8:30 till date assigned, in this case its 2017-06-02 14:20:00 for first one. So time difference should be 5 hours 50 min.
Second case, date created on 2017-06-02 09:50:00 and date assigned is: 2017-06-03 13:20:00. SO it should calculate from 9:50 till 9:00pm and again start from 8:30 till 13:20:00 (if next day lies on mon-sat. If next day is sun then timer should calculate from 11am till 1:20pm. and should give me duration in hours and minutes.
How would I do that? Its in Php & MySQL. I am not any frameworks or CMS systems. Its native php.
My Data:
Date Created: 2017-06-02 02:50:00
Date Assigned: 2017-06-02 14:20:00
Date Created: 2017-06-02 09:50:00
Date Assigned: 2017-06-03 13:20:00
Mon - Sat = 8:30am - 9:00pm
Sunday = 11am - 5pm
Thank you in advance.
Edited: This function checks first what day is your dateassigned, then calculates the time difference based on your criteria.
<?php
echo getTimeLapsedCustom('2017-06-02 14:20:00') . "<br>";
echo getTimeLapsedCustom('2017-06-03 13:20:00') . "<br>";
function getTimeLapsedCustom($time){
$timecreated = '';
$timeassigned = $time;
$datetime2 = DateTime::createFromFormat('Y-m-d H:i:s', $timeassigned);
if($datetime2->format('D') === 'Sun'){
$timecreated = $datetime2->format('Y-m-d') . ' 11:00:00';
}else{
$timecreated = $datetime2->format('Y-m-d') . ' 08:30:00';
}
$datetime1 = DateTime::createFromFormat('Y-m-d H:i:s', $timecreated);
$interval = $datetime1->diff($datetime2);
return $interval->format('%h hours %i min');
}
Results:
5 hours 50 min
4 hours 50 min

How to calculate time in php

help me in calculating exact time with AM and PM
$time1 = strtotime(10:00); /// in pm
$time1 = strtotime(08:00); ///// answer should come in am calculation
is exact but not the am pm value
$count = date ('g:i ' ,strtotime($time1 . '+' . $time2));
My Problem is if i calculate time i calculate it correctly as i want but how can i set the PM and AM to time if i take 10:00 PM time add 4 hour to it now time is 02:00 AM how to get that AM PM value with time and any help with subtract time how we subtract time
Use DateTime to deal with Dates and Times with less hassle.
<?php
$time = new DateTime("10am"); // assumes 10am today
$time->modify("+4 hours");
echo $time->format("g:i A"); // outputs 2:00 PM
See the DateTime book by the author of the DateTime extension.
All you need is:
$t1 = strtotime('10am'); // 1399910400 on the date this was written
$t2 = strtotime('8am'); // 1399903200 on the date this was written
But note that that you CANNOT just do $t1 + $t2. You'll actually be doing
$t3 = 1399910400 + 1399903200
$t3 = 2799813600
And the timestamp 2799813600 corresponds to Sep 21, 2058.
You need to do:
'8am' + 2 hours => '10am';
which is
$t3 = strtotime('8am') + 60 * 60 * 2;
^^^^^^^^^^^---2hours

PHP strtotime is wrong (some times)?

I have this issue with strtotime in my PHP code that it is wrong sometimes (only for some timezones) and it is correct for others!!
I cannot get my head around it.
I have set the <?php date_default_timezone_set('GMT'); ?> at the top of my page as well but that doesn't help!
basically what it does is that it will add or subtract the offset/3600 value to the set time in $time1 = strtotime('00:00'); depending on the if and else if conditions.
the offset/3660 value is the time difference between two timezones!
the code bellow works for some locations and it doesn't for others! basically it will add an extra 1-2 hours or takes off/subtract an extra 1-2 hours some times (not all the time).
i.e. the time difference between Abidjan and london is -1.
the time (value) that should be shown is 23:00 as 00:00 - 01:00 = 23:00. but the value is shown is 00:00.
However as i mentioned it works for some timezones.
i.e. for the time difference between New York and London which is -5 the code works and it shows 19:00 as 00:00 - 05:00 = 19:00
could someone please shed a light on this?
here is the code in question:
<?php
$time1 = strtotime('00:00');
if (0 > $offset)
{
// For negative offset (hours behind)
$hour_dif = date('H:i', strtotime($time1 -$offset/3600));
$time1 = "{$hour_dif}";
}
elseif (0 < $offset)
{
// For positive offset (hours ahead)
$hour_dif = date('H:i', strtotime($time1 +$offset/3600));
$time1 = "{$hour_dif}";
}
else
{
// For offsets in the same timezone.
$time1 = "in the same timezone";
}
echo "{$time1}";
?>
Well, since strtotime() already returns a timestamp and date() expects one you could just do
$hour_dif = date('H:i', ($time1 - ($offset*3600)));
or
$hour_dif = date('H:i', ($time1 + ($offset*3600)));
respectively, to remove or add the correct amount of seconds from/to the timestamp.
I am also assuming that $offset is the offset in hours, so you would have to multiply by 3600 to get the amount of seconds, not divide.
Alright, after testing your code and thinking through it some more, it became obvious.
With a negative offset like -1 you're going to calculate $time1 - (-1) * 3600 and we all know that a double negation is positive...
So in fact, your code can be condensed to:
$time1 = strtotime('00:00');
if ($offset == 0)
$time1 = "in the same timezone";
else
{
// For positive offset (hours ahead)
$hour_dif = date('H:i', ($time1 + ($offset*3600)));
$time1 = "{$hour_dif}";
}
echo "{$time1}\n";
and should work as expected:
cobra#box ~ $ for i in {-24..24}; do php test.php $i; done;
00:00
01:00
02:00
03:00
04:00
05:00
06:00
07:00
08:00
09:00
10:00
11:00
12:00
13:00
14:00
15:00
16:00
17:00
18:00
19:00
20:00
21:00
22:00
23:00
in the same timezone
01:00
02:00
03:00
04:00
05:00
06:00
07:00
08:00
09:00
10:00
11:00
12:00
13:00
14:00
15:00
16:00
17:00
18:00
19:00
20:00
21:00
22:00
23:00
00:00

Print time in 15-minute increments between two times in the same day

I'm trying to make a loop that will output this:
08:00
08:15
08:30
08:45
09:00
09:15
09:30
09:45
...etc
I need it to go from 08:00 to 17:00.
Here's my code so far:
function echo_datelist ($i, $j, $day, $month, $year)
{
$time = str_pad($i, 2, '0', STR_PAD_LEFT).':'.str_pad($j, 2, '0', STR_PAD_LEFT);
$date = strtotime("$month $day $year $time:00");
$sql = mysql_query("select b.room_type, c.name from bookings as b, customers as c where b.the_date='$date' and b.id_customer=c.id");
echo $time.'<br />';
}
for ($i = 8; $i <= 16; $i++)
{
for ($j = 0; $j <= 45; $j+=15)
echo_datelist($i, $j, $day, $month, $year);
echo_datelist(17, 0, $day, $month, $year);
}
The problem is, it is outputting a 17:00 in between each hour, example:
08:00
08:15
08:30
08:45
17:00
09:00
09:15
09:30
09:45
17:00
p.s. I know I shouldn't be making iterated trips to the database, but I'll solve that problem after this one.
it can also be done with the range function
<?php
date_default_timezone_set("Europe/London");
$range=range(strtotime("08:00"),strtotime("17:00"),15*60);
foreach($range as $time){
echo date("H:i",$time)."\n";
}
?>
so you don't have a loop, it just makes an array for you (my loop is just to print it out whilst formatting it)
Looks unnecessarily complicated to me. The following will print out what you want. Presumably it can be adapted for use in your code. Sorry about the messy end-condition.
$min=array("00","15","30","45");
for($i=8;$i<17;$i++)
foreach ($min as $v)
print "$i:$v\n";
print "17:00\n";
Or, if you want to do this in a slightly more opaque way...
for($i=8*60;$i<=17*60;$i+=15)
print floor($i/60) . ":" . ($i/60-floor($i/60))*60 . "\n";
The above calculates a minutes value for 8 o'clock and then adds fifteen minutes repeatedly. You then use some math to extract hours and minutes from the running variable.
my simple logic here
$start=strtotime('00:00');
$end=strtotime('23:30');
for ($i=$start;$i<=$end;$i = $i + 15*60)
{
//write your if conditions and implement your logic here
echo date('g:i A',$i).'<br>';
}
in loop you can play what you want
You need to move the last line outside of the outer for loop.
for ($i = 8; $i <= 16; $i++){
for ($j = 0; $j <= 45; $j+=15){
//inside the inner loop
echo_datelist($i, $j, $day, $month, $year);
}
//inside the outer loop
}
//outside the outer loop
echo_datelist(17, 0, $day, $month, $year);
In plain terms, you are saying:
For each hour between 8 and 16
For each 15 minute interval
Echo the time
End
Echo 17:00
End
Instead of:
For each hour between 8 and 16
For each 15 minute interval
Echo the time
End
End
Echo 17:00
I would consider performing your sql query for all hours of the day and then picking out the ones within the time from, otherwise you be doing an sql query for each 15 minute interval (37 queries with your sample data)
With PHP 5 >= 5.3.0 you can use DateTime::add, see: http://www.php.net/manual/de/datetime.add.php
DateInterval can be used to create a new dateinterval object for our date calculation and uses in any script. In the advance PHP object oriented style for all date & time calculations this format is useful.
Check below links:
http://php.net/manual/en/class.dateinterval.php
http://www.plus2net.com/php_tutorial/date-interval.php
echo_datelist(17, 0, $day, $month, $year);
Move that line to just after the outermost for-loop.
i was working on a similar problem, but with the start/end times being changeable.
this may need a little refinement, but i can't break it.
all you need to supply in the beginning are the date and times.
$day = "10/14/2011";
$startTime = date(strtotime($day." 16:00"));
$endTime = date(strtotime($day." 19:15"));
$timeDiff = round(($endTime - $startTime)/60/60);
$startHour = date("G", $startTime);
$endHour = $startHour + $timeDiff;
for ($i=$startHour; $i <= $endHour; $i++)
{
for ($j = 0; $j <= 45; $j+=15)
{
$time = $i.":".str_pad($j, 2, '0', STR_PAD_LEFT);
echo (date(strtotime($day." ".$time)) <= $endTime) ? date("g:i", strtotime($day." ".$time))."<br>" : "";
}
}
outputs:
4:00
4:15
4:30
4:45
5:00
5:15
5:30
5:45
6:00
6:15
6:30
6:45
7:00
7:15
Setting up a DateTime object with explicit bounds and its interval makes this process very clean. Remember to set the end time just passed what you want because the DatePeriod is "exclusive" of the end datetime.
Code: (Demo)
$period = new DatePeriod(
new DateTime('08:00:00'),
new DateInterval('PT15M'),
new DateTime('17:00:01')
);
foreach ($period as $dt) {
echo $dt->format("H:i") . "\n";
}
Output:
08:00
08:15
08:30
08:45
09:00
09:15
09:30
09:45
10:00
10:15
10:30
10:45
11:00
11:15
11:30
11:45
12:00
12:15
12:30
12:45
13:00
13:15
13:30
13:45
14:00
14:15
14:30
14:45
15:00
15:15
15:30
15:45
16:00
16:15
16:30
16:45
17:00
I came up with this which will print the time with whatever increase you want,
and you can change the time to show you 13PM or 1PM
<?php
$start=strtotime('00:00');
$end=strtotime('23:30');
$increase = 15; // How many minute to increase
for ($i=$start;$i<=$end;$i = $i + $increase*60)
{
if(date('H', $i) > 12 ){ //Here we check if the hour is bigger than 12, then we just do math -12 which will result in hour, for example 13PM which is 13-12=1PM
$hour = date('H', $i) - 12;
echo $hour.date(':i A',$i);
}else{
echo date('H:i A',$i);
}
}
?>
The Previous code result
00:00 AM
00:15 AM
00:30 AM
00:45 AM
01:00 AM
01:15 AM
01:30 AM
01:45 AM
02:00 AM
02:15 AM
02:30 AM
02:45 AM
03:00 AM
03:15 AM
03:30 AM
03:45 AM
04:00 AM
04:15 AM
04:30 AM
04:45 AM
05:00 AM
05:15 AM
05:30 AM
05:45 AM
06:00 AM
06:15 AM
06:30 AM
06:45 AM
07:00 AM
07:15 AM
07:30 AM
07:45 AM
08:00 AM
08:15 AM
08:30 AM
08:45 AM
09:00 AM
09:15 AM
09:30 AM
09:45 AM
10:00 AM
10:15 AM
10:30 AM
10:45 AM
11:00 AM
11:15 AM
11:30 AM
11:45 AM
12:00 PM
12:15 PM
12:30 PM
12:45 PM
1:00 PM
1:15 PM
1:30 PM
1:45 PM
2:00 PM
2:15 PM
2:30 PM
2:45 PM
3:00 PM
3:15 PM
3:30 PM
3:45 PM
4:00 PM
4:15 PM
4:30 PM
4:45 PM
5:00 PM
5:15 PM
5:30 PM
5:45 PM
6:00 PM
6:15 PM
6:30 PM
6:45 PM
7:00 PM
7:15 PM
7:30 PM
7:45 PM
8:00 PM
8:15 PM
8:30 PM
8:45 PM
9:00 PM
9:15 PM
9:30 PM
9:45 PM
10:00 PM
10:15 PM
10:30 PM
10:45 PM
11:00 PM
11:15 PM
11:30 PM
If you don't need the 1PM 2PM method, you can just use same code and remove the math for subtracting, by removing the if method and replace it with
echo date('H:i A',$i);

Categories