「正しい」JSON日付形式


1137

JSONの日付形式には、さまざまな標準がありました。

"\"\\/Date(1335205592410)\\/\""         .NET JavaScriptSerializer
"\"\\/Date(1335205592410-0500)\\/\""    .NET DataContractJsonSerializer
"2012-04-23T18:25:43.511Z"              JavaScript built-in JSON object
"2012-04-21T18:25:43-05:00"             ISO 8601

どちらが正しいですか?それとも最高?これには何らかの基準がありますか?


75
JSONには日付形式はありません。デシリアライザが日付値にマップすることを決定する文字列のみがあります。

11
stringsnumberstruefalsenullobjectsおよびarrays
ラスカム

12
ただし、JavaScriptの組み込みJSONオブジェクトISO8601には、人間とコンピューターが理解できるすべての情報が含まれており、コンピューター時代の始まり(1970-1-1)に依存していません。
poussma 2013年

回答:


1849

JSON自体日付の表現方法を指定しませんが、JavaScriptは指定します。

のメソッドによって発行された形式使用する必要があります。DatetoJSON

2012-04-23T18:25:43.511Z

理由は次のとおりです。

  1. 人間が読めるだけでなく簡潔でもある

  2. 正しくソートされます

  3. 秒の小数部が含まれているため、年表の再構築に役立ちます

  4. ISO 8601に準拠

  5. ISO 8601は10年以上国際的に確立されています

  6. ISO 8601はW3CRFC3339、およびXKCDによって承認されています

そうは言っても、これまでに作成されたすべての日付ライブラリ、「1970年からのミリ秒」を理解できます。したがって、移植を容易にするために、ThiefMasterが適切です。


32
これはに従っても好ましい表現であるECMAJSON.stringify({'now': new Date()}) "{"now":"2013-10-21T13:28:06.419Z"}"
スティーブン・

11
リストに別の重要な理由を追加します。それはロケールに依存しないためです。2014年2月3日のような日付があった場合、それが2月3日か3月2日のどちらを指しているかを知るには、追加情報が必要になります。US形式か他の形式かによって異なります。
Juanal 14

107
xkcd:D @ajorqueraに言及してリンクすることへの賛成私は通常、これにmomentjsを使用します。また、私はこの点でIEの問題を見てきました
fholzer

54
2番目の点については、10000年以降は正しく並べ替えられません。ただし、新しい形式を考え出すには8000年近くかかるので、おそらく問題ではありません。
Erfa、2015

7
実際には、@ Erfaはの-数字の前にあるため、100,000 ASCII年まで問題なくソートされます。; P
Ben Leggiero、2016年

128

JSONは日付について何も知りません。.NETが行うことは、非標準のハック/拡張です。

DateJavaScriptでオブジェクトに簡単に変換できる形式、つまりに渡すことができる形式を使用しますnew Date(...)。最も簡単でおそらく最も移植性の高い形式は、1970年以降のミリ秒を含むタイムスタンプです。


3
stackoverflow.com/questions/10286385/…-FFがそのように動作する理由を誰かが知っているかどうか見てみましょう。
ThiefMaster 2012

11
このルートを使用する場合は、1970年より前の日付を処理する必要がないことを確認してください。
ベン・ドルマン

8
@BenDolmanが言ったように、この「解決策」は1970年1月1日(エポック)より前の日付を適切に処理しません。また、そもそもISO8601が存在するのには理由があります。ここ地球には、「タイムゾーン」と呼ばれるものがあります。それはミリ秒でどこにありますか?JSONは、日付の標準を持っていないかもしれませんが、日付はJSONの外側に存在し、そこにある標準のはそのため。funrollの答えは正しいものです(xkcd.com/1179も参照)。
JoeLinux

5
うるう秒があるため、1970年からの(ミリ)秒は将来の日付では予測できないことにも言及する価値があるかもしれません。したがって、プロセス間通信とデータストレージにifを使用しません。ただし、パフォーマンスを向上させる単一の整数に格納できるため、プログラムの内部で使用すると便利です。
Brodie Garnet

5
Unixタイムスタンプは常にUTCであり、タイムスタンプを生成する前にローカルタイムゾーンから変換し、表示されているローカルタイムゾーンに再び戻ると、あいまいさはありません。
lkraider 2016年

46

正しいフォーマットはありませんJSONの仕様は、それを行うには非常に多くの異なる方法がある理由は、日付を交換するためのフォーマットを指定しません。

最良の形式は、おそらくISO 8601形式で表された日付ですWikipediaを参照)。これはよく知られ、広く使用されているフォーマットであり、さまざまな言語で処理できるため、相互運用性に非常に適しています。たとえば、生成されたjsonを制御できる場合、データをjson形式で他のシステムに提供します。日付交換形式として8601を選択することをお勧めします。

生成されたjsonを制御できない場合、たとえば、いくつかの異なる既存のシステムからのjsonを使用している場合、これを処理する最良の方法は、期待されるさまざまな形式を処理する日付解析ユーティリティ関数を使用することです。


2
@mlissnerですが、それはどちらがベストかという意見です。ISO-8601は標準ですが、JSONの標準ではありません(私がそれを使用する傾向があるとしても)。たとえば、Microsoftはそれを使用しないことを決定しました(msdn.microsoft.com/en-us/library/…)。ベストプラクティスは、1つの(賢明な)規則に固執することです。回答で述べたように、これを処理する最良の方法は、期待される形式を処理できる日付解析ユーティリティ関数を定義することです。異なるフォーマットを使用するシステムと統合する場合、関数はそれぞれのケースを処理する必要があります。
Russ Cam

1
@RussCam、前後に移動できますが、JSONで日付をエンコードする最善の方法を誰かが求めている場合、JSONを作成するときに日付をフォーマットする方法を尋ねています(そして答えは通常ISO-8601です)。あなたは反対の質問に答えています:JSONの日付がすでに作成された後、それを消費する方法(アドバイスはしっかりしていますが)。
mlissner 2013

1
JSONスキーマ仕様では、実際には、スキーマによって検証される日付は8601形式でなければならないことが規定されています。
gnasher729 2015年

3
@ gnasher729リンクはありますか?
Russ Cam

@vallismortis-これは、パーティー間で交換される特定のjson構造のスキーマを定義するためのドラフト仕様であり、json仕様の日付の形式ではありません。私はコメントに基づいて私の回答を修正します、それは十分に明確にしたようには見えません
Russ Cam

27

RFC 7493(I-JSONメッセージフォーマット)

I-JSONは、質問者に応じて、インターネットJSONまたは相互運用可能なJSONを表します。

多くの場合、プロトコルには、タイムスタンプまたは期間を含むように設計されたデータ項目が含まれています。RFC 3339で指定されているように、そのようなすべてのデータ項目をISO 8601形式の文字列値として表現し、小文字ではなく大文字を使用すること、タイムゾーンをデフォルトに含めないこと、およびオプションの後続の秒数を追加することをお勧めします。値が「00」の場合も含まれます。また、継続時間を含むすべてのデータ項目が、RFC 3339の付録Aの「継続時間」の生成に準拠し、同じ追加の制限があることも推奨されます。


2
これはDate().toISOString()とによって生成される形式でもあり、タイムゾーン値を追跡しないDate().toJSON()という制限があるDateため、常にUTC(Z)タイムゾーンでタイムスタンプを発行します。値はnew Date("...")およびを使用して解析できますDate.parseDate
セーレンLøvborg

15

参考までに、このフォーマットが使用されているのを見てきました。

Date.UTC(2017,2,22)

関数でサポートされているJSONPで動作し$.getJSON()ます。私はこのアプローチをお勧めするところまで行きます...人々がこのようにそれをしているので、可能性としてそれを単に捨てるだけです。

FWIW:通信プロトコルでエポックからの秒数や、エポックからのミリ秒は決して使用しないでください。これは、うるう秒のランダムな実装により危険が伴うためです(送信者と受信者の両方がUTCうるう秒を適切に実装するかどうかはわかりません)。

ペットは嫌いなのですが、多くの人はUTCがGMTの新しい名前だと信じています-間違っています!システムにうるう秒が実装されていない場合は、GMTを使用しています(正しくない場合でもUTCと呼ばれることが多い)。うるう秒を完全に実装する場合は、本当にUTCを使用しています。うるう秒はわかりません。それらは必要に応じてIERSによって公開され、絶え間ない更新が必要です。うるう秒を実装しようとしているが、古くなった参照テーブルが含まれているシステム(考えられるよりも一般的)を実行している場合、GMTもUTCもない場合、UTCになりすましているシステムが不安定になります。

これらの日付カウンターは、分解された形式(y、m、dなど)で表現された場合にのみ互換性があります。エポック形式では互換性がありません。心に留めておきます。


4
その形式は使用しませんが、提供した残りの情報は非常に役立ちます。ありがとうございます。
Robert Mikes

9

疑わしい場合は、F12(Firefoxの場合はCtrl + K)を押して最新のブラウザーのJavaScript Webコンソールに移動し、次のように入力します。

new Date().toISOString()

出力されます:

「2019-07-04T13:33:03.969Z」

たーだ!!


3

普遍的な相互運用性に最適な形式はISO-8601文字列ではなく、EJSONで使用される形式だと思います。

{ "myDateField": { "$date" : <ms-since-epoch> } }

ここで説明するように:https : //docs.meteor.com/api/ejson.html

利点

  1. 解析パフォーマンス: ISO-8601文字列として日付を保存する場合、その特定のフィールドの下に日付値が必要な場合に最適ですが、コンテキストなしで値タイプを決定する必要があるシステムがある場合、すべての文字列を解析します。日付形式。
  2. 日付の検証は不要:日付の検証と検証について心配する必要はありません。文字列がISO-8601形式に一致しても、実際の日付ではない可能性があります。これは、EJSONの日付では発生しません。
  3. 明確な型宣言:一般的なデータシステムに関する限り、ある場合にはISO文字列を文字列として保存し、別の場合には実際のシステム日付を保存したい場合、ISO-8601文字列形式を採用する一般的なシステムでは、これを機械的に許可しません(エスケープトリックや同様のひどいソリューションなし)。

結論

人間が読める形式(ISO-8601文字列)が80%のユースケースに役立ち、より便利であることを理解しています。実際、アプリケーションがそのようなものである場合、誰も日付をISO-8601文字列として保存しないように言われるべきではありません。理解してますが特定の値が確実に日付であることを保証する、広く受け入れられているトランスポート形式の場合、あいまいさを許容し、非常に多くの検証を行う必要がありますか?


:エポックからのミリ秒は、うるう秒などの不正確な計算などの注意事項がある理由のために、以前のスレッドでこの回答を参照してくださいstackoverflow.com/a/42480073/190476
Sudhanshuミシュラ

@SudhanshuMishra参照する警告は、主にタイムスタンプの生成に関連するUNIXタイムスタンプの非常に学術的な懸念に対する一般的な問題です。これは、ミリ秒の解像度ではそれほど問題ではありません。別のコメントで指摘されているように、ほとんどのコンピューターの日付は、他の方法で公開およびフォーマットされている場合でも、内部ではUNIXタイムスタンプとして表されます。それにもかかわらず、特定の日付と時刻のミリ秒表現には何の問題もありません。特に、他のアプローチと比較すると、内部の同じナノインパクトの警告に簡単に影響されます。
Ciabaros

UNIXタイムスタンプの「範囲外」の日付に関する懸念について追加するだけです。これらはシステムストレージの問題であり、トランスポート形式よりもはるかに広いコンテキストで対処されます。たとえば、この形式は32ビットに収まる整数に限定する必要はなく、厳密に正の数である必要もありませんが、システム/アーキテクチャレベルでタイムスタンプを削除して「2038年問題」を解決する人は誰もいません; それらは(例えば64ビット以上に)拡張する必要があるだけで、これはこの提案されたトランスポート形式に影響を与えません。
Ciabaros

3

JSON自体には日付形式はなく、日付がどのように格納されるかは関係ありません。ただし、この質問にはJavaScriptのタグが付いているため、JavaScriptの日付をJSONに保存する方法を知りたいと思います。あなただけの日に渡すことができますJSON.stringify方法、およびそれが使用するDate.prototype.toJSONターンの用途では、デフォルトでDate.prototype.toISOStringDate.toJSONのMDN):

const json = JSON.stringify(new Date());
const parsed = JSON.parse(json); //2015-10-26T07:46:36.611Z
const date = new Date(parsed); // Back to date object

またreviverJSON.parseJSON.parseのMDN)のパラメーターを使用して、JSON文字列を読み取るたびにISO文字列を自動的にJavaScriptの日付に変換することも有用であることがわかりました。

const isoDatePattern = new RegExp(/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/);

const obj = {
 a: 'foo',
 b: new Date(1500000000000) // Fri Jul 14 2017, etc...
}
const json = JSON.stringify(obj);

// Convert back, use reviver function:
const parsed = JSON.parse(json, (key, value) => {
    if (typeof value === 'string' &&  value.match(isoDatePattern)){
        return new Date(value); // isostring, so cast to js date
    }
    return value; // leave any other value as-is
});
console.log(parsed.b); // // Fri Jul 14 2017, etc...

2

推奨される方法は2018-04-23T18:25:43.511Z...

以下の図は、これが推奨される方法である理由を示しています。

JSON日付

ご覧のとおり、DateにはネイティブなMethod toJSONがありreturn、この形式で簡単にDate再び変換できます...


2
正しい!JSONデータ交換構文は標準を指定していません:ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdfしかし、実際には、JavaScriptランタイムを含むプラットフォーム間でISO 8601互換のフォーマットがより望ましいです。
Kamyar Nazeri

1

Sharepoint 2013では、データをJSONで取得する場合、日付をISO形式にする必要があるため、日付を日付のみの形式に変換する形式はありません。

yourDate.substring(0,10)

これはあなたに役立つかもしれません


0

「2014-01-01T23:28:56.782Z」

日付は、UTC時間(Zで示される)を表す標準の並べ替え可能な形式で表されます。ISO 8601は、タイムゾーンオフセットのZ値を+または–で置き換えることにより、タイムゾーンもサポートします。

「2014-02-01T09:28:56.321-10:00」

ISO 8601仕様には他にもタイムゾーンエンコーディングのバリエーションがありますが、現在のJSONパーサーがサポートする唯一のTZ形式は–10:00形式です。一般に、日付が生成されたタイムゾーンを特定する必要がない限り(サーバー側の生成でのみ可能)、UTCベースの形式(Z)を使用するのが最適です。

注意:var date = new Date(); console.log(date); // 2014年1月1日水曜日13:28:56 GMT- 1000(ハワイ標準時)

var json = JSON.stringify(date);
console.log(json);  // "2014-01-01T23:28:56.782Z"

JavaScriptには標準のフォーマットがありませんが、これが推奨される方法です。

// JSON encoded date
var json = "\"2014-01-01T23:28:56.782Z\"";

var dateStr = JSON.parse(json);  
console.log(dateStr); // 2014-01-01T23:28:56.782Z

0

Kotlinを使用している場合は、これで問題が解決します。(MS Json形式)

val dataString = "/Date(1586583441106)/"
val date = Date(Long.parseLong(dataString.substring(6, dataString.length - 2)))

-3

それはパースサーバーで私にとって仕事です

{
    "ContractID": "203-17-DC0101-00003-10011",
    "Supplier":"Sample Co., Ltd",
    "Value":12345.80,
    "Curency":"USD",
    "StartDate": {
                "__type": "Date",
                "iso": "2017-08-22T06:11:00.000Z"
            }
}

-6

これに対する正しい答えは1つしかなく、ほとんどのシステムはそれを間違っています。エポックからのミリ秒数、別名64ビット整数。タイムゾーンはUIの問題であり、アプリレイヤーやデータベースレイヤーには関係ありません。それが64ビット整数として格納することがわかっている場合に、変換の計算を実行することがわかっているときに、DBがタイムゾーンの種類を気にするのはなぜですか。

余分なビットを取り除き、日付をUIまでの数値として扱います。単純な算術演算子を使用して、クエリとロジックを実行できます。



5
ここで2つの問題があります。どのエポックを選択し、どのミリ秒をカウントする必要がありますか?おそらく最も一般的な選択はUnix時間(うるう秒に該当するものを除く1970-01-01T00:00:00 UTCおよびSIミリ秒)ですが、もちろん将来の時間は未定義になります。
aij 2016

2
では、マイクロ秒をどのように表すのですか?RFC3339はどんな精度でも問題なく機能し、タイムゾーンを解析して適切なタイムスタンプを提供するリーダーがあり、それが追加情報です。カレンダーアプリは通常、タイムゾーンを考慮します。
gnasher729 2016年

11
タイムゾーンは、次のフライトを逃してもかまわない限り、UIの問題ではありません。フライトは現地時間で投稿され、夏時間の変更に関する特定のルールに従います。オフセットを失うことは、重要なビジネス情報を失うことを意味します
Panagiotis Kanavos

1
さらにいくつかの反論には、1970年より前の時間を表す機能(その特定のエポックを想定)と、JSONはやや人間が読める傾向があります。
Timo

-8

次のコードは私のために働いています。このコードは、DD-MM-YYYY形式で日付を出力します。

DateValue=DateValue.substring(6,8)+"-"+DateValue.substring(4,6)+"-"+DateValue.substring(0,4);

それ以外の場合は、次も使用できます。

DateValue=DateValue.substring(0,4)+"-"+DateValue.substring(4,6)+"-"+DateValue.substring(6,8);

-19

それは本当にユースケースに依存すると思います。多くの場合、次のように(日付を文字列にレンダリングする代わりに)適切なオブジェクトモデルを使用する方が有益です。

{
"person" :
      {
 "name" : {
   "first": "Tom",
   "middle": "M",
  ...
}
 "dob" :  {
         "year": 2012,
         "month": 4,
         "day": 23,
         "hour": 18,
         "minute": 25,
         "second": 43,
         "timeZone": "America/New_York"
    }   
   }
}

確かに、これはRFC 3339よりも詳細ですが、

  • 人間にも読める
  • 適切なオブジェクトモデルを実装します(JSONが許可する限り、OOPと同様)
  • タイムゾーンをサポートします(指定された日時のUTCオフセットだけではありません)
  • ミリ秒、ナノ秒などの小さな単位、または単に小数秒をサポートできます
  • (日時の文字列を解析するための)個別の解析手順は必要ありません。JSONパーサーがすべてを実行します
  • 日時フレームワークまたは任意の言語での実装による簡単な作成
  • 他の暦スケール(ヘブライ語、中国語、イスラム...)と時代(AD、BC、...)をサポートするように簡単に拡張できます。
  • 10000年は安全です;-)(RFC 3339は安全ではありません)
  • 終日の日付と浮動時間をサポートします(JavaScriptはサポートDate.toJSON()していません)

正しいソート(RFC 3339のfunrollで指摘されている)は、日付をJSONにシリアル化するときに本当に必要な機能だとは思いません。また、これは、同じタイムゾーンオフセットを持つ日時に対してのみ当てはまります。


7
10000年にjsonを使用している人はいないかと思いますが、そのときまでに10000年はまだ10000年のままです。しかし、それらの両方がまだ真実である場合、フォーマットを拡張して3桁を含めることができます世紀のコンポーネント。したがって、少なくとも9900
夢の思い出

8
@downvoters:なぜ投票が重要なのか?場合は反対投票する必要がありpost contains wrong information, is poorly researched, or fails to communicate informationます。これらの理由のうち、この回答に反対した理由を説明してください。
マルテン

5
@Marten 2つのこと。1.反対票の説明はありませんが、参考になると思います。2.私はあなたの回答に反対票を投じませんでしたが、人々がこれを行うのは間違った方法だと思っているので、人々はあなたの回答を好まないでしょう。質問は何かを行うための最良の方法を探しているため、「間違った情報」と
Kevin Wells

7
私はあなたに反対票を投じませんでしたが、「もう1つの不十分に指定された形式を発明する」(これは基本的にあなたが言っていることです)がどのように間違っているか、不十分に研究されているかを理解することができます。
aij 2016

2
@ Phil、UTCは実際にはタイムゾーンではありません(公式のタイムゾーンとして「UTC」を使用する場所は地球上にありません)。これは時間の標準です。また、タイムゾーンのオフセットはかなり予測不可能です。2025年の「12:00モスクワ時間」が今日のようにまだ「9:00 UTC」であるかどうかを判断する方法はありません。過去30年間に何度か変更ています。将来の現地時間を表現したい場合は、真のタイムゾーンが必要です。
火曜日
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.