特定のタイムゾーンで日付をフォーマットする


177

Moment.jsを使用して、私のWebアプリで日付を解析およびフォーマットしています。JSONオブジェクトの一部として、私のバックエンドサーバーはUTCエポック(Unixオフセット)からミリ秒数として日付を送信します。

特定のタイムゾーンで日付解析するのは簡単です。解析する前に、文字列の最後にRFC 822タイムゾーン識別子を追加するだけです。

// response varies according to your timezone
const m1 = moment('3/11/2012 13:00').utc().format("MM/DD HH:mm")

// problem solved, always "03/11 17:00"
const m2 = moment('3/11/2012 13:00 -0400').utc().format("MM/DD HH:mm")

console.log({ m1, m2 })
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>

しかし、特定のタイムゾーンで日付をフォーマットするにはどうすればよいですか?

ブラウザの現在の時刻に関係なく一貫した結果が欲しいのですが、日付をUTCで表示したくありません。


2
Momentはまだこれをサポートしていませんが、開発中です。github.com/timrwood/moment/pull/671
Ben

5
これはうまくいくはずです。必要なオフセットを含む時間文字列を瞬間に渡す場合、ブラウザのローカル時間に自動的に調整するのではなく、そのオフセットを保持し、指定されたローカル時間を表示する必要があります。ブラウザのローカル時間に合わせたい場合は、使用するオフセットを明示的に指定する代わりに、UTC時間を指定します。つまり...私はそれに明確なオフセットを与えます、なぜそれは基本的にそれを食べて、それをブラウザのオフセットへの独自の変換をするのですか?ひどいデザイン。
Triynko 2015

@Triynkoオフセットは夏時間の影響を受けるため、常に期待どおりに機能するとは限りません。
pinkpanther

1
これに関連する何か、特定の形式、たとえば2018年3月15日で時間を出力したいのですが、これを行うための形式文字列が見つかりません。のDD MMM, YYYYように使用すると、ジェネリックが機能しませんmoment.tz("2018-02-15T14:20:00.000+0530", "Asia/Bangkok").format("DD MMM, YYYY")。誰かがこのAPIを使用するときに時間をフォーマットするためのすべてのキーを見つけることができるドキュメントで私を指摘できますか?
pRmdk 2018

@PramodKumarどうしたの?それは与える"15 Feb, 2018"DD MMMM, YYYY取得するためにフォーマット文字列を使用するつもりでした"15 February, 2018"か?
quietmint 2018

回答:


248

Mantoの回答で指摘されている.utcOffset()ように、モーメント2.9.0 以降はが推奨される方法です。この関数は、逆オフセットではなく、UTCからの実際のオフセットを使用します(たとえば、夏時間中のニューヨークの場合は-240)。"+0400"のようなオフセット文字列は以前と同じように機能します。

// always "2013-05-23 00:55"
moment(1369266934311).utcOffset(60).format('YYYY-MM-DD HH:mm')
moment(1369266934311).utcOffset('+0100').format('YYYY-MM-DD HH:mm')

古い.zone()セッターとしては、非推奨 Moment.js 2.9.0に。これは、タイムゾーン識別子を含む文字列を受け入れた(例えば、「-0400」または「-04:00」用-4時間)または分表す数値の後ろに UTCを(例えば、ニューヨークのための240 DST中)。

// always "2013-05-23 00:55"
moment(1369266934311).zone(-60).format('YYYY-MM-DD HH:mm')
moment(1369266934311).zone('+0100').format('YYYY-MM-DD HH:mm')

数値オフセットの代わりに名前付きタイムゾーンを使用する.tz()には、モーメントタイムゾーンを含めて代わりに使用します。

// determines the correct offset for America/Phoenix at the given moment
// always "2013-05-22 16:55"
moment(1369266934311).tz('America/Phoenix').format('YYYY-MM-DD HH:mm')

「TypeError:Object 240 has no method 'format'」というエラーで問題が発生しました。ゾーンはMoment.jsのバージョン2.1.0以降でのみセッターとして使用できることを認識しました(以前のバージョンを使用していました)。ありがとう!
Melinda Weathers 2013年

5
@ebiデフォルトでは、ブラウザのタイムゾーンがすでに使用されています。するために、アクセス、ブラウザのタイムゾーンのオフセット、使用を.zone()UTC(例えば、リターンの標準的な時間の間、ニューヨークのための300)からの分を返すゲッターとして。
quietmint 2013年

1
@EricCopeいいえ。あなたは、することができます使用し.tz("America/Phoenix")ますが含まれている場合momentjs.com/timezoneを同様しかし、。例で答えを更新しました。
quietmint 2013年

1
夏時間のためにタイムゾーンのオフセットが異なる場合、オフセットの使用は期待どおりに機能しないことに注意してください。
pinkpanther

1
.utcOffset()は夏時間を自動的に管理しますか?冬にUTC +1 CETを設定したときのように、夏時間の間はUTC +2 CESTに賭けますか?これにより、使用できるかどうかが決まります。
haemse 2017

61

モーメントタイムゾーンを使用する

moment(date).tz('Europe/Berlin').format(format)

特定のタイムゾーンにアクセスする前に、そのようにロードする必要があります(または、ここで説明する別の方法を使用します)。

moment.tz.add('Europe/Berlin|CET CEST CEMT|-10 -20 -30')

質問があったときにtzが利用できた瞬間はないと思いますが、これが適切な方法かもしれません。現在、MySQLにすべてのタイムスタンプがUTCとして保存されている同様の問題に取り組んでいますが、クライアントのタイムゾーンではなく、ユーザー設定に依存する特定のゾーンで表示する必要があります。
nickdnk 2015

47

いくつかの回答では、モーメントタイムゾーンは名前付きタイムゾーンを使用する方法であるとすでに述べています。このライブラリについて、私をかなり混乱させたものを明確にしたいだけです。これらの2つのステートメントには違いがあります。

moment.tz(date, format, timezone)

moment(date, format).tz(timezone)

渡された日付にタイムゾーンが指定されていない場合:

最初のコードは日付を受け取り、タイムゾーンが渡されたものであると想定します。2番目のコードは日付を取り、ブラウザーからタイムゾーンを想定し、渡されたタイムゾーンに従って時刻とタイムゾーンを変更します。

例:

moment.tz('2018-07-17 19:00:00', 'YYYY-MM-DD HH:mm:ss', 'UTC').format() // "2018-07-17T19:00:00Z"

moment('2018-07-17 19:00:00', 'YYYY-MM-DD HH:mm:ss').tz('UTC').format() // "2018-07-18T00:00:00Z"

私のタイムゾーンはutcから+5です。したがって、最初のケースでは変更されず、日付と時刻にutcタイムゾーンが設定されます。

2番目のケースでは、渡された日付が-5であると想定し、それをUTCに変換します。そのため、日付「2018-07-18T00:00:00Z」が出力されます。

注:formatパラメータは非常に重要です。省略された場合、予測できない動作が発生する可能性があるDateクラスにフォールバックする可能性があります


渡される日付にタイムゾーンが指定されていると仮定します。

この場合、両者は同じように動作します


なぜそのように機能するのかは理解できましたが、これはかなり混乱する機能であり、説明する価値があると思いました。


1
moment(...)。tzは関数ではありません
K-SOの毒性が増加しています。

5
モーメントタイムゾーンをインストールしましたか?
Nicola Pedretti、

フォーマットせずに解析され変換された瞬間を取り戻す方法はありますか?たとえば、もう一度解析せずにさまざまな方法でフォーマットしたい場合などです。
jEremyB

これを明確にしていただきありがとうございます。ユーザーのブラウザのタイムゾーンとは異なるタイムゾーンを設定するときに問題が発生しましたが、これがまさに問題でした。
Robin Schaaf

20

.zone()は廃止されました。代わりにutcOffsetを使用してください:

// for a timezone that is +7 UTC hours
moment(1369266934311).utcOffset(420).format('YYYY-MM-DD HH:mm')

8

Moment.jsでも同じ問題が発生していました。moment-timezoneをインストールしましたが、問題は解決しませんでした。次に、ここで公開されていることを実行し、タイムゾーンを設定すると、魅力的に機能します。

moment(new Date({your_date})).zone("+08:00")

どうもありがとう!


16
new Date()コンストラクタは使用しないでください。Momentは、日付を解析するために必要なすべてのものを提供します。ドキュメントの解析を参照してください。
quietmint 2014

私はそれをしない場合は、[はい、しかし、私はそれがそのようなことで廃止されていることを、瞬間から警告を受けています
facundofarias

7
警告は、モーメントが(new Date()内部的に使用している)正確に内部的にフォールバックしていることを意味しますが、ブラウザ間一貫性がありません。代わりに、予想される形式を2番目の引数として提供する必要があります。例:moment("12-25-1995", "MM-DD-YYYY")
quietmint 2014

4

ちょうどこれがacreossになりました、そして私が同じ問題を抱えていたので、私は思いついた結果を投稿するだけです

解析時にオフセットを更新できます(つまり、データ(1.1.2014)を解析していて、2014年1月1日の日付のみが必要です。GMT+ 1では31.12.2013になります。したがって、最初に値をオフセットします。

moment(moment.utc('1.1.2014').format());

さて、私がタイムゾーンを越えてサポートするのに重宝しました

B


-7

あなたはこれを試すことができます、

ここでは、クライアントのタイムゾーン(ブラウザ)に基づいて日付を取得できます。

moment(new Date().getTime()).zone(new Date().toString().match(/([-\+][0-9]+)\s/)[1]).format('YYYY-MM-DD HH:mm:ss')

正規表現は基本的にオフセット値を取得します。

乾杯!!


通常、瞬間はあなたに必要なすべてを与えます。あなたはカスタムに一致する必要はありません。
Mahesh Samudra
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.