如何用JavaScript解析日历文件日期?

如何用JavaScript解析日历文件日期?,javascript,calendar,icalendar,Javascript,Calendar,Icalendar,我们需要在浏览器上使用JavaScript来读取和解析日历文件(.ics)(也称为iCal格式)。我编写了一个自定义函数来读取这些值,然后使用JavaScript Date()函数生成一个数据对象 有没有更简单更好的方法?请看我的功能(下面),欢迎您的评论 .ics文件中的典型日期值如下所示: DTSTART:20110914T184000Z 需要在结肠处将其分开,因此: var strData = 'DTSTART:20110914T184000Z' var x = strData.index

我们需要在浏览器上使用JavaScript来读取和解析日历文件(.ics)(也称为iCal格式)。我编写了一个自定义函数来读取这些值,然后使用JavaScript Date()函数生成一个数据对象

有没有更简单更好的方法?请看我的功能(下面),欢迎您的评论

.ics文件中的典型日期值如下所示:

DTSTART:20110914T184000Z

需要在结肠处将其分开,因此:

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');