How to define the relative time for a repetitive yearly interval? - php

I'm looking for a way to filter for events that happened between previous September (1st) and upcoming September (1st) every year. Since the filter is already part of an existing piece of code I can ony add a fixed date (timestamp) or use a relative date that runs through php strtotime. I can't run any php in the field.
Because a timestamp is fixed for a set year, I want to use relative dates to make this filter work every year.
I have tried to build this filter using simple things like [last/next] September, but that is invalid strtotime syntax.
From there I tried things like 9/1 [last/this/next] year. They were valid, but since I can't use logic to determine which one to use, it is not good.
For dates prior to this year September 1st the filter would be 9/1
last year>9/1 this year
For dates past September 1st this year it is 9/1 this year>9/1 next year.
So to summarize, I am looking for a relative date string (strtotime) to get the previous September 1st and a string for the upcoming September first. (If they exist.)

i guess you want dates in between 2012/09/01 - 2013/09/01.
you can use string in link if that's what your talking about, but you need years.
$this_year='2013/09/01';
$last_year = date("Y-m-d",strtotime("$this_year - 1 year"));
$next_year = date("Y-m-d",strtotime("$this_year + 1 year"));
echo
" last year
this year
next year
";
if(strtotime($this_year) <= strtotime($filter_date) and strtotime($filter_date) >= strtotime($last_year))
{
// dates in between 2012/09/01 - 2013/09/01
}
if(strtotime($this_year) >= strtotime($filter_date) and strtotime($filter_date) <= strtotime($next_year))
{
// dates in between 2013/09/01 - 2014/09/01
}
if you are getting data from database then use code below as its easier.
SELECT * FROM table_name WHERE 'date_field' BETWEEN ('$this_year') and ('$last_year ')

Related

Carbon PHP Loop through each month on date range [duplicate]

I failed to find a proper solution to this issue. As you see in Example #3 in the PHP documentation, they state that one must beware when adding months using the DateInterval in DateTime::add.
There's not really any explanation for why the method's behavior is as such and what I can do to avoid this, which I find to be an error at first sight.
Anyone have some insight into this?
The issue is that each month can have a different number of days in them. The question is what you're doing when you want to increment a date by 1 month. Per the PHP documentation if you're on January 31st (or 30th) and you add 1 month, what is the expected behavior?
February only has 29 days in it. Do you want to be set to the last day of the month? You're generally safer incrementing by a set number of days if that's what you're looking for, or a static date based on the current date. Without knowing what you're trying to accomplish when you increment your month, it's tough to say how to watch for an error.
EDIT:
As someone mentions in the similar post commented by Mike B above, you probably want to do something where you (in pseudocode):
1) Use cal_days_in_month() for the next month and save that number to a variable x
2) If x >= current billing DOB, increment and be done
3) DateTime::modify('last day') (havent used this before but something along these lines) to set the date to the last date of the next month (set it to the 1st of the next month, then last day?)
Worth noting is that if you use the variable here as the new billing value, you'll wipe out your original value. I would save an extra DB value that's "first billing date" or just "billing_day_of_month" or something, and use that to figure out the day of month that you should be looking at
If your goal is to strictly increment by user-friendly months (thus, 3 months from January 21st should be April 21st), with the exception that shorter membership months get shortened (thus, 1 month from January 31st is February 28th/29th), then you only need to go back a few days if you crossed over into the next month:
function addMonths($date,$months) {
$orig_day = $date->format("d");
$date->modify("+".$months." months");
while ($date->format("d")<$orig_day && $date->format("d")<5)
$date->modify("-1 day");
}
$d = new DateTime("2000-01-31");
addMonths($d,1);
echo $d->format("Y-m-d"); // 2000-02-29

Use date and/or strtotime() functions in php to identify complex date patterns

I am well versed in using strtotime or the date modify functions within PHP to find NEXT or PREVIOUS days/months/years, or to add or subtract dates. There is the ability to do something like strtotime("first day of last month") but there is not the ability to use a specific month name (let's say July) as a parameter...so it seems I cannot say strtotime("first day of last July").
My question is NOT
"can you write me some code to give me the date"
but rather
"is there a streamlined 1 or 2 line approach using strtotime() or
something else that will enable me to reach the same output with
something more compact, tidy, and clear?"
I am trying to streamline some fairly clunky code to figure out the date (really just the year) of July 1 two instances ago...not the most recent past July 1, but the one a year prior to that (so it could be a date almost 2 full years in the past...or could be as recent as 1 year and 1 day in the past).
For example:
Assume today is February 26, 2014. I am trying to output 2012-07-01.
However a bit later this same year... let's say on July 2 of 2014...
the output would now be 2013-07-01
So, essentially I need to figure out if July 1 has already happened in the current year...and if not then subtract 2 from the current year...and if yes, then subtract 1 from the current year.
A clunky version looks like this:
$CurrentDate = date("Y-m-d");
$CurrentYear = date("Y");
$ThisYearCutOff = $CurrentYear.'-07-01';
if($CurrentDate > $ThisYearCutOff){
echo ($CurrentYear-1).'-07-01';
}
else
{
echo ($CurrentYear-2).'-07-01';
}
Any thoughts on how to do this in a relatively streamlined bit of php code?

PHP converting date without a year

I have a string like 09-10 which is representative of mm-dd. I need it in a format something like Monday 10th September? The problem is that I do not have a year and I can't have an array containing months and days because I would like to know the day of the week (Mon, Tue, Wed etc.)
Any idea how to do this in PHP, preferably using date() to format the date?
Note: this is not in MySQL...
You can't get the day (Monday, Tuesday etc) without knowing the year.
You can use date('jS F', strtotime('2012-09-10')); to get the day of the month and month, just shove any old year in there. I'd make sure to use a leap year year though to make sure you catch those pesky feb dates properly.
Example: http://codepad.org/JfUeTQlH
So, like this:
$d_m = '09-10';
$my_date = date('jS F', strtotime('2012-'.$d_m));
As it is clear Every 1st day of year is not Sunday, it happens after regular interval So just saying a date without year is not clear about day(Monday,Tuesday...). it will give you number of day in that year i.e. out of 365days. so if you are working within a year its OK, but if it goes beyond it You wont be able to get the day(Monday,Tuesday...).

What can go wrong when adding months with a DateInterval and DateTime::add?

I failed to find a proper solution to this issue. As you see in Example #3 in the PHP documentation, they state that one must beware when adding months using the DateInterval in DateTime::add.
There's not really any explanation for why the method's behavior is as such and what I can do to avoid this, which I find to be an error at first sight.
Anyone have some insight into this?
The issue is that each month can have a different number of days in them. The question is what you're doing when you want to increment a date by 1 month. Per the PHP documentation if you're on January 31st (or 30th) and you add 1 month, what is the expected behavior?
February only has 29 days in it. Do you want to be set to the last day of the month? You're generally safer incrementing by a set number of days if that's what you're looking for, or a static date based on the current date. Without knowing what you're trying to accomplish when you increment your month, it's tough to say how to watch for an error.
EDIT:
As someone mentions in the similar post commented by Mike B above, you probably want to do something where you (in pseudocode):
1) Use cal_days_in_month() for the next month and save that number to a variable x
2) If x >= current billing DOB, increment and be done
3) DateTime::modify('last day') (havent used this before but something along these lines) to set the date to the last date of the next month (set it to the 1st of the next month, then last day?)
Worth noting is that if you use the variable here as the new billing value, you'll wipe out your original value. I would save an extra DB value that's "first billing date" or just "billing_day_of_month" or something, and use that to figure out the day of month that you should be looking at
If your goal is to strictly increment by user-friendly months (thus, 3 months from January 21st should be April 21st), with the exception that shorter membership months get shortened (thus, 1 month from January 31st is February 28th/29th), then you only need to go back a few days if you crossed over into the next month:
function addMonths($date,$months) {
$orig_day = $date->format("d");
$date->modify("+".$months." months");
while ($date->format("d")<$orig_day && $date->format("d")<5)
$date->modify("-1 day");
}
$d = new DateTime("2000-01-31");
addMonths($d,1);
echo $d->format("Y-m-d"); // 2000-02-29

Date query and display

I am currently trying to write a little program to track time-off requests for employees. I'm fairly new to MYSQL and PHP, so it's a learning project for me as well. I've run into this problem which I do not seem to be able to figure out.
I want to display time off requests for a given week (Mon-Fri). I've got the requests in a table 'requests', with a 'Starttime' and 'Endtime' in separate fields, both Date/Time.
I can currently easily search and retrieve requests that have either (or both) Starttime or Endtime values that fall within the given ISO week I am looking at (WEEKOFYEAR() ).
What I need to be able to do is search for requests that may include days in the ISO week I am displaying, but not have a Starttime or Endtime during that week.
Example:
Employee takes off Tuesday of Week 24 through Friday of Week 24.
Currently, I would correctly display that the employee was off starting Tuesday and show a return on that Friday, but on Wed and Thursday nothing would be entered.
Employee takes off Friday of Week 30 through Monday of Week 32.
Currently, I would show that employee as not being 'off' during Week 31 because the search would not show a Starttime or Endtime during that week even though they are actually off the entire week. Though the Starttime and Endtime would be noted on the correct days.
Right now, what I do to work around this is run 5 additional queries to check if the date for each day Mon-Fri during Week 31 is contained BETWEEN the Starttime and Endtime of each request in the db.
I hate to run a total of 6 queries to get this information. Is there an easier way to get that information?
I just wrote a calendar app for events and ran into this- how bout something like this:
SELECT * FROM Requests WHERE
Start_Date BETWEEN <first_day_of_week> AND <last_day_of_week>
OR
End_Date BETWEEN <first_day_of_week> AND <last_day_of_week>
OR
<day_of_week_monday> BETWEEN Start_Date AND End_Date
OR
<day_of_week_tuesday> BETWEEN Start_Date AND End_Date
OR
<day_of_week_wedenesday> BETWEEN Start_Date AND End_Date
OR
<day_of_week_thursday> BETWEEN Start_Date AND End_Date
OR
<day_of_week_friday> BETWEEN Start_Date AND End_Date
GROUP BY ID ORDER BY Start_Date ASC, Date ASC
While < value_names > are generated with php via the currently viewed week requested. Should cover your bases.
What format are these dates stored in the DB? Assuming they are using MySQL's DATE format, its pretty easy to do. You can just use comparison operators on the fields and MySQL will do the work for you in one query.
$sql = "SELECT * FROM table WHERE startdate <= $someday AND $someday <= enddate";
Sticking to your week of year way of doing it, you can run a check to see if the current week falls within the range of the starting week off and the ending week off.
SELECT * FROM table WHERE WEEKOFYEAR(Starttime) <= N AND WEEKOFYEAR(Endtime) >= N;
(where N is the week you're displaying)
What you'd want to do, once you get the rows, is parse each day in PHP to see if that day falls between the starttime and endtime.
A good method for that is using:
$start_timestamp = strtotime($row['Starttime']);
$end_timestamp = strtotime($row['Endtime']);
You can use a similar method to get a timestamp of the day you are displaying, and see if it falls between $start_timestamp and $end_timestamp to determine if that day is off.
since you mentioned PHP as the display:
$start=30; //Friday of Week 30
$end=32; //Monday of Week 32
foreach (range($start, $end) as $number) {
echo $number;
}
You would expect to get 30,31,32.
You will have to verify that $start is < $end though as well for December to January weeks.
The range for WEEKOFYEAR() is 1-53. In this case, add 53 to the $end and display mod of $end if greater than 53:
$start=52; //Friday of Week 52, 2009
$end=2; //Monday of Week 2, 2010
If($start>$end) $end+=53;
foreach (range($start, $end) as $number) {
if($number>53){
echo $number%53;}
else{
echo $number;
}
}
You would expect to get 52,53,1,2
Probably need the query to read either like the big one with all the ORs or something like this
WHERE
Starttime <= <value for last day/time of the week>
AND
Endtime >= <value for the first day/time of the week>
That should get all the dates you need that could fall in that week, then you parse the records you get with PHP to find the ones for that actual week... though there may be an easier way to do that.

Categories