Moment: isSameOrAfterは、moment()とmoment()を比較するときにランダムな出力を提供します

作成日 2017年02月21日  ·  4コメント  ·  ソース: moment/moment

説明
そのため、私と同僚は、未定義の変数(基本的にmoment(undefined) 、それを新しいモーメントインスタンス( moment()と比較しようとしたことが原因であることが判明したコードのバグを発見しました。 )メソッドisSameOrAfterます。

つまり、基本的に使用したのは次のとおりです。

let isSame = moment(undefined).isSameOrAfter(moment());

そのコードを1回または2回実行すると、 trueが返されますが、常にそうとは限りません。 たまにfalseが返されるのは、時間を定義せずに2つのモーメントのインスタンスを次々に作成すると、数マイクロ秒の差で作成される可能性があるためだと思います。

これは、Windows10のNodev7.1.0とMoment.js2.17.1を使用したChrome / 56.0.2924.87の両方で実行したテストです。

const moment = require('moment');

function isSameOrAfter() {
    console.log('isSameOrAfter')
    for (let i = 0; i < 1000; i++) {
        let output = moment().isSameOrAfter(moment());
        if (!output) {
            console.log(output, i);
        }
    }
}

function isSame() {
    console.log('isSame')
    for (let i = 0; i < 1000; i++) {
        let output = moment().isSame(moment());
        if (!output) {
            console.log(output, i);
        }
    }
}

function sameExactVariable() {
    console.log('Another test comparing the same exact variable')
    for (let i = 0; i < 1000; i++) {
        const now = moment();
        let output = now.isSame(now);
        if (!output) {
            console.log(output, i);
        }
    }
}

isSameOrAfter();
isSame();
sameExactVariable();

最初の2つの関数はfalseを1000回のうち数回ログに記録しますが、3番目の関数はログに記録しません。 例外が発生した場合にのみログに記録されます。

環境:
2017年2月21日火曜日14:36:06GMT + 0100(西ヨーロッパ標準時)
2017-02-21 14:36:06
-60
Mozilla / 5.0(Windows NT 10.0; Win64; x64)AppleWebKit / 537.36(KHTML、Geckoなど)Chrome / 56.0.2924.87 Safari / 537.36
2.17.1

最も参考になるコメント

@imrvshah最初に注意してください

...isSameOrAfter(moment().format('MM-DD-YYYY'))

現在の時刻で新しいモーメントを作成し、それを文字列としてフォーマットし、その文字列をisSameOrAfter()に渡します。

...isSameOrAfter(moment())

そして、瞬間->文字列->瞬間の仕事を保存しました。 これははるかに優れたコードですが、バグが修正されることも間違いありません。 「ねえ、あなたはそのような瞬間に文字列を渡すことになっていない」という非推奨の警告に気づきましたか? Momentは、 moment("1982-05-25")ようなISO8601文字列を解析する方法を知っています。 また、 moment("05-25-1982", "MM-DD-YYYY")ように、形式が指定されている文字列を解析する方法も知っています。 しかし、「05-25-1982」のような文字列が「MM-DD-YYYY」であることをあなたが言わずに意味していることはわかりません。 したがって、ブラウザはその文字列をDateコンストラクタに渡すだけで推測できます。 つまり、コードは次のように展開されます。

m.isSameOrAfter("05-25-1982");
m.isSameOrAfter(moment("05-25-1982"))
m.isSameOrAfter(moment(new Date("05-25-1982")))

非推奨にした理由があります。実行しているブラウザに基づいて、一貫性のない結果が得られます。 つまり、あなたが直面しているのは、iOSがそのフォーマットをネイティブにサポートしていないということです。 私のSafari開発コンソールでは:

> new Date("05-25-1982")
Invalid Date

それはあなたに空の配列を残した悪い比較を与えました。

全てのコメント4件

おそらく私も同じような問題を抱えています。 ChromeとAndroidデバイスでは期待どおりに機能しますが、iOSでは機能しません。

let arrDates: Array<String> = []; _.each(Dates, (date) => { if (moment(date).isSameOrAfter(moment().format('MM-DD-YYYY'))) { arrDates.push(date); } });

iOSでは、ChromeとAndroidで動作しているときに配列がnullになります。

環境:

コルドバCLI:6.4.0
Ionic Frameworkバージョン:2.0.0
Ionic CLIバージョン:2.1.18
Ionic App Libバージョン:2.1.9
Ionicアプリスクリプトバージョン:1.0.0
ios-deployバージョン:1.9.0
ios-simバージョン:5.0.13
OS:macOSSierra
ノードバージョン:v6.9.2
Xcodeバージョン:Xcode8.2.1ビルドバージョン8C1002

@ErikMartensson

時間が定義されていない状態で、モーメントの2つのインスタンスを次々に作成すると、数マイクロ秒の差でそれらが作成される可能性があるためだと思います。

はい、 moment()またはmoment(undefined) -これらは同一です-は今を意味し現在が別のミリ秒である場合(これは時々発生します)、次々と発生します。 AFAIK、JSは、 moment().isSameOrAfter(moment())これら2つのmoment()呼び出しを評価する順序を定義していません。 しかし、とにかくisSameOrAfter()実行する前に、明らかに2番目の呼び出しを実行する必要があるため、実際には2番目の呼び出しが常に最初に来ても驚かないでしょう。 つまり、時差があると、テストの「orAfter」部分も失敗します。 これはデバッガーで確認できます。

何を言えばいいのかわからない。 これは、有限解像度の日時が機能する方法です。 「今」とは、いつ言うかによって異なる時間を意味します。

@imrvshah最初に注意してください

...isSameOrAfter(moment().format('MM-DD-YYYY'))

現在の時刻で新しいモーメントを作成し、それを文字列としてフォーマットし、その文字列をisSameOrAfter()に渡します。

...isSameOrAfter(moment())

そして、瞬間->文字列->瞬間の仕事を保存しました。 これははるかに優れたコードですが、バグが修正されることも間違いありません。 「ねえ、あなたはそのような瞬間に文字列を渡すことになっていない」という非推奨の警告に気づきましたか? Momentは、 moment("1982-05-25")ようなISO8601文字列を解析する方法を知っています。 また、 moment("05-25-1982", "MM-DD-YYYY")ように、形式が指定されている文字列を解析する方法も知っています。 しかし、「05-25-1982」のような文字列が「MM-DD-YYYY」であることをあなたが言わずに意味していることはわかりません。 したがって、ブラウザはその文字列をDateコンストラクタに渡すだけで推測できます。 つまり、コードは次のように展開されます。

m.isSameOrAfter("05-25-1982");
m.isSameOrAfter(moment("05-25-1982"))
m.isSameOrAfter(moment(new Date("05-25-1982")))

非推奨にした理由があります。実行しているブラウザに基づいて、一貫性のない結果が得られます。 つまり、あなたが直面しているのは、iOSがそのフォーマットをネイティブにサポートしていないということです。 私のSafari開発コンソールでは:

> new Date("05-25-1982")
Invalid Date

それはあなたに空の配列を残した悪い比較を与えました。

@icambron

私はあなたに同意し、コンソールで日付形式のために非推奨の警告であったケースを理解します。

何度もラップせず、そのまま使用することについてコメントありがとうございます。 ...isSameOrAfter(moment())

このページは役に立ちましたか?
0 / 5 - 0 評価