We need to use JavaScript on the browser to read and parse calendar files (.ics) (also called iCal formats). I wrote a custom function to read these values and then use the JavaScript Date() function to make a data object.
Is any easier and better way to do this? Please look at my function (below), your ments would be wele.
A typical date value from an .ics file looks like this:
DTSTART:20110914T184000Z
Need to break it apart at the colon, so:
var strData = 'DTSTART:20110914T184000Z'
var x = strData.indexOf(":");
var strVal = strData.slice(x + 1 );
next, call a function that returns a date object:
var dateObj = calenDate(strVal);
//resulting dateObj value: Fri Oct 14 2011 18:40:00 GMT-0400 (Eastern Daylight Time)
Here is the function that parses the date.
function calenDate(icalStr) {
// icalStr = '20110914T184000Z'
var strYear = icalStr.substr(0,4);
var strMonth = icalStr.substr(4,2);
var strDay = icalStr.substr(6,2);
var strHour = icalStr.substr(9,2);
var strMin = icalStr.substr(11,2);
var strSec = icalStr.substr(13,2);
var oDate = new Date(strYear,strMonth, strDay, strHour, strMin, strSec)
return oDate;
}
I think something is wrong since it is getting the month wrong.
We need to use JavaScript on the browser to read and parse calendar files (.ics) (also called iCal formats). I wrote a custom function to read these values and then use the JavaScript Date() function to make a data object.
Is any easier and better way to do this? Please look at my function (below), your ments would be wele.
A typical date value from an .ics file looks like this:
DTSTART:20110914T184000Z
Need to break it apart at the colon, so:
var strData = 'DTSTART:20110914T184000Z'
var x = strData.indexOf(":");
var strVal = strData.slice(x + 1 );
next, call a function that returns a date object:
var dateObj = calenDate(strVal);
//resulting dateObj value: Fri Oct 14 2011 18:40:00 GMT-0400 (Eastern Daylight Time)
Here is the function that parses the date.
function calenDate(icalStr) {
// icalStr = '20110914T184000Z'
var strYear = icalStr.substr(0,4);
var strMonth = icalStr.substr(4,2);
var strDay = icalStr.substr(6,2);
var strHour = icalStr.substr(9,2);
var strMin = icalStr.substr(11,2);
var strSec = icalStr.substr(13,2);
var oDate = new Date(strYear,strMonth, strDay, strHour, strMin, strSec)
return oDate;
}
I think something is wrong since it is getting the month wrong.
Share Improve this question asked Dec 28, 2011 at 15:44 TGanoeTGanoe 3491 gold badge3 silver badges10 bronze badges4 Answers
Reset to default 8For some odd reason the month parameter is zero-based (reference).
Change this line in your function.
var strMonth = icalStr.substr(4,2);
to this:
var strMonth = parseInt(icalStr.substr(4,2),10)-1;
See working demo on jsFiddle: http://jsfiddle/cTkTQ/
A somewhat more robust way of parsing the dates would be:
var parser = XRegExp("^ (?<prefix> [^:;]+ ) # DTSTART/DTEND/DTSTAMP \n\
((:|;TZID=(?<tz>[^:]+):)) # timezone \n\
(?<year> [0-9]{4} ) # year \n\
(?<month> [0-9]{2} ) # month \n\
(?<day> [0-9]{2} ) T # day \n\
(?<hour> [0-9]{2} ) # hour \n\
(?<minute> [0-9]{2} ) # minute \n\
(?<second> [0-9]{2} ) # second \n\
(?<utc> Z? ) # utc", "x");
parts = parser.exec (d);
var od = new Date (parseInt (parts.year, 10),
parseInt (parts.month, 10) - 1,
parseInt (parts.day, 10),
parseInt (parts.hour, 10),
parseInt (parts.minute, 10),
parseInt (parts.second, 10));
This requires you to add an additional (tiny) dependency, XRegExp, which might be a bit overkill depending on your further needs, but it allows for a clean, easy to read regexp parsing of the date format in .ics files. This also takes into account the time zone identifier, if the date is not UTC. I leave it to you to add proper handling of time zones as well as the use of the prefix
part.
The short answer (as noted by jessegavin) however, is that the month
-parameter of the constructor expects a number between 0-11 (refer Mozilla Developer Network for more information). However, parseInt()
tries to parse leading zeros as radix 8
(octal), so you should make sure to add radix 10
too, that would be the second parameter to parseInt(string [, radix])
.
This is a new package (with tests) that seems to work well: ical-date-parser
Usage
import iCalDateParser from 'ical-date-parser';
iCalDateParser('20140422T233000Z');
Сomplete solution:
function parseICalDate(date) {
const year = date.substr(0, 4);
const month = parseInt(date.substr(4, 2), 10) - 1;
const day = date.substr(6, 2);
const hour = date.substr(9, 2);
const minute = date.substr(11, 2);
const second = date.substr(13, 2);
return new Date(Date.UTC(year, month, day, hour, minute, second));
}