18

まず、おそらくタイムゾーンが関係していると思います。私はEST / EDTにいます。また、これを chromium 17 / Linux でテストしています。

ここで、次のような 2 つの日付を作成するとします。

// December 5

dateFromNumbers = new Date(2020, 11, 5);
dateFromString = new Date("2020-12-5");

これらの日付のタイムスタンプは同一である必要があるようですが、次のようになります。

+dateFromNumbers == +dateFromString; // true

...少なくともこの場合。ただし、場合によっては、そうではありません。

// December 15

dateFromNumbers = new Date(2020, 11, 15);
dateFromString = new Date("2020-12-15");

+dateFromNumbers == +dateFromString; // false

何が起きてる?

dateFromNumbers; // Tue Dec 15 2020 00:00:00 GMT-0500 (EST)
dateFromString;  // Mon Dec 14 2020 19:00:00 GMT-0500 (EST)

dateFromStringこの場合よりも 5 時間早いようですdateFromNumbers(EST は GMT - 5 です。何らかの形で関連していると確信しています)。

10 月から 12 月の月末に影響するようです。これは、どの日が異なるかを簡単に確認できるようにするためのフィドルです (赤緑の色盲でない限り、その場合は見にくい場合があります。申し訳ありません)。

http://jsfiddle.net/9gBfX/

何を与える?


ノート:

  • システムのタイムゾーンを EST/EDT に設定して、私が見ているように jsfiddle の例を確認できます。
  • Date の月の数字は 0 から始まります。これ11はタイプミスではありません。
  • この問題は、私がチェックした毎年表示されます。
4

5 に答える 5

6

V8のソースコードを見た後:

// Specification:
// Accept ES5 ISO 8601 date-time-strings or legacy dates compatible
// with Safari.
<...>
//  A string that matches both formats (e.g. 1970-01-01) will be
//  parsed as an ES5 date-time string - which means it will default
//  to UTC time-zone. That's unavoidable if following the ES5
//  specification.

周囲のコードを読むと、月と日の両方の記号を持つ日時文字列は、有効な ES5 日時文字列と見なされるようです。ES5 パーサーのさらに下に、日付と時刻を解析した後、コメントがあります。

// Successfully parsed ES5 Date Time String. Default to UTC if no TZ given.

「YYYY-MM-DD」の場合、コードがそこまで到達すると、ES5 パーサーは文字列全体を正常に解析したため、従来のパーサーがタイムゾーンをローカライズする機会を得る前に戻ります。それ以外の場合 (月/日は 1 シンボルの長さ)、「従来の」日時として扱われ、従来のパーサーがそれを処理してローカライズします。

于 2012-04-22T17:06:24.350 に答える
3

これは、他の回答から得た簡単な回答です。

日付はさまざまな文字列形式を認識します

  • 非標準の日付
  • RFC 2282 の日付
  • ES 5 日程

ほとんどの形式は現地の日付として解釈されます

RFC 2282の 14 ページには、次のように記載されています。

日付と時刻は、現地時間を表現する必要があります。

非標準の日付も同様に扱われます。

ES 5 形式は UTC として解釈されます

ES 5 仕様のセクション 15.9.1.15には、次のように記載されています。

タイム ゾーン オフセットがない場合の値は「Z」です。

「Z」は UTC 時間を表します。

十月十日

ES 5 形式の日付には、2 桁の月と日が必要です。元の投稿の月と日はゼロ埋めされていません。「2020-9-9」は有効な ES 5 日付表現ではありません。これは非標準形式であるため、現地時間で解釈されます。「2020-10-10」有効な ES 5 日付表現であるため、UTC で解釈する必要があります。

考えられる回避策

  • 文字列コンストラクタ / Date.parse を使用しないでください!
  • 区切り文字を変更して、形式が ES 5 形式と一致しないようにします。
  • タイムゾーンを指定します。
  • 日付を現地時間に調整します。時間または分がある場合: date.setMinutes(date.getTimezoneOffset());(とにかく、これはうまくいくようです)。
于 2012-04-22T17:55:21.473 に答える
2

米国の日付の日付区切り文字として「-」を使用すると、一部のブラウザが混乱します。日付演算を実行するブラウザもあれば、NaNを返すブラウザもあるため、「/」日付区切り文字を使用してください。カルチャに対応したソリューションは、date.jsを使用することです。これは、指摘したような問題(http://www.datejs.com/)を解決する優れたJavaScript日付ハンドラーです。解析メソッドを使用すると、すべての混乱が解消されます。

Date.parse("2020-12-15").toString() // yields the correct date ("Tue Dec 15 00:00:00 PST 2020"). 
于 2012-04-22T16:21:04.663 に答える
2

日付コンストラクターには「-」ではなくスペースが必要なようです。おすすめの方法です。このリンクをチェックしてください:
3.3. 日時指定

日時指定全体で空白の折り畳みが許可されていますが、FWS が表示される各場所で単一のスペースを使用することをお勧めします (必須かオプションかに関係なく)。

このリンクもチェックしてください:
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date

dateString: 日付を表す文字列値。文字列は、解析メソッド (IETF 準拠の RFC 2822 タイムスタンプ) によって認識される形式である必要があります。

次のコードを試してみましたが、trueを返します

dateFromNumbers = new Date(2020, 11, 15);
dateFromString = new Date("2020 12 15");
alert(+dateFromNumbers == +dateFromString);​

また、10 月から始まるのも問題ではなく、2 桁の月と関係があります。9 月に同じ方法を試すと、次のようになります。

dateFromNumbers = new Date(2020, 8, 15);
dateFromString = new Date("2020-09-15");
alert(+dateFromNumbers == +dateFromString);​ // This returns false

しかし、9 月に 1 桁を使用すると、true が返されます。

dateFromNumbers = new Date(2020, 8, 15);
dateFromString = new Date("2020-9-15");
alert(+dateFromNumbers == +dateFromString);​ // This returns true

また、2 桁の 9 月にスペースを使用すると、true が返されます。

dateFromNumbers = new Date(2020, 8, 15);
dateFromString = new Date("2020 09 15");
alert(+dateFromNumbers == +dateFromString);​//This returns true
于 2012-04-22T17:08:21.333 に答える
2

この投稿を中継すると、Dateの文字列引数コンストラクターはDate.parse()、ブラウザーによるさまざまな実装により、実装に依存しているようです。

ブラウザで EST を正しく解析したい場合は、このコンストラクタを完全に使用しないようにする必要があります。

于 2012-04-22T16:39:53.060 に答える