In PHP, I'm generating a calendar with code from here. I've connected it with Basecamp and am successfully calculating the hours worked each day and sum them for the week and month. To properly calculate overtime, I need the hours from the whole week, even when it spans the end/beginning of a month.
After several hours of trying, I haven't been able to calculate the dates of the days marked with '?' in the above image.
I can't escape the feeling that I'm missing something obvious here, but haven't been able to figure it out. Any help much appreciated, thank you.
You can use mktime() and set a day argument which is less than 1: 0 for the last day, -1 for the day before the last day, etc.
That gives you a UNIX timestamp you can use to find out the weekday and then - until you've reached Sunday/Monday (whatever week start you use) - subtract -86400 or call mktime() again with the day reduced by 1.
Example:
mktime(0, 0, 0, 12, -1, 2010); # timestamp of Nov 29th 00:00:00 2010
Related
I have the following example of me subtracting the DateInterval from DateTimeImmutable
$dateA = new DateTimeImmutable('2016-06-30');
$dateB = new DateTimeImmutable('2016-05-31');
$dateInterval = new DateInterval('P3M');
// print 2016-03-30 as expected
echo $dateA->sub($dateInterval)->format('Y-m-d');
// print 2016-03-02 which i would expect 2016-02-29
echo $dateB->sub($dateInterval)->format('Y-m-d');
When I set the period to 'P8M' it works as expected. How it comes, it dosent works for february?
Ok, it's really simple (kind of). Each 'month' interval evaluates to the prior (or X number of prior) month's equivalent day. If there are more days in the current month, than the month being landed on, the excess overflows to the following month.
So if you have a date which is May 31, 2016 and want to subtract 3 month intervals, it will:
Go back 3 months (in the list of months, don't think days yet), resulting in 'February'
Then look for February 31st. This doesn't exist so bleed over to following month 2 days (2016 Febuary has 29 days, so 2 extra days)
Viola! March 2nd.
Go forward, lets say you're in May 31, 2016 and want to add one month
Go forward one month to June.
Look for June 31st, nope, 1 extra day, bleed over to July.
As expected, July 1st is the answer.
The lesson in this: Adding and Subtracting Month intervals sucks, is confusing, and can lead to non-intuitive results unless you've got your month calculation rosetta stone with you.
Explanation from the PHP Docs
Note:
Relative month values are calculated based on the length of months that they pass through. An example would be "+2 month 2011-11-30", which would produce "2012-01-30". This is due to November being 30 days in length, and December being 31 days in length, producing a total of 61 days.
I'm trying to generate random date, any day from 10 to 30 days after the current day and the generated day should not be Saturday and Sunday. I search quite a lot but haven't found the solution for this.
Try:
repeat
day <- pickRandomDay(10 ... 30)
until (not satOrSun(day))
return day
You won't get too many times round the loop.
Is there a simple way of, given a month and a year, establishing:
How many days there are in that month (factoring in leap years) Done
What day of the week the first day fall upon?
See http://php.net/manual/en/function.cal-days-in-month.php
$num = cal_days_in_month(CAL_GREGORIAN, 8, 2003); // 31
and weekdays:
$weekday = date("l", mktime(0,0,0,$month,$day,$year));
$print ($weekday);
The latter is not very efficient but seems nicer than using getdate:
$my_t=getdate(date("U"));
print("$my_t[weekday], $my_t[month] $my_t[mday], $my_t[year]");
Output like
Wednesday, September 29, 2011
You may find the answer to your questions with all needed variables and calculations by going to wikipedia. http://en.wikipedia.org/wiki/Calculating_the_day_of_the_week
Take a look at the date function, particularly date('t') for the number of days in the month (ie the month given in time()) and date('t',$epoch) for the number of days of the month represented by the timestamp $epoch (which, of course, is given in epoch).
And for the day of the week, there's date('l',$epoch) (where the first argument is a lower-case 'L').
I've seen lots of "Date" related questions here, however, I haven't been able to find one that calculates this:
I am trying to figure out the numerical value of a given date string. For example:
$date = "2010-09-01";
Given the date above, how might I be able to determine that this is the "1st" Wednesday of the month.
I know that: date("l", $date); will tell me that it's a Wednesday, but how do I determine if it's the 1st, 2nd, 3rd, or 4th Wednesday of the Month?
Any help on this would be great!
I think this gets you what you want:
$i = (int) (($day_of_month + 6) / 7);
where $day_of_month is from 1 to 31.
You just need a little bit of maths.
If the day of the month is < 8, then it's the first Wednesday. Or Friday. Or Monday. Or Saturday. So if it's between 7 and 15, then it's the second whatever. And so on. #konforce has posted the actual formula.
I need to be able to get the last day of the previous month into a date variable. The script could be run on any day of the current month. It needs to dynamically adjust even if the last day of the previous month falls on 29,30, 31 etc.
What would be the best day to do this?
I'll give a way that none of the duplicates mentioned. mktime supports out-of-range values, so if you ask for 7/40/2010 it'll give you 8/9/2010 instead; you can reverse that and ask for day 0 of the current month to get the last day of the previous:
$lastDayTimestamp = mktime(0, 0, 0, date('n'), 0);