Background: where I park my car, during the winter it is cleaning day once a week (=parking is not allowed) so I have to move the car before that to avoid getting a ticket. I want to create an iCal reminder about that but the pattern is very complicated.
The season starts Nov 1 and ends May 15.
Only weekdays are cleaning nights.
There are two repeating patterns, yearly (Nov to May) and every 4/6 days (see the examples below for details)
Examples:
I am parked on a street where Wednesday is the cleaning day (i.e., "Wednesday street") so Tuesday evening I move the car to a street that just was cleaned (i.e., a "Tuesday street"). Every week the day I have to move the car is moved forward one day. The repeating pattern is "every 6th day".
However, if I have parked on a Monday street, the situation is different - then I want to move the car on the Friday, not the Sunday. Suddenly the repeating pattern is "every 4th day".
I have read this question Can iCal schedule an event for the first weekday after BYMONTHDAY if BYMONTHDAY is a weekend? and have figured out a couple things:
I can set BYMONTH=11,12,1,2,3,4,5 to limit it to Nov to May.
BYDAY=MO,TU,WE,TH,FR limits it to weekdays
but after that I am stuck. I have been playing around at http://recurrence-expansion-service.appspot.com/ with different combinations but so far without success.
How do I limit it to mid-May?
How do I write a rule that "skips" the weekends when I have parked on a Monday street?
How do I achieve two repeating patterns (a yearly pattern - Nov to May - and a 4/6 day pattern)?
Related
I want to get first day of week for specificid ZonedDateTime in NodaTime.
But week starts Saturday in Persian calendar and Monday in Gregorian calendar.
How can I get first day of week based on calendar of ZonedDateTime?
We don't expose that information, because it's not as cut and dried as you expect it to be. Different cultures and contexts use different week rules - for example, while you've stated that the week starts on Monday in the Gregorian calendar, that's context specific. In many contexts Sunday is used as the first day of the week instead.
See the week numbering part of the Wikipedia article on weeks for examples of this.
It sounds like you'll probably want a Dictionary<CalendarSystem, IsoDayOfWeek> or possibly a Dictionary<CalendarSystem, IWeekYearRule> in your application, depending on what you're trying to achieve.
This should be a 2 hour 50 minute event starting at 5pm PST on a thursday evening repeating weekly. When imported into google calendar or Evolution, the first occurrence is correct, but subsequent weeks have the event on Wednesdays.
DTSTART:20170908T000000Z
DTEND:20170908T025000Z
RRULE:FREQ=WEEKLY;UNTIL=20171201T080000Z;BYDAY=TH
Other events that my application generate occur on multiple days i.e. BYDAY=TH,TU so simply removing the BYDAY is not a solution for my problem.
You are mixing up the timezone of the event and the display timezone. As far as recurrence calculation goes, the only thing that counts is the timezone that you declare in the VEVENT. Here you are using UTC. So:
The first instance is on the 20170908 which is a Friday. From there, you ask for a recurrence every thursday. The next thursday after 20170908 is 20170914, so the next instance starts on 20170914T000000Z.
When viewed with a display timezone of PST, this event has indeed its first instance on Thursday evening. But the second instance, as calculated above, is on a Thursday UTC time, so on a Wednesday PST time.
Besides this particular issue, you also need to worry about daylight saving changes. If your event is really taking place in PST timezone, the event, as expressed above will see its time change in November, after the DST transition takes place.
Hence it is almost never a good idea to express a recurring event by using UTC (Zulu) time.
You should have your event expressed in local time with timezone, i.e. use:
DTSTART;TZID="America/Los_Angeles":20170907T170000
In Brazil my payday happen on every 5th day of month.
But if the 5th day is a saturday/sunday, then the payment will happen on the 4th day.
Same if 4th is saturday/sunday: then the payment will happen on 3rd day. And so on.
Is there any way to create a event that will work with Google Calendar and iCal?
You can achieve that with iCalendar, at least as far as it concerns weekends.
Consider the following rule:
DTSTART;TZID=US-Eastern:20160505T000000
RRULE:FREQ=MONTHLY;BYMONTHDAY=1,2,3,4,5;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1
The rule is evaluated as follows:
FREQ=MONTHLY;BYMONTHDAY=1,2,3,4,5: expand to the 1st, 2nd, 3rd, 4th and 5th day of each month
BYDAY=MO,TU,WE,TH,FR: filter by week day, retain only work days/remove weekend days
BYSETPOS=-1: retain only the last day of the set
You can verify the result at http://recurrence-expansion-service.appspot.com/
Here are the first 100 instances.
It's not possible to achieve that for holidays though.
Update:
It's actually sufficient to specify
RRULE:FREQ=MONTHLY;BYMONTHDAY=3,4,5;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1
Since the weekend is at most 2 days long, payday must fall on one of the 3rd, 4th or 5th day of the month. Again, this does not take holidays into account.
Holidays always need special consideration. Not only does RRULE not support this kind of logic for arbitrary days, sometimes it's difficult or even impossible to express holidays by an RRULE themselves. In some countries certain holidays are always on a specific day, except when the days falls on a weekend, in which case the holiday is on the Friday before or the Monday after the weekend. Or consider the Easter date and holidays relative to the Easter date, they can't be expressed by an RRULE at all.
Not to forget that some holidays may change every now and then (like "King's days" or "Queen's days" in certain countries).
The best you can do is to manage these manually and add an RDATE and an EXDATE if payday would fall on a holiday according to the RRULE above.
I am trying to add a feature on one of my applications. Here is a sample:
Company ABC
Business hours:
Sunday closed
Monday 7am - 5pm
Tuesday 7am - 5pm
Wednesday 7am - 5pm
Thursday 7am - 5pm
Friday 7am - 5pm
Saturday closed
Company DEF
Sunday 10am - 12pm
Monday 8am - 4pm
Tuesday 8am - 4pm
Wednesday 8am - 4pm
Thursday 8am - 4pm
Friday 8am - 4pm
Saturday closed
Now, what I want to do is to have my users be able to search/filter the business hours. For example, only return businesses who are open during Monday 2PM, or Saturday 1PM, or Monday any time.
My idea is to use datetime in SQL Server, but it appears I may need to create 7 columns for each day (Sunday to Saturday) and different columns for Starting time to open to Closing time to open.
The next idea is to make these columns searchable such that I will be able to filter them. for example, if a user searches for Monday 12PM, the search will be Monday (open time) <= (user search, 12pm) <= (close time).
So basically, it will be similar to:
SELECT *
FROM Companies
WHERE [user_search_time] IS "BETWEEN open_time AND close_time WHERE day=[user_search_day]
I'm having a hard time designing this, let alone how to implement it.
Technology used is C#/ASP.Net and SQL Server 2008.
The problem is how to design/implement this feature using the technologies mentioned above.
Any idea/tips will be appreciated. Thanks!
Might want to push this to codereview, or programmers. I think you are on the right path, but instead of adding columns, add a new table. called business_hours
BUSINESS_HOURS
business (company fk)
open_time (datetime)
close_time (datetime)
day (M,T,W,TH,F,S,Sun) // you can do this however u want 1-7 would work as well
Then your query is almost the same as what you have.
SELECT *
FROM
business_hours
WHERE
business = user_company_id
[user_search_time] IS BETWEEN open_time AND close_time and
day=[user_search_day]
Benefits to a table is it's more denormalized and you could support hours that have breaks in them. I could suport 12-2 as well as 5-8. You would just insert a new record and it would work. I am not a big fan of doing all day by doing a range from 12AM to 12PM but it will work, and keep your design simple.
I'm writing an application that indexes data for our stores, some of which are open late (8 am - 2 am). We need to be able to search this database quickly -- basically, to run a query to find which stores are open at a given point in time (now, Sunday at 1 am, whatever).
In addition, the open/close times can vary day-by-day -- some stores are closed on Sundays, for example.
The obvious solution to me would be to make a table where I have a row with the store ID, day, open time, and close time. For something like Monday, 8 am - 2 am, that would actually be two rows, one for Monday 0800 - 2400, and one for Tuesday 0000 - 0200.
We have a lot of stores, so the search has to perform well (basically, the data has to be index-friendly), but I'll also have to display this data back out in a human-readable format. With my current solution, that'd look something like this:
Monday: 8:00 - Midnight
Tuesday: Midnight - 2:00 am; 8:00 am - Midnight
I'm just wondering if anybody else has alternative solutions before I jump right to an implementation. Thanks!
When PBS (the US Public Broadcasting System) faced this same problem a couple of years ago, they invented the idea of the "30 hour day" -- Where 00:00 is midnight at the start of the day, 24:00 is midnight at the end of the day, 25:00 is 1am the next day, 30:00 is 6am the next day. That way Mon closing time of 26:00 is 2am Tues morning.
Rather than two records representing a single store's times for a day, it may be more object oriented to think of the "store day" as the object. That way 1 record = 1 store's times for a day. If you want to store the two sets of open/close times, just use four fields in the record instead of two--and adjust your queries appropriately.
Remember that your queries should use a library/api that you write and publish. The library will then deal with the data store and its data layout. No one but your library should be looking at the db directly.
Time zones are very important in this sort of app too. (Hopefully) at some point, the store chain will expand to cover more than one time zone. You'll then need to determine the local time of the query. -- May not the same as the time zone of your server which is handling the queries.
Further thoughts--
I now see that you're standardizing to GMT. Good. You could also use datetime values (vs time values) and standardize to a given week in time. Eg open time is Sun Jan 1, 1995 10am - Mon Jan 2, 1995 2am (using Jan 1, 1995 as a base since it was a Sunday).
Then rationalize your "current time and date" to match the same point in the week of Jan 1, 1995. Then query to find open store days.
HTH,
Larry