I'm trying to create a recurrence rule with the Google Calendar Api.
[JAVASCRIPT - Google Client Library]
var req = gapi.client.calendar.events.insert({
[...],
"recurrence": [
"RRULE:FREQ=WEEKLY;UNTIL="+date.toISOString()
],
[...]
});
req.execute();
The code above return 400 Bad request, because the recurrence rule is not correctly formatted.
I don't understand how to create a correct date format for the UNTIL field.
I've tried to use a date object and use the ISO conversion but it doesn't work either.
Anyway a single creation for the event works correctly and also a repeat with a COUNT field.
FILE ON GITHUB
There are several rules that apply to UNTIL. First of all, it is not an ISO string but of value DATE or DATE-TIME (https://www.rfc-editor.org/rfc/rfc5545#section-3.3.5). Then you need to pay attention that the DATE value is used if the recurring event start is all-day event and vice versa. At last you need to pay attention to Timezone. The UNTIL must be in the same timezone as your start. I really recommend reading about recurrence rules in the RFC https://www.rfc-editor.org/rfc/rfc5545#section-3.8.5.3
Related
From server I'm getting timestamp like this: " 2022-12-21 16:47:10 ". And I want to convert this time to local time zone, depends on client. E.g. 16:47:10 in Poland was 10am in US. Any ideas how to achieve that? I'm using Vue framework.
From server I'm getting timestamp like this: "2022-12-21 16:47:10"
That represents a date and a time without any time zone or offset. There's no way to tell that it is from Poland from this data alone.
Thus, the first part of your solution would be to change the server-side code to do one of the following:
Emit the time in terms of UTC. For example: "2022-12-21T15:47:10Z". In many cases this is the best choice, especially if your timestamps don't have any meaningful relationship to a local time zone.
Emit the time in terms of a local time, including the time zone offset for that point in time in that time zone. For example, if indeed the value is from Poland, then the server should emit "2022-12-21T16:47:10+01:00" because Poland is one hour ahead of UTC at that date and time.
Emit the time in terms of local time, but include a time zone identifier in a separate field. For example:
{
"datetime" : "2022-12-21T16:47:10",
"timezone" : "Europe/Warsaw",
}
However, this approach could have ambiguities during a backward transition, such as when daylight saving time ends.
Combine the previous two options to resolve ambiguities:
{
"datetime" : "2022-12-21T16:47:10+01:00",
"timezone" : "Europe/Warsaw",
}
This is the most complete form of the data, but generally should only be necessary if your use case is related to scheduling of future events.
For more on use cases for the options above, read DateTime vs DateTimeOffset, which was written for .NET but applies here as well.
As far as the client-side JavaScript goes, for either of the first two options, you can pass the inputs directly to the Date object's constructor, then use methods like toString or toLocaleString. You can also use that approach for the datetime portion of the fourth option.
For the third option though, you'll need to use a library such as Luxon to handle the input time zone identifier. The Date object cannot accept a time zone identifier as input presently. (There is a timeZone option on toLocaleString, but that is for output, not input.)
For example:
const dt1 = luxon.DateTime.fromISO("2022-12-21T16:47:10", {zone: "Europe/Warsaw"});
const dt2 = dt1.toLocal();
console.log(dt2.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/3.1.1/luxon.min.js"></script>
I have a collection elements with documents that contain start date (timestamp data type) and end date (timestamp data type).
If I want to get all elements which end date is greater than today, I do:
firebase.firestore().collection('elements').where('end', '>', new Date()).get();
This works perfectly. Now I want to add a rule with the same check on firestore, to prevent that a malicious user could perform this request with new Date() containing a past date and return expired documents.
I added the following rule to firestore:
match /elements/{document=**} {
allow read: resource.data.end > request.time
}
Now all the queries return FirebaseError: Missing or insufficient permissions and I can't understand why. The query is requesting for all elements that end date is greater than today's date, and the rule is verifying that document's end date is greater than server time. In my mind this should work.
The problem is almost certainly that the client machine's clock does not match the Google server's clock. If the client clock is running even slightly faster than Google's clock, the rule will deny the query.
You could try adding some padding from the date to add a reasonable offset from the current time:
// add 10 seconds from current time so as not to undershoot the end
.where('end', '>', new Date(Date.now() + 10000))
While this might work OK for clients whose clocks are reasonably in sync with world standards, it could still fail if the client's clock is still way off.
I'm working on a scheduling system for music venues. The basic idea is that there's an "Create new schedule" page, on which there is a DatePicker calendar (using AngularUI Bootstrap). The user selects a Date, then adds performers into timeslots. The built object looks something like this:
{
date: 2017-6-22 00:00:00.000-5:00
venue: VenueID
performances: [
{
performer: performerID,
time: 2017-06-22 22:00:23.231-5:00
},{
perfomer: performer2ID,
time: 2017-06-22 23:00:42.523-5:00
}
]
}
There's a couple of problems here. For the original date selection, I set the time (using myDate.setHours(0,0,0,0)) to midnight because the time doesn't really matter, I only care about the actual date. Likewise for the timeslots, their date doesn't matter (since they belong to the schedule for that day), so I only care about the time. Then in another project, we have a node/mongo app that saves these schedules, and returns them to a page in the angular project that lets you select a schedule for editing/etc. It selects which ones to return by grabbing all the schedules for a specific venue, and doing "if (schedule.date >= new Date().setHours(0,0,0,0)) { add schedule to return list }"
Anyway, on to the actual problem. The angular app does all of the date calculations client side. What I mean is, I'm in CST. If I select a Date on the calendar and save a schedule for that date, then someone in EST selects the same day on the calendar and saves a schedule, they have different dates in the database. For example, when I make the schedule, the date in the DB is "2017-06-22 00:00:00.000-5:00". When the EST friend makes a schedule on the same date, it gets saved as "2017-06-22 00:00:00.000-4:00".
In the "Select a schedule to view/edit" page, I do something like this:
<select ng-model="schedule" ng-options="s.date|date:'fullDate' for s in schedules" ng-show="schedules.length>=1"></select>
Of course this doesn't work because when my EST friend looks at the list, he sees the correct date. But when I look at one that he created, the date is one day off because "2017-06-22 00:00:00.000-4:00" converted to local timezone is "2017-06-21 23:00:00.000-5:00".
I guess TL;DR is I'm not sure how to handle it since the venue and anyone creating/editing the schedules may not share the same time zone. I want all of the dates/times to show up in the timezone of the venue (which I have the address for. I guess I could geolocate to find timezone?). I'm just not sure how to go about it.
The DatePicker gives you a date object. Instead of storing the entire value string just grab the day month and year Date(value).getYear() + '-' + Date(value).getMonth() + '-' + Date(value).getDate(). As for the times do the same as the dates. Store those values in the DB and then when you get them back you will have to convert them back to a date object so that the date picker can understand them.
Ultimately with this solution your just trying to store dates without the timezones. Make sure to state in your app that the times are for those areas.
You have to distinguish between the format the date/time is transported, saved vs. how the date will be shown to the user.
For transportation and saving use UTC in a format that is easy computable (eg. ISO8601).
For visualization to the user convert this value to the timezone and desired user format by using some helper library.
I have deployed an action lis with a kind of dashboard. Through this, I would like to highlight the overdue action by adding the status on a dedicated column via javascript. My full script works well except the line where I want to get the Due Date.
For trying to identify the issue, I have simply copied the Due Date in an other column (check column), and the result is surprising!!!
Examples:
Due Date as displawed in the pop-up > Check column interpreted by the JS code
-30/07/2016>27/07/2016 22:00:00
-16/08/2016>17/08/2016 22:00:00
-01/08/2016>03:08:2016 22:00:00
Find hereafter an extract of the code:
var Status = oListItem.get_item('Status');
duedate = oListItem.get_item('DueDate');
oListItem.set_item('Check', oListItem.get_item('DueDate'));
It seems that the issue is related to the orignial Due Date column, qnd linked to a wrong conversion.
Does someone have an idea how to correct this issue?
I have found a solution or work around:
Create a calculated field which recreate the date from the Due Date field
In the JS, get the string from the calculated field, and then split it, et recreate the date with the JS code
Have fun!
I'm trying to use MomentJS to support dates handling in my application. However, I'm facing a problem with date manipulation.
The files are loaded in this order:
<script src="/javascripts/modules/moment/moment.min.js"></script>
<script src="/javascripts/modules/moment/moment-timezone.min.js"></script>
<script src="/javascripts/modules/moment/moment-timezone-data.js"></script>
<script src="/javascripts/modules/moment/moment-with-langs.min.js"></script>
Now in somepart of my JS code I change the moment language to FR or PT.
moment.lang('fr');
Both languages validade a date as "DD/MM/YYYY" instead of american pattern. So I expect moment
to validate a date following the country date pattern passed.
Then 12/10/2014 must be: day (12), month (09), year (2014), but it is returning always american pattern instead of the correct one.
I'm getting the date properties as:
console.log("DAY: " + moment(textDate).date());
console.log("MONTH: " + moment(textDate).month());
console.log("YEAR: " + moment(textDate).year());
where textDate is my date taken from a text input.
## EDIT ##
I know I can pass the pattern to Moment. I.e:
moment(textDate, 'DD/MM/YYYY');
In the case of my application I'm using like this:
moment(textDate, '<%=lingua.general.time.pDate%>');
However, it suppose to work automatically, don't it? Of course if you already have needed language packages as well. So the previous way I mentioned before should Works, whatever.
If you don't pass any formatting arguments, moment will let your browser do the parsing (with the exception of a full ISO timestamp).
To tell moment to do the parsing, and to use the localized short date format associated with the language, pass an L as the format string:
moment(textDate, 'L')
See in the docs:
Parsing using #String+Format
The display formats. Scroll down to "Localized formats". (The parser uses the same format strings)
Also, not related to your question, but moment-with-langs already includes a copy of moment.js, so you don't need both scripts.