Building a weekly dropdown with php - php

I have reports i run, they are based on weekly reports from Wed - Tue each week example here:
else if($_GET['week'] =='aug13th2014'){
$date_from = "2014-08-13 00:00:00";
$date_to = "2014-08-19 23:59:59";
$date_display = "Aug 13th to Aug 19th 2014";
}
Then i echo the select
echo "<option value='aug13th2014'>Aug 13th to Aug 19th 2014</option>";
So if a user selects that week and submits the form, then it uses the $date_from and $date_to to run my reports and return the values for that week.
This all works great but its a pain in the butt to have to manually create those else if statements every single week and if i am not concentrating then i can make mistakes on the date values.
What i want to do is automate it. So im thinking ill use a script that does the following:
Note that even though i say from wednesday to tuesday its officially
Get Todays Date
Find the date for the previous Wednesday
Check if 168 hours (7 days) has elapsed since Wed at 00:00:00
If not then find the previous Wednesday and then get the date for 168 hours after that point.
This will give me 2 dates now. Wed 13th Aug 2014 and ill set the time to 00:00:00 and then ill also have the date for Tuesday 19th Aug.
Then ill decide how many weeks i want to show in the dropdown and loop that many times
Then i will need to deduct 168 hours from both wednesday and tuesdays date in the next loop to get the previous week.
Repeat that for however many loops i get
My question is before i got to all that hassle is there a more efficient way to do this? Maybe a php class available for this very type of problem? I am not using any frameworks and its not worth converting just for this job. Also are there any obvious flaws in my approach or it looks good?
One of my concerns is handling Daylight Savings Time where the time goes back and forward one hour, i guess i could manually change it twice a year but maybe there is a simpler solution

The PHP function strtotime can help you here.
echo strtotime('Last Wednesday');
I wouldn't do:
echo "<option value='aug13th2014'>Aug 13th to Aug 19th 2014</option>";
Rather use a timestamp so code your dropdown like so:
$date = strtotime('Last Wednesday');
$weeks = 5;
$i = 1;
echo '<select>';
while ($i <= $weeks) {
echo '<option value="'.$date.'">Week of ' . date('D d M', $date) . '</option>';
$date = strtotime( date('Y-m-d', $date) . ' + 7 Days');
$i++;
}
echo '</select>';

Related

PHP dateTime previous month of 31 Dec is wrong

I have this:
$previousMonth = new DateTime('2019-12-31');
$previousMonth->modify('-1 month');
My understanding is '-1 month' should modify the object regardless of number of days in that month, or?
Naturally what should I get or expect to get is end of Nov(2019-11-30) but what I get is first of December(the same month).
BTW if I change the date to '2019-12-30'(one day prior) then it will be end of Nov.
If my initial assumption is not correct, then what is the best alternative to reliably calculate the previous month?
Any thoughts?
The simplest and easiest way to get the last month in php is
$previousMonth = date("Y-n-j", strtotime("last day of previous month"));
Same as been suggested on other thread Getting last month's date in php
$date = "2019-12-31 00:00:00";
echo date('Y-m-d', strtotime($date . '-1month'));
This prints out 2019-12-01 as the 31/11 does not exist.
The following doesn't answer your question but may help in the future. I like to use Carbon when working with dates. Your issue could be resolved quite simply with this.
https://carbon.nesbot.com/
It has many functions and is extremely simple to use, and it can be installed with Composer.
To get the last day of the previous month, you can get the first day of the current month and substract 1 second or 1 day :
$previousMonth = new DateTime('2019-12-31');
$previousMonth->modify($previousMonth->format('Y-m-01')); // date is 2019-12-01 00:00:00
$previousMonth->modify('-1 sec');
echo $previousMonth->format('Y-m-d H:i:s') . PHP_EOL; // Outputs 2019-11-30 23:59:59
$previousMonth->modify('+1 sec'); // set back the original date 2019-12-01 00:00:00
$previousMonth->modify('-1 day');
echo $previousMonth->format('Y-m-d H:i:s'); // Outputs 2019-11-30 00:00:00

php date addition skipping days

I have a date, and need to add 24 Months (and not 2 Year) to it. This is what I tried:
strtotime("+24 months", $mydate);
If my date is, 20th Dec 2013 then the computed date is coming as 10th Dec 2015, whereas my expected date was 20th Dec 2015.
I know, what is going behind the scene:
2 Year: 365 days x 2 = 730 days
24 Months: 24 x 30days = 720 days
This gives me the missing 10 days. But how to over come this issue.
In Java we have Calendar class, which takes care of such calculations. However, I din't find anything here.
Can this issue be resolved.? Or I need to handle it manually?
You should always use the DateTime() class for anything like that.
i.e
$date = new DateTime("UTC");
//get date in 24months time:
$date->add(new DateInterval("P24M"));
//output date:
echo $date->format("d/m/Y H:i:s");
By using the DateTime and DateInterval classes, you can be sure that it will account of leap years and other such irregularities in dates.
See more at: http://php.net/manual/en/class.datetime.php
I hope this helps.
$mydate = "2014-10-01";
echo date('d-m-Y',strtotime("+24 months", strtotime($mydate)));
DateTime should work perfectly here:
$date = new DateTime("20th Dec 2013");
echo $date->format("d-m-Y");
$date->add(new DateInterval('P24M'));
echo $date->format("d-m-Y");
Output:
20-12-2013
20-12-2015
Demo
Sidenote:
I couldn't reproduce your error with:
echo date("d-m-Y", strtotime("+24 months", $mydate = strtotime("2013-12-20")));
See:
http://3v4l.org/HURAt

Display the 1st, 2nd, 3rd, 4th, & 5th date of the current week in php

Ok, So im trying to figure out the best way in php to write (or print) the 1st, 2nd, 3rd, 4th, & 5th date of the current week (starting with Monday) in php.
For example... Using the week of the 4th through the 8th of February...
I would need a script for the 1st day of the week (starting with Monday) displayed as February 04, 2013 and then I would need the same script four more times to display Tues, Wed, Thurs, & Fri...
All-together I would end up with 5 scripts or one script that I could copy and manipulate to work the way I need it to...
Also, If you could tell me how to do the same for Saturday and Sunday that would be greatly appreciated as-well.
If there is anything that you do not understand, please let me know and I will try my hardest to clarify...
Thanks in advance!
First you need to get the "current" week's Monday. To do this, I would suggest calling date("N") and see if it's 1. If it is, then now is the Monday you want. Otherwise last monday is. Pass that to strtotime to get the timestamp corresponding to the first monday of the week. Then repeatedly add 24 hours (24*3600 seconds) to get each day.
$startofweek = date("N") == 1 ? time() : strtotime("last monday");
for($i=0; $i<5; $i++) {
$day = $startofweek + 24*3600*$i;
echo "Day ".($i+1).": ".date("d/M/Y",$day)."<br />";
}
You can use strtotime with special parameters. like:
$time = strtotime('monday this week');
$time = strtotime('today');
$time = strtotime('next monday');
$time = strtotime('previous monday');
Same goes for every other days of the week

selecting a day of the week every x number of days thats not a weekend

I have code already for a date range that works fairly well (not using datetime class, I'm stuck in 5.2). But I want to modify it to select the previous day before the weekend (e.g. friday) based on every fortnight from the starting date.
I have been experimenting with finding all the saturdays and sundays then doing a array_search with a mktime as such: mktime(0, 0, 0, date("m", $date), date("d", $date)-1, date("Y", $date)
It seems to find all the Saturdays & Sundays but my code seems replace the actual dates instead of just selecting the previous day and styling it.
My code is a bit of a mess, but its pretty generic date range, e.g. while ($date1 <= $date2) { do stuff here }
So how can I select the friday before a weekend of a number of every 14 days from the start date.
Edit:
The answers below were all fine, but not quite what I was asking. Hopefully I can be more clear here.
I don't want code that finds me all the fridays in a date range specifically, I want to do a date range and every time there is a friday that is +14 days from the start date (i.e. every 2 weeks) I want to style it so it stands out. I have managed to find all the weekends every 2 weeks and style it, but I can't figure out how to select the friday's 2 weeks in advance from the start date.
You can use strtotime() to get the initial Friday and then you can either use that or your mktime function to do your 14 day adds.
$thisWeekFriday = strtotime('friday');
$twoWeeksFromFriday = $thisWeekFriday + 1209600; //1209600 seconds in two weeks
echo date('Y-m-d H:i:s', $twoWeeksFromFriday);
$number_of_dates = 10;
for ($i = 0; $i < $number_of_dates; $i++) {
echo date('Y-m-d', strtotime('Friday +' . ($i * 2) . ' weeks'));
}
today this would output
2011-08-12
2011-08-26
2011-09-09
2011-09-23
2011-10-07
2011-10-21
2011-11-04
2011-11-18
2011-12-02
2011-12-16

How to get previous month and year relative to today, using strtotime and date?

I need to get previous month and year, relative to current date.
However, see following example.
// Today is 2011-03-30
echo date('Y-m-d', strtotime('last month'));
// Output:
2011-03-02
This behavior is understandable (to a certain point), due to different number of days in february and march, and code in example above is what I need, but works only 100% correctly for between 1st and 28th of each month.
So, how to get last month AND year (think of date("Y-m")) in the most elegant manner as possible, which works for every day of the year? Optimal solution will be based on strtotime argument parsing.
Update. To clarify requirements a bit.
I have a piece of code that gets some statistics of last couple of months, but I first show stats from last month, and then load other months when needed. That's intended purpose. So, during THIS month, I want to find out which month-year should I pull in order to load PREVIOUS month stats.
I also have a code that is timezone-aware (not really important right now), and that accepts strtotime-compatible string as input (to initialize internal date), and then allows date/time to be adjusted, also using strtotime-compatible strings.
I know it can be done with few conditionals and basic math, but that's really messy, compared to this, for example (if it worked correctly, of course):
echo tz::date('last month')->format('Y-d')
So, I ONLY need previous month and year, in a strtotime-compatible fashion.
Answer (thanks, #dnagirl):
// Today is 2011-03-30
echo date('Y-m-d', strtotime('first day of last month')); // Output: 2011-02-01
Have a look at the DateTime class. It should do the calculations correctly and the date formats are compatible with strttotime. Something like:
$datestring='2011-03-30 first day of last month';
$dt=date_create($datestring);
echo $dt->format('Y-m'); //2011-02
if the day itself doesn't matter do this:
echo date('Y-m-d', strtotime(date('Y-m')." -1 month"));
I found an answer as I had the same issue today which is a 31st. It's not a bug in php as some would suggest, but is the expected functionality (in some since). According to this post what strtotime actually does is set the month back by one and does not modify the number of days. So in the event of today, May 31st, it's looking for April-31st which is an invalid date. So it then takes April 30 an then adds 1 day past it and yields May 1st.
In your example 2011-03-30, it would go back one month to February 30th, which is invalid since February only has 28 days. It then takes difference of those days (30-28 = 2) and then moves two days past February 28th which is March 2nd.
As others have pointed out, the best way to get "last month" is to add in either "first day of" or "last day of" using either strtotime or the DateTime object:
// Today being 2012-05-31
//All the following return 2012-04-30
echo date('Y-m-d', strtotime("last day of -1 month"));
echo date('Y-m-d', strtotime("last day of last month"));
echo date_create("last day of -1 month")->format('Y-m-d');
// All the following return 2012-04-01
echo date('Y-m-d', strtotime("first day of -1 month"));
echo date('Y-m-d', strtotime("first day of last month"));
echo date_create("first day of -1 month")->format('Y-m-d');
So using these it's possible to create a date range if your making a query etc.
If you want the previous year and month relative to a specific date and have DateTime available then you can do this:
$d = new \DateTimeImmutable('2013-01-01', new \DateTimeZone('UTC'));
$firstDay = $d->modify('first day of previous month');
$year = $firstDay->format('Y'); //2012
$month = $firstDay->format('m'); //12
date('Y-m', strtotime('first day of last month'));
strtotime have second timestamp parameter that make the first parameter relative to second parameter. So you can do this:
date('Y-m', strtotime('-1 month', time()))
if i understand the question correctly you just want last month and the year it is in:
<?php
$month = date('m');
$year = date('Y');
$last_month = $month-1%12;
echo ($last_month==0?($year-1):$year)."-".($last_month==0?'12':$last_month);
?>
Here is the example: http://codepad.org/c99nVKG8
ehh, its not a bug as one person mentioned. that is the expected behavior as the number of days in a month is often different. The easiest way to get the previous month using strtotime would probably be to use -1 month from the first of this month.
$date_string = date('Y-m', strtotime('-1 month', strtotime(date('Y-m-01'))));
I think you've found a bug in the strtotime function. Whenever I have to work around this, I always find myself doing math on the month/year values. Try something like this:
$LastMonth = (date('n') - 1) % 12;
$Year = date('Y') - !$LastMonth;
date("m-Y", strtotime("-1 months"));
would solve this
Perhaps slightly more long winded than you want, but i've used more code than maybe nescessary in order for it to be more readable.
That said, it comes out with the same result as you are getting - what is it you want/expect it to come out with?
//Today is whenever I want it to be.
$today = mktime(0,0,0,3,31,2011);
$hour = date("H",$today);
$minute = date("i",$today);
$second = date("s",$today);
$month = date("m",$today);
$day = date("d",$today);
$year = date("Y",$today);
echo "Today: ".date('Y-m-d', $today)."<br/>";
echo "Recalulated: ".date("Y-m-d",mktime($hour,$minute,$second,$month-1,$day,$year));
If you just want the month and year, then just set the day to be '01' rather than taking 'todays' day:
$day = 1;
That should give you what you need. You can just set the hour, minute and second to zero as well as you aren't interested in using those.
date("Y-m",mktime(0,0,0,$month-1,1,$year);
Cuts it down quite a bit ;-)
This is because the previous month has less days than the current month. I've fixed this by first checking if the previous month has less days that the current and changing the calculation based on it.
If it has less days get the last day of -1 month else get the current day -1 month:
if (date('d') > date('d', strtotime('last day of -1 month')))
{
$first_end = date('Y-m-d', strtotime('last day of -1 month'));
}
else
{
$first_end = date('Y-m-d', strtotime('-1 month'));
}
If a DateTime solution is acceptable this snippet returns the year of last month and month of last month avoiding the possible trap when you run this in January.
function fn_LastMonthYearNumber()
{
$now = new DateTime();
$lastMonth = $now->sub(new DateInterval('P1M'));
$lm= $lastMonth->format('m');
$ly= $lastMonth->format('Y');
return array($lm,$ly);
}
//return timestamp, use to format month, year as per requirement
function getMonthYear($beforeMonth = '') {
if($beforeMonth !="" && $beforeMonth >= 1) {
$date = date('Y')."-".date('m')."-15";
$timestamp_before = strtotime( $date . ' -'.$beforeMonth.' month' );
return $timestamp_before;
} else {
$time= time();
return $time;
}
}
//call function
$month_year = date("Y-m",getMonthYear(1));// last month before current month
$month_year = date("Y-m",getMonthYear(2)); // second last month before current month
function getOnemonthBefore($date){
$day = intval(date("t", strtotime("$date")));//get the last day of the month
$month_date = date("y-m-d",strtotime("$date -$day days"));//get the day 1 month before
return $month_date;
}
The resulting date is dependent to the number of days the input month is consist of. If input month is february (28 days), 28 days before february 5 is january 8. If input is may 17, 31 days before is april 16. Likewise, if input is may 31, resulting date will be april 30.
NOTE: the input takes complete date ('y-m-d') and outputs ('y-m-d') you can modify this code to suit your needs.

Categories