PHP Trouble with day change - php

I have this code bellow it works fine but when the time hits 24 till 1 it doesn't work. I'm not sure why.
The code I have:
<?php
$h = date('G'); //set variable $h to the hour of the day
$d = date('w'); //set variable $d to the day of the week.
$year = date('Y'); //set variable $year to the current year
//G is the date key for hours in 24 format (not 12), with no leading 0s, like 02.
// MONDAY SCHEDULE
if ($d == 1 && $h >= 0 && $h < 4) $text= 'bob';
else if ($d == 1 && $h >= 22 && $h < 23) $text= 'adam';
else if ($d == 1 && $h >= 23 && $h < 24) $text= 'tina';
else if ($d == 2 && $h < 0) $img = 'mark';
// TUESDAY SCHEDULE
if ($d == 2 && $h >= 0 && $h < 4) $text= 'alex';
else if ($d == 2 && $h >= 4 && $h < 8) $text= 'jason';
else if ($d == 3 && $h < 0) $text= 'gorge';
print $text;
?>
When it's mark's or gorge's turns it doesn't work. I would like to know how to fix it. Any help would be appreciated.
Thank you

Like stated in comments, the test on $h < 0 will always return false, as $h is an integer between 0 and 23.
But you could make your schedule more readable and manageable if you would create a data structure for it, like this:
mb_internal_encoding("UTF-8");
$persons = array(
'-' => '(no one)',
'a' => 'Bob',
'b' => 'Adam',
'c' => 'Tina',
'd' => 'Marc',
'e' => 'Alex',
'f' => 'Jason',
'g' => 'George'
);
$schedule = array(
// 012345678901234567890123
'------------------------', // Sunday
'aaaa------------------bc', // Monday
'eeeeffff----------------', // Tuesday
'------------------------', // Wednesday
'------------------------', // Thursday
'------------------------', // Friday
'------------------------', // Saturday
);
// Use mb_substr to support multi-byte characters (unicode)
print $persons[mb_substr($schedule[date('w')],date('G'),1)];
In the above code, each person gets a unique letter. That letter is used in a kind of grid, where each row represents a weekday, and each column (character position) an hour of the day (0-23).
This way you have a rather visual representation, which might be easier to manage. And as it turns out, to get the person that is scheduled for the current hour-slot just takes a single line of code.

Related

Calculate n dates of next x days of the week

so I'm trying to build a function that allows me to calculate the dates of the next x days of the week, for example, I want 5 dates from now (02/08/2022), of Tuesday and Thursday, so the output should be:
02/08/2022 - Tu
02/10/2022 - Th
02/15/2022 - Tu
02/17/2022 - Th
02/22/2022 - Tu
I'm not sure how to achieve that, since I want to be able to input various days of the week... Is there a way to do this? My current aproach is this one, but of couse, is not doing what I want, I kinda blocked right now, sorry if the answer is too obvious:
function getNextDates($start_date, $range_weeks, $how_many_dates, $days)
{
$range = 'P' . ($range_weeks * 7) . 'D';
$sd = new DateTimeImmutable($start_date);
$nd = new DateTime($start_date);
$dates_list = array();
$dates_list[0] = array('day' => $sd->format('D'), 'date' => $sd->format('d-m-Y'));
$ind = 1;
$how_many_dates--;
while ($how_many_dates > 0) {
// This in case I want a n weeks space
$nd->add(new DateInterval($range));
for ($i = 0; $i < count($days); $i++) {
if (($i + 1) < count($days)) {
if ($sd->modify($this->nextDay($days[$i])) < $sd->modify($this->nextDay($days[$i + 1]))) {
$nextDate = $nd->modify($this->nextDay($days[$i]));
$dates_list[$ind] = array('day' => $nextDate->format('D'), 'date' => $nextDate->format('d-m-Y'));
$how_many_dates--;
$ind++;
}
} else {
$nextDate = $nd->modify($this->nextDay($days[$i]));
// $sd = $nextDate;
$dates_list[$ind] = array('day' => $nextDate->format('D'), 'date' => $nextDate->format('d-m-Y'));
$how_many_dates--;
$ind++;
}
if ($how_many_dates <= 0) break;
}
}
return $dates_list;
}
Being:
$start_date: 02/08/2022
$range_weeks: 0 // Meaning every week
$how_many_dates: 5
$days: Tuesday, Thursday
I got:
02/08/2022
02/10/2022
02/17/2022
02/24/2022
03/03/2022
Sorry for my amateur code...
Starting from the start date, a day is always added and it is checked whether it is the desired day of the week.
$start = "02/08/2022";
$number = 5;
$weekDays = ['Tue','Thu'];
$dates = [];
for($date = date_create($start); $number > 0; $date->modify('+1 Day')){
$day = $date->format('D');
if(in_array($day,$weekDays)) {
$dates[] = $date->format("d/m/Y");
$number--;
}
}
Result $dates
array (
0 => "08/02/2022",
1 => "10/02/2022",
2 => "15/02/2022",
3 => "17/02/2022",
4 => "22/02/2022",
)

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 Function to show different image based on day of the month and hour of the day

I'm trying to display an image based on the day of the month and the hour of the day. Here's the php code that I found via a forum and tweaked to meet my needs
<?php
$h = date('G'); //set variable $h to the hour of the day
$d = date('d'); //set variable $d to the day of the month.
//G is the date key for hours in 24 format (not 12), with no leading 0s, like 02.
// Adjust offset code if needed $h = $h-2;
// 01 Calendar Day
if ($d = 01 && $h >= 4 && $h < 12) $img = 'img/s1.jpg'; //if day is 1st and it's between 4am and 12pm show day strength 1 image
else if ($d == 01 && $h >= 12 && $h < 2) $img = 'img/c1.jpg'; //if day is 1st and it's between 12pm and 2am show evening condition 1 image
else if ($d == 01 && $h >= 2 && $h < 4) $img = 'img/rest.jpg'; //if day is 1st and it's between 2am and 4am show rest image
?>
<img src="/<?php echo $img; ?>">
The goal is to create if/else statements for all 31 possible days in a month, where there is a morning image, an evening image, and a buffer image that displays in the late night as a buffer.
But when i check the code to see if it works I'm getting errors. Please help and also if there's a more efficient way to code this verses 31 if/else statements that would be wonderful also.
You dont need to apply day condition as your image is not changing bases on day. It is changing on time bases. So you can use something like below:
$h = date('H'); // it will return hour in 24 format.
if ($h >= 4 && $h < 12) $img = 'img/s1.jpg'; //if it's between 4am and 12pm show day strength 1 image
else if ( ($h >= 12 && $h <= 23) || ($h >= 1 && $h <= 2) ) $img = 'img/c1.jpg'; //it's between 12pm and 2am show evening condition 1 image
else if ($h >= 2 && $h < 4) $img = 'img/rest.jpg'; //if it's between 2am and 4am show rest image
You can make changes in your arithmetical operators as per your requirement. And if your image changes on day bases, you can simply add date in your image variable as below:
$h = date('H'); // it will return hour in 24 format.
$d = date('d');
if ($h >= 4 && $h < 12) $img = 'img/s'.$d.'.jpg';
else if ( ($h >= 12 && $h <= 23) || ($h >= 1 && $h <= 2) ) $img = 'img/c'.$d.'.jpg';
else if ($h >= 2 && $h < 4) $img = 'img/rest.jpg';
Hope it helps you.
Try This,
$h = date('G'); //set variable $h to the hour of the day
//G is the date key for hours in 24 format (not 12), with no leading 0s, like 02.
$d = date('d'); //set variable $d to the day of the month.
$DynamicDay = '21';
if ($DynamicDay == $d) {
switch ($h) {
case ($h >= 4 && $h < 12):
$img = 'img/s' . $d . '.jpg';
break;
case ($h >= 12 && $h < 14):
$img = 'img/c1.jpg';
break;
case ($h >= 14 && $h < 18):
$img = 'img/rest.jpg';
break;
default:
break;
}
}
echo 'Hour => '.$h.'<p>';
echo 'day => '.$d.'<p>';
echo $img;
die;
Out Put:
Hour => 10
day => 21
img/s21.jpg
Instead of multiple if/else, you can put all the rule into array for easy to maintain.
$array = [
1 => [
4 => 'img/s1.jpg',
12 => 'img/s12.jpg',
14 => 'img/s14.jpg',
],
2 => [
2 => 'img/c2.jpg'
]
];
function getDayDateImage($array, $d, $h)
{
while (!$array[$d][$h]) {
$h--;
if ($h < 0) {
$h = 23;
$d--;
}
if ($d < 1) {
return 'img/rest.jpg'; // Default
}
}
return $array[$d][$h];
}
echo getDayDateImage($array, 1, 1); // Get img/rest.jpg
echo getDayDateImage($array, 1, 13); // Get img/s12.jpg
echo getDayDateImage($array, 2, 1); // Get img/s14.jpg
echo getDayDateImage($array, 2, 4); // Get img/c2.jpg
//Just pass you $d and $h
//getDayDateImage($array, $d, $h);
Hope this help.

Pulling in data around/after midnight

Ok.. so I've created myself a messy problem.
So I have a jquery slider that shows 5 slides of content
1) -2 hours ago
2) -1 hour ago
3) (0) present
4) +1 hours
5) +2 hours
The content for each slide is decided by what time of day it is. However when it comes to trying to go back/forwards 1 to 2 hours during the run up to midnight and after midnight the whole script breaks, and kills the site.
<?php
$h = date('G', strtotime ("-2 hour")); //set variable $h to the hour of the day.
$m = date('i', strtotime ("-2 hour")); //set variable $m to the min of the hour.
$d = date('w', strtotime ("-2 hour")); //set variable $d to the day of the week.
// SATURDAY SCHEDULE
if ($d == 6 && $h >= 0 && $h < 07) $file ='earlyhours.php';
else if ($d == 6 && $h >= 07 && $h < 09) $file ='breakfast.php';
else if ($d == 6 && $h >= 09 && $h < 12) $file ='throughthemorning.php';
else if ($d == 6 && $h >= 12 && $h < 13) $file ='rewind.php';
else if ($d == 6 && $h >= 13 && $h < 17 && $m <= 30) $file ='nonstop.php';
else if ($d == 6 && $h >= 17 && $m >= 30 && $h <21) $file ='livetrend.php';
else if ($d == 6 && $h >= 17 && $m >= 35 && $h < 21) $file ='nonstop.php';
else if ($d == 6 && $h >= 21 && $h < 18) $file ='gennation.php';
else if ($d == 6 && $h >= 23) $file ='earlyhours.php';
else if ($d == 7 && $h >= 0) $file ='earlyhours.php';
require $_SERVER['DOCUMENT_ROOT'] . '/collection/profiles/' . $file . '';
?>
As you can see it figures the time and then drops the correct file in - there's five of these for everyday of the week (-2.php, -1.php, 0.php, 1.php, 2.php).
Does anybody have a solution? Ideally I need to stop the break, but I don't want my visitors to be scrolling +1 / 2 or -1 / 2 hours on for the same days rotation when it nears, and steps over midnight.
For example, right now the code is broken on -2.php until at least 2am (my timezone) so that it back track.
I've totally burnt myself out trying to figure this one out.
The problems arising from the change of day can become intractable. I'd tackle this a different way. Start by calculating the day and hour for the five periods your interested in and use DateTime to do the heavy lifting. Then, use a function to provide the schedule item for a particular day/time combination.
Here's a skeleton
<?php
date_default_timezone_set('Pacific/Auckland');
$now = new DateTime();
$oneHour = new DateInterval('PT1H');
$minusOne = (clone $now);
$minusOne->sub($oneHour);
$minusTwo = (clone $minusOne);
$minusTwo->sub($oneHour);
$plusOne = (clone $now);
$plusOne->add($oneHour);
$plusTwo = (clone $plusOne);
$plusTwo->add($oneHour);
echo returnFile($minusTwo);
echo returnFile($minusOne);
echo returnFile($now);
echo returnFile($plusOne);
echo returnFile($plusTwo);
function returnFile(DateTime $t) {
$day = $t->format('D');
$hour = $t->format('G');
// echo "Day:$day, Hour: $hour;<br>";
switch ($day) {
case 'Mon':
if ($hour<7) {
// Small hours Monday...
$filename = "smallMonday.html";
break;
}
if ($hour<12) {
// Monday morning
$filename = "morningMonday.html";
break;
}
break;
case 'Tue':
if ($hour >=23) {
// Late Tuesday
$filename = "lateTuesday.html";
}
default:
$filename = "Some other time";
}
return $filename;
}
?>
I haven't put in a complete schedule - you can work that out.
If you're using PHP 5.5 or later you can use DateTimeImmutable instead of DateTime which does away with all the cloning.
There's a fiddle here
Get rid of the leading zeros in your comparisons. Those are octal numbers and not decimals. You won't get the results you expect.
// 09 is not a valid octal number. It gets converted to zero in decimal.
else if ($d == 6 && $h >= 07 && $h < 09)
..
else if ($d == 6 && $h >= 09 && $h < 12) $file ='throughthemorning.php';

displaying relevant date formats in months days minutes or seconds?

im trying to convert a mysql timestamp to time in months or days or hours or minutes.
so the output will look like this:
added 1 month ago / added: 0 hours ago / added: 21 minutes ago / added 30 seconds ago
so i only want one format of time depending on how many minutes or how many hours or how many days etc, so 60 minutes converts to 1 hour ago or 24 hours converts to 1 day ago and 48 hours converts to 2 dayS ago.
so far i have this code:
<?
$datetime1 = new DateTime();
$datetime2 = new DateTime ($news['date_added']);
$interval = $datetime1->diff($datetime2);
str_replace('0 hours', '', $variable);
echo $interval->format('%h hours %i minutes');
?>
and this outputs the following:
added 0 hours ago 57 minutes ago.
can someone help me or show me what id need to do in order to get the formats to display right, im really new to php and am not sure how i can do this. thank you.
From http://php.net/manual/en/ref.datetime.php
Just change $precision to 1 when you call the function and add in whatever text you want to come before and after the date. You'll have to make sure you convert your date objects to timestamps, but that shouldn't be a problem for you.
/**
* this code assumes php >= 5.1.0. if using < 5.1, read
* php.net/strtotime and change the condition for checking
* for failure from strtotime()
*/
// $t1, $t2: unix times, or strtotime parseable
// $precision: max number of units to output
// $abbr: if true, use "hr" instead of "hour", etc.
function date_diff ($t1, $t2, $precision = 6, $abbr = false) {
if (preg_match('/\D/', $t1) && ($t1 = strtotime($t1)) === false)
return false;
if (preg_match('/\D/', $t2) && ($t2 = strtotime($t2)) === false)
return false;
if ($t1 > $t2)
list($t1, $t2) = array($t2, $t1);
$diffs = array(
'year' => 0, 'month' => 0, 'day' => 0,
'hour' => 0, 'minute' => 0, 'second' => 0,
);
$abbrs = array(
'year' => 'yr', 'month' => 'mth', 'day' => 'day',
'hour' => 'hr', 'minute' => 'min', 'second' => 'sec'
);
foreach (array_keys($diffs) as $interval) {
while ($t2 >= ($t3 = strtotime("+1 ${interval}", $t1))) {
$t1 = $t3;
++$diffs[$interval];
}
}
$stack = array();
foreach ($diffs as $interval => $num)
$stack[] = array($num, ($abbr ? $abbrs[$interval] : $interval) . ($num != 1 ? 's' : ''));
$ret = array();
while (count($ret) < $precision && ($item = array_shift($stack)) !== null) {
if ($item[0] > 0)
$ret[] = "{$item[0]} {$item[1]}";
}
return implode(', ', $ret);
}
$t1 = 'Feb 4, 2008 12:16:00';
$t2 = 'Jul 3, 2006 16:15:30';
echo date_diff($t1, $t2), "\n",
date_diff($t1, $t2, 3), "\n",
date_diff($t1, $t2, 2, true), "\n";
?>
Here is a possible solution. You format the time difference as a string with months-days-hours-minutes-seconds, then look through that string for the first non-zero number: that's the one you want...
$mdhms = explode('-',$interval->format('%m-%d-%H-%i-%s'));
$labels = Array(' months', ' days', ' hours', ' minutes', ' seconds');
$i = 0;
foreach($mdhms as $t){
if($t > 0) break;
$i+=1;
}
if ($i < 5) echo "It happened ".$t.$labels[$i]." ago";
else echo "It is happening right now!"

Categories