What is the best way to write an rrule that is Tuesday after the third Monday each June?
Currently I write the rule like this:
rule_mo = rrule(freq=YEARLY,
bymonth=6,
byweekday=MO(+3),
...)
rule = (x + relativedelta(weekday=TU(+1)) for x in rule_mo)
Is there a way to write this entire rule using just the rrule and not having to use the second pass with the relativedelta?
Reference : http://jkbr.github.io/rrule/
rule = RRule.fromText("every June on 3rd Tuesday")
rule.origOptions
{
freq: RRule.YEARLY,
bymonth: [6],
byweekday: [RRule.TU.nth(3)]
}
rule.toString()
FREQ=YEARLY;BYMONTH=6;BYDAY=+3TU
rule.toText() every June on the 3rd Tuesday
Related
How can I in a smart way get the first business day of a month after the weekend?
To get the first business day of the month (given dateInput), we can do:
firstBusdayMonth = fbusdate(year(dateInput),month(dateInput));
As an example, for November, using the above function will return Thursday November 1 as the first business day. However, the first business day of the month after the first weekend is Monday November 5. How can I get this latter date?
Notes:
The weekend does not have to be in the same month.
If the Monday is not a working day, then I would like it to return the next business day
This function will do the trick. Here is the logic:
Create a datetime array for all days in the given month.
Get the day numbers.
Create a logical array, true from the first Monday onwards (so after the first weekend, accounting for the last day of the previous month being a Sunday).
Create another logical array using isbusday to exclude Mondays which aren't working days.
Finding the first day number where these two logical arrays are true, therefore the first business day after the weekend.
Code:
function d = fbusdateAferWE( y, m )
% Inputs: y = year, m = month
% Outputs: day of the month, first business day after weekend
% Create array of days for the given month
dates = datetime( y, m, 1 ):days(1):datetime( y, m, eomday( y, m ) );
% Get the weekday numbers to find first Monday, 1 = Sunday
dayNum = weekday( dates );
% Create the logical array to determine days from first Monday
afterFirstWeekend = ( cumsum(dayNum==2) > 0 ).';
% Get first day which is afterFirstWeekend and a business day.
d = find( afterFirstWeekend & isbusday( dates ), 1 );
end
You could probably speed this up (although it will be pretty rapid already) by not looking at the whole month, but say just 2 weeks. I used eomday to get the last day of the month, which means I don't have to make assumptions about a low number of holiday days in the first week or anything.
Edit: Working with datenum speeds it up by half (C/O JohnAndrews):
function d = fbusdateAferWE( y, m )
% Inputs: y = year, m = month
% Outputs: day of the month, first business day after weekend
% Create array of days for (first 2 weeks of) the given month
dates = datenum(datetime(y,m,1)):datenum(datetime(y,m,eomday(y,m)))-14;
% Get the weekday numbers to find first Monday, 1 = Sunday
dayNum = weekday( dates );
% Create the logical array to determine days from first Monday
afterFirstWeekend = ( cumsum(dayNum==2) > 0 ).';
% Get first day which is afterFirstWeekend and a business day.
d = find( afterFirstWeekend & isbusday( dates ), 1 );
end
I would add something like this after your statement:
[DayNumber, DayName] = weekday(firstBusdayMonth);
if DayNumber > 2
day = 10 - DayNumber;
else
This works because 'weekday' will return a number between 1 (Sunday) and 7 (Saturday).
The fbusdate() function will never return a 1 or 7, so we can ignore those cases.
If weekday(fbusdate()) == 2, the first is on a Monday and the firstBusdayMonth variable doesn't need to be changed.
If weekday(firstBusdayMonth) returns between 2 and 6, we need to skip to the next week, so we subtract the weekday value from 10 to find the next Monday.
It might not be the most elegant solution, but should work.
We can use fbusdate to get the first business day of a month:
Date = fbusdate(Year, Month);
However, how do we get the first business day of a week?
As an example, during the week that I'm posting this, Monday 09/07/2017 was a holiday in the US:
isbusday(736942) % = 0
How do I determine that the first business day for this week would be the next day 736943?
I'm not aware of a builtin function that returns the first working day of a week, but you can obtain it by requesting the next working day after Sunday:
busdate(736941); % 736941 = Sunday 09/03/2017
Your desired fbusdateweek function can be done in one line using just the function weekday to get the first Sunday of the week then busdate to get the next business day after that:
dn = 736942; % Date number for any day in a week
Date = busdate(dn-weekday(dn)+1);
Note: busdate uses the function holidays by default to get all holidays and special nontrading days for the New York Stock Exchange. If necessary, you can define an alternate set of holidays for busdate to use as follows:
holidayArray = ...; % Some set of date numbers, vectors, or datetimes
Date = busdate(dn-weekday(dn)+1, 1, holidayArray);
This way you can define a set of localized holidays.
Solved it. Here is a function that is based on the answer of #m7913d:
function Busday = fbusdateweek(date)
% Return the first business day after Sunday
% 'date' is a datenum input
dperiod = date-6:date;
sundays = weekday(dperiod)==1;
sunday = find(sundays==1,1,'first');
datesunday = dperiod(sunday);
% -->
Busday = busdate(datesunday);
end
I have a nice idea of an app and I am new in swift. The app is about a week schedule, you can add some things you have to do in a schedule.For example, on Monday you have to clean the bathroom and get milk. You can add this two things to the day plan for Monday. But my really problem is that I want the app to show the schedule of the current day when you open it. I don't have any idea how to check the day of the week so the schedule when you open the app is for the current day. It will be easy if I add a label named dayname on the top and it should show the name of the current weekday !!
I did not try it, but this post seems to be clear with enough details and examples dealing with dates in Swift. Check it HERE
here is an example from the same source working with NSDateComponents weekday property:
// First Saturday of March 2015, US/Eastern
let firstSaturdayMarch2015DateComponents = NSDateComponents()
firstSaturdayMarch2015DateComponents.year = 2015
firstSaturdayMarch2015DateComponents.month = 3
firstSaturdayMarch2015DateComponents.weekday = 7
firstSaturdayMarch2015DateComponents.weekdayOrdinal = 1
firstSaturdayMarch2015DateComponents.hour = 11
firstSaturdayMarch2015DateComponents.minute = 0
firstSaturdayMarch2015DateComponents.timeZone = NSTimeZone(name: "US/Eastern")
// On my system (US/Eastern time zone), the result for the line below is
// "Mar 7, 2015, 11:00 AM"
let firstSaturdayMarch2015Date = userCalendar.dateFromComponents(firstSaturdayMarch2015DateComponents)!
It says :
NSDateComponents‘ weekday property lets you specify a weekday
numerically. In Cocoa’s Gregorian calendar, the first day is Sunday,
and is represented by the value 1. Monday is represented by 2,
Tuesday is represented by 3, all the way to Saturday, which is
represented by 7.
I would like to check if a given date is the first, second, third, fourth or last monday, tuesday, wednesday,..., sunday in the dates month.
The function should look like this:
if(checkdate(date, "second", "monday"))
{
alert("This is the second monday of the month");
}
else
{
alert("This is NOT the second monday of the month");
}
I would rather write a function that returns an object telling me the day and the week-number-in-month of the given date. Something like:
function infoDate(date) {
return {
day: date.getDay()+1,
week: (date.getDate()-1)%7+1
}
}
Then I can read the returned object and find out if it's the second monday or whatever:
var info = infoDate(date);
if(info.day==1 && info.week==2) {
// second monday
}
Of course, you can still write another localized function that does exactly what you ask for based on an array of numeral and day names.
use getDate() to get day of the month
then getDay() to get the day of the week
using these two you should be able to accomplish your task. Refer to this http://www.w3schools.com/jsref/jsref_obj_date.asp
It seems to me you only need to divide the date by 7 to know how many full weeks have passed, no matter what day it is. Subtracting one before dividing and adding it after sets the first week from 0 to one.
Date.prototype.weekofMonth= function(){
return Math.floor((this.getDate()-1)/7)+1;
}
alert(new Date().weekofMonth())
I'm aware that there are several Cocoa Touch/iPhone calendar implementations available online, but for certain reasons I'm trying to create my own. I'm running into an issue where the code that I use to lay out the dates (which I represent as instances of UIView placed as subviews into another UIView) is messing up in December.
Currently, what I do is decompose the date into an instance of NSDateComponents, then get the week and weekday properties of the components to figure out the X and Y "positions" of the date view, respectively. I can offset the X position by the week property for the first day of the month I'm laying out.
Brief example: the first day of August 2009 falls on a Saturday, and its date components' week property is 31 (using a Gregorian calendar). Therefore its Y position is 6 and its X position is 0, and the X offset I'll be using is 31. So I can take the second day of August, which is a Sunday, and determine that its X position is 0 and its Y position is week - 31 = 32 - 31 = 1. This way I can lay out a zero-indexed grid of date views for the month of August, and it all goes swimmingly...
...until I try to do the same for December. In December of 2009, apparently the week property wraps to 1 on the 27th (a Sunday), meaning that I wind up trying to place the 27th through the 31st at Y positions -48 or so.
My question is twofold: why does the week property wrap partway into the last month of the year? Is it indexed at the last Sunday of the previous year, rather than the first day of the year? And second, is there a better way to lay out a date grid like this (using other components from an NSDateComponents instance, or anything else I can get from an NSDate and an NSCalendar), or do I just have to add a check for the "last week of year" condition?
The last few days in December start to belong to week 1 of the next year. (see here)
Instead of using the week property to calculate the weekday positions, I'd just start with Y=0 and then increase it after each Saturday (if your week starts on Sundays)
int x = <calculate x based on the weekday of the 1st of the month>
int y = 0
for (days in month) {
<add subview for this day>
x += xOffset
if (currentWeekday == saturday) {
x = 0
y += yOffset
}
}
P.S.: I'd probably look at the current locale to determine the first weekday:
NSLocale *locale = [NSLocale currentLocale];
NSCalendar *calendar = [locale objectForKey:NSLocaleCalendar];
NSUInteger firstWeekday = [calendar firstWeekday];
I probably wouldn't use weeks in my calculation. You need to lay out the days in rows of 7, which of course we know conceptually as weeks. Practically you should be able to get away just knowing the day of the year and doing a modulus.
Say the year starts on Sunday (column 1) and you want know the position of the 100th day. Well 100 / 7 = 14 with a remainder. So it is in the 14th row. Then do a mod 100 % 7 = 2. So it falls on a Monday (in my example).