Will this strtotime code loop every two weeks? - php

I want to display something every second week for 5 days. So this week it's Feb 8 to Feb 12, and I want it to show again Feb 22 to Feb 26 and continue on indefinately, will this code work? thanks.
$StartDate = strtotime('2016-01-25');
$CurDate = date("Y-m-d");
$NextDate = date("Y-m-d", strtotime("+2 week", $StartDate));
$EndDate = date("Y-m-d", strtotime("+18 days", $StartDate));
while ($CurDate > $NextDate && $CurDate > $EndDate ) {
$NextDate = date("F j", strtotime("+2 week", strtotime($NextDate)));
$EndDate = date("F j", strtotime("+18 days", strtotime($EndDate)));
}
<?php if ( $CurDate >= $NextDate && $NextDate <= $EndDate ) { echo "..."; } ?>
I think the code is right but I'm not sure if it will loop.
Thanks.

It is best to run your code and attempt to debug it yourself before asking for help, you never know what you'll find on your own!
As for your code, I don't see any immediate issues, however I'm not the PHP interpreter!

It might, but you might be better off using the date() function to get the current week of year:
if (((int) date('W')) % 2 === 0)
{
// display message
}
date('W') will return the current week number (out of 52 weeks per year). The above code would display the message on even weeks and hide it on odd weeks. You could check for === 1 to display the message on odd weeks instead.

Related

Only future dates with PHP strtotime()

PHP's strtotime() uses the current year by default. How to get only future dates?
echo date('l d. M Y', strtotime('first sunday of april')); // Sunday 03. Apr 2016
I can't manage to get the next first Sunday of April. The date must not be in the past and it must be always relative (no 2017 or 2018 hardcoded).
echo date('l d. M Y', strtotime('first sunday of next april')); // fails
echo date('l d. M Y', strtotime('first sunday of april next year')); // wrong from January until that Sunday in April
I think I could do it in multiple steps or create a function to check, if current time is before/after the first Sunday and insert a 'next year' at the end.
But I was wondering if there is a simple solution with strtotime()
I dont think this is particularly elegant, but it works, and I hope it is what you were looking for?
echo date('l d. M Y', strtotime('first sunday of april', strtotime('first day of next year')));
However this seems like a much better, maintainable, readable solution
$d = new DateTime();
$d->modify( 'first day of next year');
echo $d->format('l d. M Y') . PHP_EOL;
$d->modify( 'first sunday of april');
echo $d->format('l d. M Y') . PHP_EOL;
Which gives
Tuesday 01. Aug 2017
Sunday 02. Apr 2017
The echo of the year change date, you would not need to do, its there just to prove that the year changed
I came here looking for a solution to the title of this post. I wanted to get the future date for a strtotime result every time.
date("Y-m-d", strtotime("Jan 2"));
If today's date is Jan 1, 2018, it will return the future date of 2018-01-02, but if today's date is Jan 3, 2018, it will return the same date (which is now in the past). In that case, I would prefer to get back 2019-01-02.
I know the OP said they didn't want a function, but that seemed like the simplest solution. So, here's the quick function I made to get the next future strtotime that matches.
function future_strtotime($d){
return (strtotime($d)>time())?strtotime($d):strtotime("$d +1 year");
}
Get that good date using...
date("Y-m-d", future_strtotime("Jan 2"));
Here's a more robust solution. It replaces strtotime but requires a second parameter -- a string of either past or future and offsets according.
<?php
function strtotimeForce($string, $direction) {
$periods = array("day", "week", "month", "year");
if($direction != "past" && $direction != "future") return strtotime($string);
else if($direction == "past" && strtotime($string) <= strtotime("now")) return strtotime($string);
else if($direction == "future" && strtotime($string) >= strtotime("now")) return strtotime($string);
else if($direction == "past" && strtotime($string) > strtotime("now")) {
foreach($periods as $period) {
if(strtotime($string) < strtotime("+1 $period") && strtotime($string, strtotime("-1 $period"))) {
return strtotime($string, strtotime("-1 $period"));
}
}
return strtotime($string);
}
else if($direction == "future" && strtotime($string) < strtotime("now")) {
foreach($periods as $period) {
if(strtotime($string) > strtotime("-1 $period") && strtotime($string, strtotime("+1 $period")) > strtotime("now")) {
return strtotime($string, strtotime("+1 $period"));
}
}
return strtotime($string);
}
else return strtotime($string);
}

Using if statement to determine weekend

So I've got a table display of a calendar. I need to use PHP to evalute each row and if the row is on a Saturday or Sunday then set to a specific CSS class that will highlight the row as red.
if (isset($_POST['date'])) {
//store passed data from date to variables
$startdate = date('Y-m-d', strtotime($_POST['date']));
$holdstart = $startdate;
$enddate = date('Y-m-t', strtotime($_POST['date']));
} else {
// Nothing passed use current month
$startdate = date('Y-m-d');
$holdstart = $startdate;
$enddate = date('Y-m-t');
};
The above is the PHP code I use in order to produce the table. The code below is the code used to loop through the days in the calendar that is selected:
//loops through each day of the month
while ($startdate != $enddate) {
$startdate = date('Y-m-d', strtotime($startdate . ' +1 day'));
$friendlymonth = date('D d M Y', strtotime($startdate));
$dates[] = $startdate;
}
I know that what I'm looking for is an if condition however I don't know how to exactly specify the date and evaluate a condition based on if the date is a Saturday or a Sunday. Thanks for reading.
date('N', $timestamp) will return numeric representation of the day of the week (1-7).
Found the solution:
<?php if(date('w', strtotime($startdate)) == 6 || date('w', strtotime($startdate)) == 0) { echo 'danger'; }?>
For anyone that doesn't know $startdate is the variable where my date is stored in. If you see there where I've evaluate the condition to the values 6 and 0. Its because 6 to PHP is Saturday, 0 is Sunday. And the it starts from 1 = Monday, ans so forth. Feel free to chime in if I've added anything wrong.

PHP: Week starts on Monday, but "monday this week" on a Sunday gets Monday next week

Here's a summary of the issue: On Sundays, strtotime('this week') returns the start of next week.
In PHP, the week seems to start on Monday. But, on any day except Sunday, this code
echo date('Y-m-d', strtotime('monday this week', strtotime('last sunday')));
Outputs the date of this week's Monday, when it seems like it should be outputting last weeks Monday. It seems like, in this case, PHP is treating both Sunday and Monday as the the start of the week. It's now Monday, Dec 10, 2012, or 2012-12-10. date('Y-m-d', strtotime('sunday last week')) returns 2012-12-09 - yesterday.
Is this a bug, or am I missing something? It seems like a bug this obvious should be fairly well known, but I can't find anything about it. Is the only way to get the start of the week to use some special handling for Sundays?
$week_offset = (int) 'sunday' == date('l');
$week_start = strtotime("-$week_offset monday"); // 1 or 0 Mondays ago
As far as I can tell, this is a bug. I see no logical reason why strtotime('this week'); should return a future date. This is a pretty major bug. In my particular case, I had a leaderboard that showed the users with the most points since the beginning of the week. But on Sundays, it was empty because strtotime returned a timestamp for a future date. I was doubtful, because just I don't know how this could have gone unnoticed, but I couldn't find any other reports of this bug.
Thanks for all your time and help, folks.
This answer is late, but it's something that I've been struggling with. Every solution I've tried so far has malfunctioned for one reason or another. This is what I ended up with that worked for me. (though it may be look pretty, it at least works).
$thisMonday = strtotime('next Monday -1 week', strtotime('this sunday'));
Here is how you can get Monday of current week:
echo date("Y-m-d", strtotime(date('o-\\WW')));
It's not ideal but this is what I resorted to using:
if(date('N') == 7) {
$date = date('Y-m-d',strtotime('monday last week'));
} else {
$date = date('Y-m-d',strtotime('monday this week'));
}
I think the only problem with your coding is TimeZone.
Solution:
Set your own time Zone. Here is the example of my own time zone:
Example
date_default_timezone_set('Asia/Kolkata');
Set the above line before calling any time function.
Have a nice day.
I think instead of trying
echo date('Y-m-d', strtotime('monday this week', strtotime('last sunday')));
you should try
echo date('Y-m-d', strtotime('monday last week'));
Try this code
// set current date
$date = date("m/d/Y");
$ts = strtotime($date); // also $ts = time();
// find the year and the current week
$year = date('o', $ts);
$week = date('W', $ts);
// print week for the current date
$i = 1; // 1 denotes the first day of week
$ts = strtotime($year.'W'.$week.$i);
echo $day = date("l", $ts); // generate the name of day
echo "<br>";
echo $day = date("Y-m-d", $ts); // generate the date
You will get the the date of current week, whether you are on monday you will get the date of that monday.
If you want the most recent monday:
function mostRecentMonday(){
if(date("w") == 1){
return strtotime("midnight today");
} else {
return strtotime("last monday");
}
}
Easy to modify to use DateTime, or, to even specify a different date to use as the base.
Based on Bryant answer :
$first_week_date = date('d F Y', strtotime('next Monday -1 week', strtotime('this sunday')));
$last_week_date = date('d F Y', strtotime('next Monday -1 week + 6 days', strtotime('this sunday')));
This is for thos looking for a friendly solution that works with any day.
function getWeekStart($week_start_day = "Monday") {
$week_days = array("Sunday"=>0,"Monday"=>1,"Tuesday"=>2,"Wednesday"=>3,"Thursday"=>4,"Friday"=>5,"Saturday"=>6,);
if(!isset($week_days[$week_start_day])) {
return false;
} else {
$start_day = $week_days[$week_start_day];
$today = date("w");
$one_day = (60 * 60 * 24);
if($today < $start_day) {
$days_difference = 7 - ($start_day - $today);
} else {
$days_difference = ($today - $start_day);
}
$week_starts = strtotime(date("Y-m-d 00:00:00")) - ($one_day * $days_difference);
return $week_starts;
}
}
//Test: If today is Monday, it will return today's date
echo date("Y-m-d H:i:s", getWeekStart("Monday"));

Getting the previous date and time

I'm currently working on a website where customers are able to cancel an order, but they can only cancel it up to 4pm 1 day before the end of the order.
I know how to get the previous day, but I can't figure out how to find out if it's 4pm or not.
$prevDay = date("Y-m-d h:m:s", strtotime('-1 day', strtotime($order->date."00:00:00")));
This gives me this output: 2011-05-08 12:05:00
$prevDay = date("Y-m-d", strtotime('-1 day')) . " 16:00:00";
$orderTime = $order->date."00:00:00";
if($orderTime < $prevDay) {
// do stuff
}
EDIT: Wait, not sure if the logic is right there, but in principle the $prevDay value should give you the date of 4PM yesterday.
$ordertime = strtotime($order->date);
$prevday = strtotime('-1 day' , $ordertime);
if (time() < $prevday && date('H') < 16) {
// it's okay to cancel
}
anything more then 12 is after noon forexample 13 14 15 till the 24. then explode the output with space character and
$time = db_value
$time = explode('',$time);
compare $time[1] > 16
i hope the above sudu code helps you

Repeating Events on the "nth" Weekday of Every Month

I've looked at at least 2 dozen topics about this and haven't really found a good answer yet, so I come to you to ask once again for answers regarding the dreaded topic of Repeating Events.
I've got Daily, Weekly, Monthly, and Yearly repeats working out fine for now (I still need to revamp the system with Exception events and whatnot, but it works for the time being). But, we want to be able to add the ability to repeat events on the (1st,2nd,3rd,4th,5th) [Sun|Mon|Tue|Wed|Thu|Fri|Sat] of every month, every other month, and every three months.
Now, if I can just understand the logic for the every month, I can figure out the every other month and the every three months.
Here's a bit of what I have so far (note: I'm not saying I have the best way of doing it or anything, but the system is one we update very slowly over time when we aren't busy with other projects, so I make the code more efficient as I have the time).
First I get the starting and ending dates formatted for date calculations:
$ending = $_POST['end_month'] . "/" . $_POST['end_day'] . "/" . substr($_POST['end_year'], 2, 2);
$starting = $_POST['month'] . "/" . $_POST['day'] . "/" . substr($_POST['year'], 2, 2);
Then I get the difference between those two to know how many times to repeat using a function I'm fairly certain I found on here some time ago and dividing that amount by 28 days to get just about how many TIMES it needs to repeat so that there is one a month:
$repeat_number = date_diff($starting, $ending) / 28;
//find the difference in DAYS between the two dates
function date_diff($old_date, $new_date) {
$offset = strtotime($new_date) - strtotime($old_date);
return $offset/60/60/24;
}
Then I add the (1st,2nd,etc...) part to the [Sun|Mon|etc...] part to figure out what they are looking for giving me somehthing like 'first Sunday' :
$find = $_POST['custom_number']. ' ' . $_POST['custom_day'];
Then I use a loop that runs the number of times this needs to repeat (the $repeat_number from above):
for($m = 0; $m <= $repeat_number; $m++) {
if($m == 0) {
$month = date('F', substr($starting,0,2));
} else {
$month = date('F', strtotime($month . ' + ' . $m . ' months'));
}
$repeat_date = strtotime($find . ' in ' . $month);
}
Now, I'm aware this code doesn't work, I at one time did have code that turned up the correct month and year for the repeat, but wouldn't necessarily find the first tuesday or whatever it was that was being looked for.
If anyone could point me back in the right direction, it would be most appreciated. I've been lurking in the community for some time now, just started trying to actively participate recently.
Thanks in advance for any input or advice you can provide.
Here's a possible alternative for you. strtotime is powerful, and the syntax includes really useful bits like comprehensive relative time and date wording.
You can use it to generate the first through Nth specific weekdays of a specific month by using the format " of ". Here's an example using date_create to invoke a DateTime object, but regular old strtotime works the same way:
php > $d = date_create('Last Friday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Friday March 25 2011 00:00:00
php > $d = date_create('First Friday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Friday March 04 2011 00:00:00
php > $d = date_create('First Sunday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Sunday March 06 2011 00:00:00
php > $d = date_create('Fourth Sunday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Sunday March 27 2011 00:00:00
php > $d = date_create('Last Sunday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Sunday March 27 2011 00:00:00
It will also overflow the month, if you ask for an invalid one:
php > $d = date_create('Ninth Sunday of March 2011'); if($d instanceof DateTime) echo $d->format('l F d Y H:i:s');
Sunday May 01 2011 00:00:00
Note that it only works with the ordinal number wording. You can't pass "1st" or "3rd", unfortunately.
Once you use this to grab the proper Nth weekday, you can then simply add the number of needed weekdays to skip (7 for one week, 14 for two, 21 for three, etc) as required until the designated end date or designated number of weeks has passed. Once again, strtotime to the rescue, using the second argument to chain together relativeness:
php > echo date('l F d Y H:i:s', strtotime('+14 days', strtotime('First Thursday of March 2011')));
Thursday March 17 2011 00:00:00
(My local copy also accepted '+14 days First Thursday of March 2011', but that felt kind of weird.)
I have a more simple method, although it may seem hack-ish.
What we can do is take the start date, and infer it's "n" value from it by taking the ceiling of its day divided by 7.
For example, if your start date is the 18th, we divide by 7 and take the ceiling to infer that it is the 3rd "whatever-day" of the month.
From there we can simply repeatedly add 7 days to this to get a new date, and whenever the new date's ceilinged 7-quotient is 3, we've hit the next "nth whatever-day" of the month.
Some code can be seen below:
$day_nth = ceil(date("j", strtotime($date))/7);
for ($i = 0; $i < $number_of_repeats; $i++) {
while (ceil(date("j", strtotime($date))/7) != $day_nth)
$date = date("Y-m-d", strtotime("+7 days", strtotime($date)));
/* Add your event, or whatever */
/* Now we increment date by 7 days before the loop starts again,
** otherwise the while loop would never execute and we'd just be
** adding to the same date repeatedly. */
$date = date("Y-m-d", strtotime("+7 days", strtotime($date)));
}
What's nice about this method is that we don't even have to concern ourselves with which day of the week we're dealing with. We just infer everything from the start date and away we go.
I make it like that:
//$typeOfDate = 0;
$typeOfDate = 1;
$day = strtotime("2013-02-01");
$to = strtotime(date("Y-m-d", $day) . " +6 month");
if ($typeOfDate == 0) { //use the same day (number) of the month
$dateArray[] = date("Y-m-d", $day);
$event_day_number = date("d", $day);
while ($day <= $to) {
$nextMonth = date("m", get_x_months_to_the_future($day));
$day = strtotime(date("Y-" . $nextMonth . "-d", $day));
$dateArray[] = date("Y-m-d", $day);
}
}
if ($typeOfDate == 0) { //use the same day (like friday) of the month
$dateArray[] = date("Y-m-d", $day);
$monthEvent = date("m", $day);
$day = strtotime(date("Y-m-d", $day) . " +4 weeks");
$newMonthEvent = date("m", $day);
if ($monthEvent == $newMonthEvent) {
$day = strtotime(date("Y-m-d", $day) . " +7 days");
}
while ($day <= $to) {
$dateArray[] = date("Y-m-d", $day);
$monthEvent = date("m", $day);
$day = strtotime(date("Y-m-d", $day) . " +4 weeks");
$newMonthEvent = date("m", $day);
if ($monthEvent == $newMonthEvent) {
$day = strtotime(date("Y-m-d", $day) . " +7 days");
}
}
}

Categories