Bi-weekly rotation of three options, rolling on a Friday at Midday - php

I need to rotate 3 options based on the current week number; ie:
if($weekNumber == 42 || $weekNumber == 43){
$thisID = 1;
}
else if($weekNumber == 44 || $weekNumber == 45){
$thisID = 3;
}
else if($weekNumber == 46 || $weekNumber == 47){
$thisID = 2;
}
else if($weekNumber == 48 || $weekNumber == 49){
$thisID = 1;
}
I'd obviously prefer this to be less manual! I've considered placing the 3 ID's in an array and selecting based on the number of weeks that have passed since date X but I'm not sure how to implement that.
And additionally... the rollover needs to be at Midday on a Friday. I considered simply incrementing the week number in the above plan too, with additional adjustments for when we're rolling from week 52 to week 1, but there must be a more sensible approach!
Thanks

Why don't you take the rounded half of the week number? Then you only need a catalog holding 26 IDs and you can implement a direct lookup:
$catalog=[1,2,3,4,5,6,3,4,2,5,6,7,4,4,7,9,5,8,8,9,2,4,5,7,6,8,9];
$thisID = $catalog[floor($weekNumber/2)];

This should work:
$options = array(1,2,3);
$offset = 129600;
$twoWeeks = 1209600;
$idx = floor((time()-$offset)/$twoWeeks) % count($options);
$chosenOption = $options[$idx];
Some explanation:
0 Unix time was a Thursday at midnight, so the first Friday at midday was 129600 seconds later.
With time()-$offset we shift the time to set Friday at midday as the zero point of our time calculation.
Now as Friday at midday is the zero point, we can count the number of full two weeks from the first Friday at midday by simply dividing the passed seconds by 1209600.

Related

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.

Count back the week numbers based on user input (not current week number)

I'm trying to make a logic in PHP that returns the week number of 4 week before a given week number instead of the current weeknumber. The input for the given week number is $argv[1] because the script is executed CLI.
$FOURWEEKSAGO = date("W", strtotime("-4 week"));
Above example is with the current timestamp but i'm trying to do the same with the following. The example below doesn't work but it illustrates what I want to do.
$FOURWEEKSAGO = $argv[1], strtotime("-4 week");
The functionality must ensure that when its week 2 it will count back and results in 51 (4 week earlier)
A little help would be appreciated
Let $inputWeek be the numerical input value and $week the numerical resulting week.
If last year wasn't a leap-year:
$week = ($inputWeek + 48) % 52
If last year was a leap-year:
$week = ($inputWeek + 49) % 53
In order to decide whether last year was a leap-year, I assume that you can use:
if ((date("Y") - 2017) % 4 == 0)
...since 2017 is a "year-after-a-leap-year", and so every 4th year from that one is.
As pointed out in the comments, the code will get 0 if the input is 4, which can be fixed using an if-statement. Note though that it's important to distinguish if week 0 is identical to week 53 or week 52. All in all:
if ((date("Y") - 2017) % 4 == 0)
{
$week = ($inputWeek + 49) % 53;
if ($week == 0) $week = 53;
}
else
{
$week = ($inputWeek + 48) % 52;
if ($week == 0) $week = 52;
}

PHP is date between 2 other dates - Ignoring month

I am trying to determine if a day and time are between two others, I have the following...
$currentdate = date("N h:i:s A");
This returns the day of the week as a number and then the current time in 24 hour format.
I want to check if the $currentdate is between 9am on a Friday and 9am on a Monday.
What is the best way to tackle this?
I believe this should give you what your asking for but I'm sure there are better ways to implement. So basically the time has been converted into an INT for comparing and the hours are configured not to have a leading zero hence why $timeOne and $timeTwo is shorter. I've then used an if statement to test days and time on that specific day leaving you a slot to add your code if those conditions are met.
function checkDayTime() {
$day = date(w); //0 (for Sunday) through to 6 (for Saturday)
$timeOne = 90000;
$timeTwo = 90000;//Added for easier reading
$currentTime = (int) date('Gis'); //Time as INT 00000 > 240000
if (($day == 5 && $currentTime > $timeOne) || ($day == 6 || $day == 0) || ($day == 1 && $currentTime < $timeTwo)) {
//Between those hours
return TRUE;
} else {
//Not between those hours
return FALSE;
}
}
Just removed the extra if statement as it was not needed

Alarm sound at certain time of a day

The idea is to play an alarm from html/php web-page via a TV hanging near the school canteen reminding students to wash their hands. The TV is used as a tabloid screen for school events and news.
The piece of code I'm using on this page is as follows:
<?php
$hour = date('G');
$day = date('1..5'); // 1..7 for Monday to Friday
if (($hour >= 11.05 && $hour <= 11.35) // 5am - 7am
|| ($hour >= 12.15 && $hour <= 12.30) // 10am - 12 noon
|| ($hour >= 21.10 && $hour <= 21.30) // 10am - 12 noon
|| ($day == 1-5) // Monday - Friday
) { ?>
<audio src="Audio/sirena.mp3" autoplay="true" loop="loop">
<?php } ?>
This only plays it once the page is uploaded onto the server, and if it falls within the times above. Otherwise, it stays silent. And, strangely it plays only on my home PC on Chrome/IE/Mozilla and it doesn't play completely on school PCs.
Bear in mind the page auto refreshes itself every 5 min.
Would appreciate if someone gave a hint on event listeners or anything else.
There are a couple of problems with your code.
In $day = date('1..5');, '1..5' isn't a valid format for date(). That will just return the string 1..5. You want date('w').
date('G') returns the hour in 24-hour format, so $date will be a string representation of an integer. In your if condition you are comparing it to floats. Since all of the different time conditions are various decimals above the same integers, $date will never match any of them. For example, if the time is 11:30 AM, $date will be '11', which is not between 11.05 and 11.35. (Obviously, neither is '10' or '12'.)
In the last part of the if condition, you have || ($day == 1-5). There are two problems with that. First, 1-5 does not mean "between one and five"; it means "one minus five". And second, the fact that this is an additional non-nested or condition means that it negates all of the various time comparisons, because whenever any part of an or condition is true, the entire condition evaluates to true. If it was || ($day >= 1 && $day <= 5), then the if would be true all day every Monday through Friday. As it is, it's true all day only on Thursday.
I added an updated version that I think will do what you want it to (based on the comments in your code). I used some kind of strange indentation in the if condition to hopefully show the grouping a little better. Basically it needs to check the day and check a group of time conditions. Note the different format for time ('Gi'), which gets the hour and minute in a format that can be compared to integer values in the if condition.
$day = date('w');
$time = date('Gi');
if ( ($day > 0 && $day < 6) // Monday - Friday
&& ( // AND
($time >= 1105 && $time < 1135) // time range 1
|| // OR
($time >= 1215 && $time < 1230) // time range 2
|| // OR
($time >= 2110 && $time < 2130) // time range 3
)
)
echo '<audio src="Audio/sirena.mp3" autoplay="true" loop="loop">';

Determine if a week is odd or even

I have debugged this legacy code, and would like a sanity check on it.
The purpose of it is to allow someone to choose a delivery frequency for shipping a product. If someone wants their product Every Other Week, the system needs to determine if they should get an order next week, or two weeks from now. We call it A week, or B Week.
Keep in mind I did not write this, I am just trying to make sense of it and would like some help evaluating its accuracy:
if (date("l") == "Monday" ) {
$start = 0;
} else if (date("l") == "Tuesday" || date("l") == "Wednesday" || date("l") == "Thursday" || date("l") == "Friday" || date("l") == "Saturday"|| date("l") == "Sunday") {
$start = -1;
}
// if changing to every other week set to next week's a/b-ness
$a_week_tid = 34;
$b_week_tid = 35;
$every_other_week_frequency_id = 32;
if ($delivery_frequency == $every_other_week_frequency_id) {
$julian = (int) (strtotime('Monday +' . $start . ' week') / 86400);
$julian_week = ($julian-4) / 7;
if ($julian_week % 2) {
$today_a_or_b = $b_week_tid;
$next_week_a_or_b = $a_week_tid;
$a_or_b_week_string = '(A Week)';
} else {
$today_a_or_b = $a_week_tid;
$next_week_a_or_b = $b_week_tid;
$a_or_b_week_string = '(B Week)';
}
} else {
$next_week_a_or_b = NULL;
$a_or_b_week_string = NULL;
}
This code is not commented or documented. The part that confuses me is:
Why is 4 subtracted from Julian, then divided by 7?
If today is Monday, $julian_week is 2129, and 2129 % 2 evaluates TRUE. Is that correct?
Is this even how it should be done? Can't I rewrite this using date('w') a lot easier?
Yeah using date would totally be easier, plus it takes into account leap years, daylight saving time, all that extra stuff you don't want to have to deal with.
if (date('W')%2==1)
That's SOOOO much easier to maintain than the above.
I don't believe you can use date("W") in this case. According to the ISO calculation, on occasion, there will be years with 53 weeks. In those years, Week 53 is followed by Week 01, both odd numbers, and an A/B calculation based on Even/Odd ISO week number would result in two successive A or B weeks.
The original calculation determines the number of days from the UNIX epoch of the present Monday, or of the most recent Monday if today is not a Monday. The -4 causes the A/B week labels to change on Thursdays. Even/oddness of a week is determined from a fixed date (the Unix Epoch), so there will be no discontinuity in the oscillation of A/B-ness using the original code.
The ISO standard for week one in a year is that it is the week that the first Thursday of the year falls. This is the reason for the 4 subtracted from the Julian date. The week number is then found by dividing by 7.
Again the ISO standard implies that week number cannot be greater than 53. I don't understand how your figure of 2129 can arise. However the div operator will not evaluate TRUE for this figure. Checking the div operator on the week number is the way of determining whether you are in week a or b. If it is before Thursday, it is quite likely that the number will be 1 less than you anticipate.
The coding looks fairly good to me, though I have not stepped through all of it. It does look correct.
Using W on consecutive Fridays, mod by 2. Both lines output 1. So doing it this way will occasionally fail.
echo date('W',strtotime('2016-01-01'))%2;
echo date('W',strtotime('2016-01-08'))%2;
Just a simple way.
<?php
$weekNumber = date("W");
echo 'Week number:',$weekNumber;
if($weekNumber&1) {
echo '<strong>Week A.</strong>';
} else {
echo '<strong>Week B.</strong>';
}
?>
$day = '2019-11-10';
$date = new DateTime($day);
$dayOfMonth = $date->format("j"); // month days 1 - 30
$weekNumber = ceil($dayOfMonth / 7); // get the week number
if ($weekNumber % 2 == 0) { //if week number is even
echo "Even Week";
} else {
echo "Odd Week";
}
**// output Even Week**

Categories