Webアプリケーションを書いている間は、(サーバー側)all datetimeをUTCタイムスタンプとしてDBに格納するのが合理的です。
JavaScriptでのタイムゾーン操作に関して、あなたがネイティブでそれほど多くのことができないことに気付いたとき、私は驚きました。
Dateオブジェクトを少し拡張しました。この機能は意味がありますか?基本的に、私がサーバに何かを送るたびに、それはこの関数でフォーマットされたタイムスタンプになるでしょう...
ここで何か大きな問題がありますか。それとも別の角度からの解決策?
Date.prototype.getUTCTime = function(){
return new Date(
this.getUTCFullYear(),
this.getUTCMonth(),
this.getUTCDate(),
this.getUTCHours(),
this.getUTCMinutes(),
this.getUTCSeconds()
).getTime();
}
それは私には少し複雑に思えます。そしてパフォーマンスについてもよくわかりません。
このようにして作成された日付は現地のタイムゾーンを使用するため、作成された日付は正しくありません。特定の日付オブジェクトのタイムゾーンを設定することは、タイムゾーンを含む日付文字列からそれを構成することです。 (私はそれを古いAndroidブラウザで動かすのに問題がありました。)
getTime()
は普通の秒ではなくミリ秒を返すことに注意してください。
UTC/Unixタイムスタンプの場合は、以下で十分です。
Math.floor((new Date()).getTime() / 1000)
現在のタイムゾーンのオフセットが結果に反映されます。文字列表現の場合、 David Ellis ' answerが機能します。
明確にするために:
new Date(Y, M, D, h, m, s)
その入力は現地時間として扱われます。 UTC時間が渡された場合、結果は異なります。観察しなさい(私は今GMT +02:00にいる、そしてそれは07:50である):
> var d1 = new Date();
> d1.toUTCString();
"Sun, 18 Mar 2012 05:50:34 GMT" // two hours less than my local time
> Math.floor(d1.getTime()/ 1000)
1332049834
> var d2 = new Date( d1.getUTCFullYear(), d1.getUTCMonth(), d1.getUTCDate(), d1.getUTCHours(), d1.getUTCMinutes(), d1.getUTCSeconds() );
> d2.toUTCString();
"Sun, 18 Mar 2012 03:50:34 GMT" // four hours less than my local time, and two hours less than the original time - because my GMT+2 input was interpreted as GMT+0!
> Math.floor(d2.getTime()/ 1000)
1332042634
getUTCDate()
をgetUTCDay()
の代わりに使用することはできません。これはgetUTCDate()
が 月の日 を返すからです。一方、getUTCDay()
は 曜日 を返します。
GetTimezoneOffsetとgetTimeを利用してそれを行うこともできます。
x = new Date()
var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000)/1000;
console.log("UTCseconds", UTCseconds)
そんなことする必要はありません。私があなたを正しく理解していると仮定すると、あなたはただ toUTCString
method が欲しいだけです。
var UTCstring = (new Date()).toUTCString();
console.log('UTCstring', UTCstring);
ただし、取得する日付値は、サーバーではなく、クライアントのマシンのクロックに基づいていることに注意してください。これらの日付に正確な値が必要な場合(たとえば、他のユーザーのアクションに対してこのアクションまたはそのアクションがいつ実行されたかを適切に順序付けるため)、あなたはクライアントに依存できませんとにかく、クライアントがあなたに連絡したときに基づいてサーバー側の日付を計算する必要があります。
基本的に、すべてのクライアント側コードはクライアントによって変更され、代わりに悪意のある値が返される可能性があることを忘れないでください。サーバー側でのみコードを保証できます。クライアント側を攻撃者のように扱います。
あなたは一般的にクライアント側で "タイムゾーン操作"の多くをする必要はありません。原則として、私はUTC日付を格納して、ticks
または "1970年1月1日午前0時からのミリ秒数"の形式で処理します。これは本当にストレージ、ソート、オフセットの計算を簡単にし、そして何よりも「夏時間」調整の頭痛からあなたを取り除きます。これが私が使っている小さなJavaScriptコードです。
現在のUTC時刻を取得するには
function getCurrentTimeUTC()
{
//RETURN:
// = number of milliseconds between current UTC time and midnight of January 1, 1970
var tmLoc = new Date();
//The offset is in minutes -- convert it to ms
return tmLoc.getTime() + tmLoc.getTimezoneOffset() * 60000;
}
それからあなたが一般的に必要とするものは彼らのローカルタイムゾーンとフォーマットのためにエンドユーザーのための日付/時刻をフォーマットすることです。以下は、クライアントコンピュータ上の日付と時刻の形式のすべての複雑さを扱います。
function formatDateTimeFromTicks(nTicks)
{
//'nTicks' = number of milliseconds since midnight of January 1, 1970
//RETURN:
// = Formatted date/time
return new Date(nTicks).toLocaleString();
}
function formatDateFromTicks(nTicks)
{
//'nTicks' = number of milliseconds since midnight of January 1, 1970
//RETURN:
// = Formatted date
return new Date(nTicks).toLocaleDateString();
}
function formatTimeFromTicks(nTicks)
{
//'nTicks' = number of milliseconds since midnight of January 1, 1970
//RETURN:
// = Formatted time
return new Date(nTicks).toLocaleTimeString();
}
だから、次の例:
var ticks = getCurrentTimeUTC(); //Or get it from the server
var __s = "ticks=" + ticks +
", DateTime=" + formatDateTimeFromTicks(ticks) +
", Date=" + formatDateFromTicks(ticks) +
", Time=" + formatTimeFromTicks(ticks);
document.write("<span>" + __s + "</span>");
以下を返します(私のアメリカ英語ロケールの場合)。
ticks = 1409103400661、DateTime = 8/26/2014 6:36:40 PM、Date = 8/26/2014、Time = 6:36:40 PM
私は実際にjsのDate値はC#DateTimeオブジェクトを言うよりはるかに良いと思います。 C#DateTimeオブジェクトにはKindプロパティがありますが、そのような厳密な基礎となるタイムゾーンはありません。2つのUTC以外の時刻とローカル以外の時刻の間で変換する場合、タイムゾーン変換を追跡するのは困難です。 jsでは、すべてのDate値に基本となるUTC値があります。これは、ユーザーが行った最悪の変換やタイムゾーン変換に関係なく、受け渡しされて認識されています。 Dateオブジェクトに関する私の最大の不満は、ブラウザの実装者が選択した未定義の振る舞いの量です。これは、jsで日付を攻撃する人々を、仕様を読むよりも試行錯誤で混乱させる可能性があります。 iso8601.jsのようなものを使用すると、Dateオブジェクトの単一の実装を定義することによってこのさまざまな動作を解決できます。
デフォルトでは、この仕様では、ISO 8601のように拡張された日付形式で日付を作成できると規定されています。
var someDate = new Date('2010-12-12T12:00Z');
そのため、この方法で正確なUTC時間を推測できます。
Date値をサーバーに渡したいときは、次のように呼び出します。
someDate.toISOString();
ミリ秒のタイムスタンプ(1970年1月1日のUTCからのミリ秒数)を使用したい場合は、
someDate.getTime();
ISO 8601が標準です。日付オフセットを含めると、日付文字列が何を意味するのか混乱することはありません。あなたが開発者としてあなたにとって意味することは、あなたが自分で現地時間の変換を扱う必要が決してないことです。現地時間値は純粋にユーザーの利益のために存在し、日付値はデフォルトでは現地時間で表示されます。すべての現地時間操作により、ユーザーにとって意味のあるものを表示したり、ユーザー入力から文字列を変換したりすることができます。できるだけ早くUTCに変換することをお勧めします。jsDateオブジェクトを使用すると、これはかなり簡単になります。
不利な点として、クライアントにタイムゾーンやロケールを強制する余地はあまりありません(これは私が知っています)が、ウェブサイト固有の設定には厄介なことになるかもしれませんが、これはユーザーだからです。触れてはいけない設定。
つまり、要するに、タイムゾーン操作に対するネイティブサポートがそれほど多くないのは、単にそれをしたくないからです。
従来の形式でUTC時刻を取得する最も簡単な方法は次のとおりです。
new Date().toISOString()
"2016-06-03T23:15:33.008Z"
私はこれがより良い解決策だと思います
// UTC milliseconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()
// UTC seconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()/1000|0
ワンライナーが必要な場合は、JavaScriptでTC Unixタイムスタンプを作成できます。
var currentUnixTimestap = ~~(+new Date() / 1000);
これはシステムのタイムゾーンを考慮に入れるでしょう。基本的にはエポックから経過した秒数です。
new Date()
。unary +
を追加してタイムスタンプに変換し、timestamp integer
に変換します。 :+new Date()
。+new Date() / 1000
~~(+new Date())
私は以下を使います:
Date.prototype.getUTCTime = function(){
return this.getTime()-(this.getTimezoneOffset()*60000);
};
このメソッドを定義したら、次のことができます。
var utcTime = new Date().getUTCTime();
new Date().toUTCString()
は"Wed, 11 Oct 2017 09:24:41 GMT"
のような文字列を返すので、最後の3文字をスライスしてスライスされた文字列をnew Date()
に渡すことができます。
new Date()
// Wed Oct 11 2017 11:34:33 GMT+0200 (CEST)
new Date(new Date().toUTCString().slice(0, -3))
// Wed Oct 11 2017 09:34:33 GMT+0200 (CEST)
編集:以下のコードは動作しません。私はいつもnew Date()。getTime()が1970年1月1日から現在のタイムゾーンまでの秒数を返すと仮定していました。これは事実ではありません:getTime()はUTCの秒数を返します。そのため、以下のコードは大幅に調整し過ぎています。みんなありがとう!
まず第一に、あなたの素晴らしい洞察力をありがとう。私の質問は間違ったタイトルを持っていたと思います…それは「既存の日付のUTC Unixタイムスタンプを取得する」であるべきでした。
だから、私は日付オブジェクトがある場合:
var d = new Date(2009,01,31)
私は "UTC Unixタイムスタンプ"を教えてくれる関数の後にいました。
この関数は本当のトリックのようです。
Date.prototype.getUTCUnixTime = function (){
return Math.floor( new Date(
this.getUTCFullYear(),
this.getUTCMonth(),
this.getUTCDate(),
this.getUTCHours(),
this.getUTCMinutes(),
this.getUTCSeconds()
).getTime() / 1000);
}
これは "this"で動作することに注意してください。これは私ができることを意味します:
var n = new Date(2008,10,10)
...
...
n.getUTCUnixTime();
そしてUnix時間で1970年1月1日からの秒数を取得します。右?
JavascriptがすべてをUTC時間に格納するのは少し面倒ですが、その数値を取得するには、個々のUTCゲッターを渡す新しいDateオブジェクトを作成し、最後にgetTime()を呼び出す必要があります。
メルク.
私はこの質問がどれほど複雑になったかに驚いています。
これらはすべて同一であり、それらの整数値はすべて===エポックタイム:Dです。
console.log((new Date()).getTime() / 1000, new Date().valueOf() / 1000, (new Date() - new Date().getTimezoneOffset() * 60 * 1000) / 1000);
私を信じていない、チェックアウト: http://www.epochconverter.com/
New Date()。getTime()は実際にはUTC値を返すことを明確にしておきたいので、ローカライズされた時間にとらわれない方法で日付を保存および管理するための本当に便利な方法です。
言い換えれば、すべてのUTC JavaScript関数に煩わされないでください。代わりに、単にDate.getTime()を使用してください。
説明のより多くの情報はここにあります: もしJavaScript "(new Date())。getTime()"が2つの異なるタイムゾーンから実行されている場合
これはUTCのタイムスタンプを返します:
var utc = new Date(new Date().toUTCString()).getTime();
これはあなたが期待していることだと思います...
var currTimestamp = Date.now(), //1482905176396
utcDateString = (new Date(currTimestamp)).toUTCString(); //"Wed, 28 Dec 2016 06:06:50 GMT"
今、
new Date(utcDateString).getTime(); //This will give you UTC Timestamp in JavaScript