2

次の形式の日付文字列があります。

2012-09-20T01:36:51.556Z

mongodb からそのまま返される日付フィールドです。Chrome、FF、および IE はこの文字列を解析できますが、Safari はエラーで失敗しますInvalid Date。DateJS を試してみましたが、この日付も解析できません。この日付を簡単に解析するにはどうすればよいですか? または、Safari が失敗する特定の原因は何ですか?

mongodb のネイティブ ノード ドライバーを使用しています。そして、日付を上記の形式の文字列として返します。

4

3 に答える 3

1

私のDateExtensionsはそれを解析する必要があります:

http://depressedpress.com/javascript-extensions/dp_dateextensions/

ライブラリをページに追加した後、静的なDate.parseIso8601(date)メソッドを使用して日付を解析します。

拡張機能はそのために少し重いです(ただし、必要に応じてデータ解析のものだけを引き出すことができます)。

Safariには、日付が完全に有効なISO 8601日付(ここで定義:http ://www.w3.org/TR/NOTE-datetime )であるように見えるなどの問題が発生していることに驚いています。これは、日付が取得するのとほぼ同じくらい単純なバニラです。完全に推測できますが、「T」セパレーターをスペースに置き換えてみましたか?それは標準ではありませんが、私はそれをそのように使用する多くの実装を見てきました(そして私のコンポーネントはそれを可能にします)。

価値のあるものとして、DP_DateExtensionsから取得した私のメソッドを次に示します。これでうまくいくと思います。

    // parseIso8601
    // Attempts to convert ISO8601 input to a date
Date.parseIso8601 = function(CurDate) {

        // Check the input parameters
    if ( typeof CurDate != "string" || CurDate == "" ) {
        return null;
    };
        // Set the fragment expressions
    var S = "[\\-/:.]";
    var Yr = "((?:1[6-9]|[2-9][0-9])[0-9]{2})";
    var Mo = S + "((?:1[012])|(?:0[1-9])|[1-9])";
    var Dy = S + "((?:3[01])|(?:[12][0-9])|(?:0[1-9])|[1-9])";
    var Hr = "(2[0-4]|[01]?[0-9])";
    var Mn = S + "([0-5]?[0-9])";
    var Sd = "(?:" + S + "([0-5]?[0-9])(?:[.,]([0-9]+))?)?";
    var TZ = "(?:(Z)|(?:([\+\-])(1[012]|[0]?[0-9])(?::?([0-5]?[0-9]))?))?";
        // RegEx the input
        // First check: Just date parts (month and day are optional)
        // Second check: Full date plus time (seconds, milliseconds and TimeZone info are optional)
    var TF;
    if ( TF = new RegExp("^" + Yr + "(?:" + Mo + "(?:" + Dy + ")?)?" + "$").exec(CurDate) ) {} else if ( TF = new RegExp("^" + Yr + Mo + Dy + "[Tt ]" + Hr + Mn + Sd + TZ + "$").exec(CurDate) ) {};
        // If the date couldn't be parsed, return null
    if ( !TF ) { return null };
        // Default the Time Fragments if they're not present
    if ( !TF[2] ) { TF[2] = 1 } else { TF[2] = TF[2] - 1 };
    if ( !TF[3] ) { TF[3] = 1 };
    if ( !TF[4] ) { TF[4] = 0 };
    if ( !TF[5] ) { TF[5] = 0 };
    if ( !TF[6] ) { TF[6] = 0 };
    if ( !TF[7] ) { TF[7] = 0 };
    if ( !TF[8] ) { TF[8] = null };
    if ( TF[9] != "-" && TF[9] != "+" ) { TF[9] = null };
    if ( !TF[10] ) { TF[10] = 0 } else { TF[10] = TF[9] + TF[10] };
    if ( !TF[11] ) { TF[11] = 0 } else { TF[11] = TF[9] + TF[11] };
        // If there's no timezone info the data is local time
    if ( !TF[8] && !TF[9] ) {
        return new Date(TF[1], TF[2], TF[3], TF[4], TF[5], TF[6], TF[7]);
    };
        // If the UTC indicator is set the date is UTC
    if ( TF[8] == "Z" ) {
        return new Date(Date.UTC(TF[1], TF[2], TF[3], TF[4], TF[5], TF[6], TF[7]));
    };
        // If the date has a timezone offset
    if ( TF[9] == "-" || TF[9] == "+" ) {
            // Get current Timezone information
        var CurTZ = new Date().getTimezoneOffset();
        var CurTZh = TF[10] - ((CurTZ >= 0 ? "-" : "+") + Math.floor(Math.abs(CurTZ) / 60))
        var CurTZm = TF[11] - ((CurTZ >= 0 ? "-" : "+") + (Math.abs(CurTZ) % 60))
            // Return the date
        return new Date(TF[1], TF[2], TF[3], TF[4] - CurTZh, TF[5] - CurTZm, TF[6], TF[7]);
    };
        // If we've reached here we couldn't deal with the input, return null
    return null;

};

はるかに小さく、より合理化されたバージョンを作成できると確信しています(私のコードはコンパクトさよりも保守性のために書かれています)-しかし、これはISO8601の日付時間のほとんどのバリエーションを管理し、私をがっかりさせることはありません。; ^)

お役に立てれば!

于 2012-09-20T02:41:22.713 に答える
0

クライアントに送信する前に、サーバー側で日付をタイムスタンプに変換することになりました。NodeJS (もちろん、Chrome の JavaScript エンジンに基づいています) は、この形式を問題なく解析します。

于 2012-10-08T01:28:32.240 に答える
0

私は同じ問題を抱えていましたが、これはうまくいきました: https://github.com/csnover/js-iso8601

Date.parse 関数をオーバーライドします。

于 2013-01-23T16:09:57.483 に答える