如何用JavaScript解析日历文件日期?
我们需要在浏览器上使用JavaScript来读取和解析日历文件(.ics)(也称为iCal格式)。我编写了一个自定义函数来读取这些值,然后使用JavaScript Date()函数生成一个数据对象 有没有更简单更好的方法?请看我的功能(下面),欢迎您的评论 .ics文件中的典型日期值如下所示: DTSTART:20110914T184000Z 需要在结肠处将其分开,因此:如何用JavaScript解析日历文件日期?,javascript,calendar,icalendar,Javascript,Calendar,Icalendar,我们需要在浏览器上使用JavaScript来读取和解析日历文件(.ics)(也称为iCal格式)。我编写了一个自定义函数来读取这些值,然后使用JavaScript Date()函数生成一个数据对象 有没有更简单更好的方法?请看我的功能(下面),欢迎您的评论 .ics文件中的典型日期值如下所示: DTSTART:20110914T184000Z 需要在结肠处将其分开,因此: var strData = 'DTSTART:20110914T184000Z' var x = strData.index
var strData = 'DTSTART:20110914T184000Z'
var x = strData.indexOf(":");
var strVal = strData.slice(x + 1 );
接下来,调用一个返回日期对象的函数:
var dateObj = calenDate(strVal);
//结果日期OBJ值: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;
}
我认为有点不对劲,因为它把月份弄错了。出于某种奇怪的原因,month参数是以零为基础的() 在函数中更改这一行
var strMonth = icalStr.substr(4,2);
为此:
var strMonth = parseInt(icalStr.substr(4,2),10)-1;
请参阅JSFIDLE上的工作演示:解析日期的更健壮的方法是:
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));
var parser=XRegExp(“^(?[^:;]+)#DTSTART/DTEND/DTSTAMP\n\
(:;TZID=(?[^::+):)#时区\n\
(?[0-9]{4})年\n\
(?[0-9]{2})#月\n\
(?[0-9]{2})T#天\n\
(?[0-9]{2})小时\n\
(?[0-9]{2})分钟\n\
(?[0-9]{2})秒\n\
(Z?)#utc,“x”);
parts=parser.exec(d);
var od=新日期(parseInt(parts.year,10),
parseInt(parts.month,10)-1,
帕塞因特(parts.day,10),
parseInt(部分小时,10),
parseInt(parts.minute,10),
parseInt(parts.second,10));
这要求您添加一个额外的(微小的)依赖项,这可能有点过分,取决于您的进一步需要,但它允许对.ics文件中的日期格式进行干净、易于阅读的regexp解析。如果日期不是UTC,这也会考虑时区标识符。我让您添加对时区的正确处理以及前缀的使用
但是,简单的回答(正如jessegavin所指出的)是,构造函数的month
-参数期望一个介于0-11之间的数字(有关更多信息,请参阅)。但是,parseInt()
尝试将前导零解析为基数8
(八进制),因此您应该确保也添加基数10
,这将是parseInt(字符串[,基数])的第二个参数。
这是一个新的包(带有测试),似乎工作正常:
用法
月份是以零为基础的吗?谢谢你指出这一点!我没有在RFC 5545中看到它。很抱歉评论这个僵尸评论,但我只想指出,不是iCal(RFC 5545)中的月份是零基的,而是javascript日期月份。很好,不需要所有这些变量,直接进入日期构造函数
import iCalDateParser from 'ical-date-parser';
iCalDateParser('20140422T233000Z');