Recurring events on a calendar : RFC 5545 Javascript parsing - javascript

I need to integrate recurring events into an adapted version of full-calendar that has an added javascript module which allows offline event browsing.
I'm looking for a javascript library that can parse recurring events according to RFC 5545.
I need to be able to list all recurring events that occur between 2 dates (start date and end date), using RRULE and EXDATE and interpreting daily, weekly, monthly and yearly recurrences.
I've spent hours searching for something to no aval, and I don't want to reinvent the wheel....Can anyone please point me in the right direction for an existing javascript parser?

I checked into skyporters rrule_parser and found that it doesn't support all of the rules (particularly, it won't do BYDAY properly). I found a fantastic alternative:
https://github.com/jakubroztocil/rrule
They are actively supporting this library and have a great demo website that shows all of the functionality. You can parse from either 5545 format or plain text (using the nlp extension). It is feature packed and, as far as I can tell, fully functioning.

look into https://github.com/skyporter/rrule_parser.
I hope it will help you.

here is a recurrence widget for jquery, which parses/creates RFC5545 compatible recurrence strings.
https://github.com/collective/jquery.recurrenceinput.js
it does not expanding of a recurrence rule into occurrence dates, though. but it includes a python server, which can do it for you, using python-dateutil: http://labix.org/python-dateutil

I needed this functionality myself, along with time zone support, so I made a typescript/javascript library: rSchedule.
Currently supports all ICAL recurrence rules except BYSETPOS, BYWEEKNO, and BYYEARDAY. Supports serialization to/from ICAL format along with a ton of extra stuff.
Example:
const rule = new RRule({
frequency: 'YEARLY',
byMonthOfYear: [2, 6],
byDayOfWeek: ['SU', ['MO', 3]],
start: new Date(2010,1,7),
}, {
dateAdapter: StandardDateAdapter
})
let index = 0;
for (const date of rule.occurrences()) {
date.toISOString()
index++
if (index > 10) break;
}
rule.occurrences({
start: new Date(2010,5,7),
take: 5
})
.toArray()
.map(date => date.toISOString())

Related

Kotlin JavaScript Date.now() return type

I was wondering why the Kotlin JavaScript Date class returns a Double for the getTime function. According to the documentation, the getTime function should return the number of milliseconds since 1 January 1970 00:00:00 UTC.
I know that JS doesn't have a 64 bit numeric representation, but since Kotlin emulates Longs I feel like the value returned by Date.now() and Date().getTime() should be a Long. At the very least it would make more sense to return an Int.
Is there any reason that it returns a Double instead of a whole number?
There are two separate reasons for that: consistency and performance.
But before I get into that please note that you can easily get the desired behavior via extensions, e.g.:
inline val Date.time get() = getTime().toLong()
println(Date().time) // 1522757176433
Consistency. As you can see in the Date documentation page, it an external class. Which means it just describes an existing JavaScript API. Is it a good design decision to reuse it as it? Maybe not. But it has a benefit of being familiar to the JS folks. Changing the return type of a single function ruins that and makes the whole API quite inconsistent.
Performance. It is possible hide the original getTime and create a helper function instead. But keep in mind that in order to emulate Long Kotlin creates an object with 2 Number's. Creation, comparison, binary operations, storage - emulated Long's perform a lot worse than native JS Numbers.
Summing up. Changing the return type would make the API inconsistent and inefficient. If you value semantics over performance, just write a few helper functions.
P.S. I think the Date API will be redesigned at some point to make it possible to use it in multiplatform projects. But that's another story.
In kotlin use Date().time .It will return the long Values you will get whole number
val s= Date().time
print(s)
for example
val date = "01-02-2018 07:05:00.999"
val fmt = SimpleDateFormat("MM-dd-yyyy HH:mm:ss.S") //parse date based your format
var myDate: Date? = null
try {
myDate = fmt.parse(date)
} catch (e: ParseException) {
e.printStackTrace()
}
println(myDate)
val timestamp = myDate!!.time //timestamp values in long only not double
println(timestamp)

Add o'clock/Uhr to a globalize.js formatted date

Pretty simple question: I want to add a switch to my globalize format skeleton, so that it adds an "o'clock" or German "Uhr" after the time. Right now, I'm using the following pattern:
yMMddHHmm
I found the o'clock string in the respective cldr files, but I don't know how to add them to the skeleton.
Here's my code:
Globalize.formatDate(dTermin, { skeleton: 'yMMddHHmm' });
Thank you in advance for your help!
There's no skeleton that would give you "o'clock" kinda output [1]. Although, if you really want that format and are willing to provide the i18n data for all the locales you think could support it you can use globalize's raw option like:
// Not recommended anyway...
if (locale === "en") {
formatter = globalize.dateFormatter({raw: "HH 'o''clock'"});
}
Though, it's usually a not recommended approach since you have to maintain this list of custom formatters yourself.
1: In order to check, I've grep'ed the whole CLDR and found no match.

Is there a way to get the decimal and thousands separator in ECMAscript Internationalization API?

I'm trying to use the new Javascript internationalization API, and would like to know if there is a way to get the decimal and thousands (grouping) separator for a Intl.NumberFormat instance?
There is a resolvedOptions method on the object, but that does not provide the symbols.
In case anybody's wondering, then for en-US, these would be a comma , and period ., such as in 1,000.00.
If nothing else, as a trick solution (that doesn't pass the Turkey Test; see comment), you can use the output of toLocaleString() to determine information about number formatting in a locale. For the current locale, for example:
var decimalSeparator =
(12345.6789).toLocaleString().match(/345(.*)67/)[1];
var thousandSeparator =
(12345.6789).toLocaleString().match(/12(.*)345/)[1];
var numberOfDecimals =
(12345.6789).toLocaleString().match(/345(\D*)(\d+)$/)[2].length;
The same trick can be used for currency formatting, using e.g. (12345.6789).toLocaleString("en-GB", { style: "currency" }).
I'm afraid ECMA-402 standard does not define the API that let you access separators. There is also another problem - at the moment the adoption of ECMA-402 is not as wide as we wish.
Therefore for the time being, if I were you I would look to something like CLDR JSON bindings or iLib which apparently provides these information through LocaleInfo's getDecimalSeparator() and getGroupingSeparator() functions.
BTW. iLib seems to use CLDR as a source of information.

Very custom date format in momentjs

I am working with kibana (elasticsearch dashboard) which allow to specify a date pattern to explain the index naming pattern.
For instance, default pattern is: [logstash-]YYYY-MM-DD.HH
I'd like to organize my index by block of hours, let's say by block of 4 hours. Indices would then be named logstash-2014-02-25.00, logstash-2014-02-25.04, logstash-2014-02-25.08, …
Is there any way to get such format with momentjs ? I am dreaming of [logstash-]YYYY-MM-DD.{HH%4}
but the documentation does not explain such thing (how weird).
It seems impossible to do it with formatting primitives.
However, I found we can override some of the language-dependant formatter such as meridiem formatter.
A solution would then be to insert somewhere (in kibana conf file for example):
moment.lang('fourHourblocks', {
meridiem: function(hour, minute, isLowercase) {
hourBlock = Math.floor(hour / 4).toString();
if (hourBlock.length < 2) hourBlock = "0" + hourBlock;
return hourBlock;
}
}
then I can set the pattern to [logstash-]YYYY-MM-DD.A.
This is kind of hacky so I am still opened to other solutions

Parse ONLY a time string with DateJS

I'm using the excellent (but large) DateJS library to handle dates and times in my webapp. I just came across something that I'm not sure how to handle.
I want my users to be able to enter Time strings only, without a date, but they should be able to enter it in any manner they please. For instance:
5:00 pm
17:00
5:00pm
5:00p
5p
etc.
Using Date.parse(value) converts these strings into a full date, which is exactly what I want. However, it also allows the user to enter any other part of a date string, such as:
sat 5pm
1/1/2010 5pm
etc.
I'm trying to use DateJS to validate an input field for a time value. Something like:
function validateTime(value) {
return Date.parse(value) !== null;
}
Is there a way to use DateJS features to solve this? There are other SO questions that provide solutions, but if DateJS has a way to do this, I don't really want to add more custom code to my app to do this.
Shortly after asking my question, I discovered that Date.parseExact() can take an array of format strings. Somehow I'm missed that. I managed to get something working with the following code:
function validateTime(input) {
return Date.parseExact(input, [
"H:m",
"h:mt",
"h:m t",
"ht","h t"]) != null ||
Date.parseExact(input, [
"h:mtt",
"h:m tt",
"htt","h tt"]) != null;
};
Note that some formats don't seem to be able to be included together at the same time, which is why I split them into two separate parseExact() calls. In this case, I couldn't include any string that contained a single t in it with format strings that contained a double tt in it.
The additive approach seems cumbersome. Takes away the beauty of DateJS in my opinion. I needed the same solution and decided to just sneakily append the date in front of my input string before parsing with DateJS:
var parsed = Date.parse(Date.today().toString('M/d/yyyy') + ' ' + this.value);
if (parsed) {
alert(parsed.toString('h:mm tt'));
}
Now DateJS will not be sniffing around for any of its date-part parsing patterns, as you have already subbed it in.
Hope this helps someone!

Categories