我们需要在浏览器上使用JavaScript来读取和解析日历文件(.ics)(也称为iCal格式)。我编写了一个自定义函数来读取这些值,然后使用 JavaScript Date() 函数创建一个数据对象。
有没有更简单、更好的方法来做到这一点?请看我的功能(下面),欢迎您的评论。
.ics 文件中的典型日期值如下所示:
DT开始:20110914T184000Z
需要在结肠处将其分开,所以:
var strData = 'DTSTART:20110914T184000Z'
var x = strData.indexOf(":");
var strVal = strData.slice(x + 1 );
接下来,调用返回日期对象的函数:
var dateObj = calenDate(strVal);
//结果 dateObj 值:2011 年 10 月 14 日星期五 18:40:00 GMT-0400(东部夏令时间)
这是解析日期的函数。
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;
}
我认为出了问题,因为月份错误。
出于某种奇怪的原因,月份参数是从零开始的(reference)。
更改函数中的这一行。
var strMonth = icalStr.substr(4,2);
对此:
var strMonth = parseInt(icalStr.substr(4,2),10)-1;
查看 jsFiddle 上的工作演示:http://jsfiddle.net/cTkTQ/
解析日期的更可靠的方法是:
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));
这需要您添加一个额外的(微小)依赖项XRegExp,根据您的进一步需求,这可能有点过大,但它允许对 .ics 文件中的日期格式进行干净、易于阅读的正则表达式解析。如果日期不是 UTC,这还会考虑时区标识符。我将其留给您来添加对时区的正确处理以及
prefix
部分的使用。
简短的答案(如 jessegavin 所指出的)是,构造函数的
month
参数需要一个 0-11 之间的数字(请参阅 Mozilla Developer Network 了解更多信息)。但是,parseInt()
尝试将前导零解析为radix 8
(八进制),因此您应该确保也添加radix 10
,这将是parseInt(string [, radix])
的第二个参数。
这是一个新包(带有测试),似乎运行良好:ical-date-parser
import iCalDateParser from 'ical-date-parser';
iCalDateParser('20140422T233000Z');
С完整的解决方案:
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));
}