質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • JavaScript

    16389questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • C#

    7102questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • ASP.NET MVC Framework

    59questions

    ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

サーバー時刻をクライアントのタイムゾーンの時刻に変換したい

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,098

clubman

score 46

クライアントはJavaScriptサーバーサイドはC#で開発をしています。

C#のみで表題の処理をしたい場合はクライアントのコードは以下でいけたのですが、JavaScriptですとクライアントのロケールが取得できないため困っています。

DateTime serverDateTime = new DateTime(2017, 3, 1, 12, 30, 0);
TimeZoneInfo serverTimeZone = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time");
DateTime date = TimeZoneInfo.ConvertTime(serverDateTime, serverTimeZone, TimeZoneInfo.Local);

例えばサーバーのロケールが中国。時刻が「2017/03/01 12:30」で、クライアントのロケールが日本の場合、日本のと中国の時差は1時間なのでdate変数には「2017/03/01 13:30」が取得できます。
この結果をクライアントはJs、サーバーはC#の環境で実現したいのですが、、

なにか妙案があればご助言頂けませんでしょうか。
よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+3

Javascriptでは、dateのgetUTCHours()とgetHours()の差を求める事で、ローカルタイム(クライアントのロケールでの時間)と世界標準時の時差を求める事ができます。

 var currentTime = new Date();
  jisa = ( currentTime.getHours() - currentTime.getUTCHours() + 24 ) % 24; // 世界標準時との時差を計算

時間の表示に使うのであれば、世界標準時との時差が判れば十分なのではないでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/02 22:59

    一応、new Date().toTimeString() でタイムゾーン付きの書式が得られます。
    ところで、クライアント側の時差を参照する理由は時差を計算した上で new Date() に日本時間を入力する事にあるのでしょうか。
    例えば、サーバの中国時間からクライアントの日本時間に変換する事を考えた場合、中国時間と日本時間の時差を計算して new Date に日本時間を入力するよりも UTC 時間で入力する方が手間がない気がしたので、ちょっと気になりました。

    キャンセル

  • 2017/03/03 14:36

    「ロケールが中国のサーバから時刻を取得し、サーバとクライアントの時差を考慮して、サーバから取得した時間をクライアントのロケールの時間に変換したい (TimeZoneInfo.ConvertTime)」が質問者が求めるものだと解釈したので、上記のような回答になりました。 中国の標準時とサーバの時刻が一致しているのなら、UTC時間あるいはJSTを使えば良いと思いますが、中国のサーバから取得した時刻を使うコードになっているのは、そうしなければならない事情があるのかと考えました。

    キャンセル

checkベストアンサー

+2

 サーバから日付出力

まず、サーバから日付出力する場合に次のどちらのフォーマットにしてください。

  • タイムゾーン付きの日付フォーマット
  • UTC日時(世界標準日時)の日付フォーマット

 ISO 8601

サーバから ISO 8601 形式の日付文字列を出力できれば、時差なく JavaScript で処理できます。

/**
 * 日本日時
 */
console.log(new Date('2017-03-01T16:00:00+09:00').toString());  // Wed Mar 01 2017 16:00:00 GMT+0900 (東京 (標準時))

/**
 * 中国日時
 */
console.log(new Date('2017-03-01T15:00:00+08:00').toString());  // Wed Mar 01 2017 16:00:00 GMT+0900 (東京 (標準時))

/**
 * 世界標準日時
 */
console.log(new Date('2017-03-01T07:00:00Z').toString());  // Wed Mar 01 2017 16:00:00 GMT+0900 (東京 (標準時))

なぜなら、JavaScript の Date オブジェクトは内部的に「1970/01/01 0:00からのUTC時間」として扱うからです。

/**
 * 日本日時
 */
console.log(new Date('2017-03-01T16:00:00+09:00').getTime());  // 1488351600000

/**
 * 中国日時
 */
console.log(new Date('2017-03-01T15:00:00+08:00').getTime());  // 1488351600000

/**
 * 世界標準日時
 */
console.log(new Date('2017-03-01T07:00:00Z').getTime());       // 1488351600000

 Date.UTC()

UTC日時が得られれば、Date.UTC() を使用する方法もあります。

console.log(new Date(Date.UTC(2017, 3, 1, 7, 0, 0, 0)).toString()); // Sat Apr 01 2017 16:00:00 GMT+0900 (東京 (標準時))

Re: clubman さん

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/03 10:44

    think49さま、丁寧な解説ありがとうございます。
    UTC日時を使う方がやりやすそうなのでそちらでアプローチしてみたいと思います。
    ありがとうございました!

    キャンセル

0

「クライアントはJavaScriptサーバーサイドはC#で開発」ということは ASP.NET Web アプリでしょうか? (であれば、ASP.NET のタグもつけていただければ)

サーバーとクライアントの PC の時間の整合を取るということが目的なのですか?

そうであれば、JavaScript でクライアント PC の時刻を取得して、何らかの手段(PostBack するなり Ajax を使うなりして)でサーバーにその情報を送って、サーバー側で時間差を調べて整合を取るというようなことが可能と思いますが。

クライアント側の現地時刻取得
http://surferonwww.info/BlogEngine/post/2010/10/06/How-to-obtain-local-time-of-client-side.aspx

そういう話ではないということでしたら、何を作っているのか(ASP.NET web アプリ? その他?)、全体的なシナリオを含めてやりたいことは何かを書いていただけませんか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/01 16:05

    SurferOnWwwさま、ご回答ありがとうございます。
    はい、サーバー側はASP.Net MVC5を採用しています。

    やりたいこととしてはタイムスタンプ的なことになります。クライアントの時刻をそのまま使ってしまうと時間がズレていたり意図的に変えられてしまうためサーバーの時刻を使いたいのです。そしてサーバーは海外にあるかもしれないのでクライアントのロケールを使ってサーバーの時刻をクライアントのロケール時刻に変換したいというシナリオになります。

    ご紹介くださったページですとクライアントの時刻をそのまま出力しているだけに思えますので要件を満たすことができなさそうです。

    よろしくお願いいたします。

    キャンセル

  • 2017/03/01 16:32 編集

    JavaScript でロケール / カルチャが取得できるかどうかわかりませんが(個人的にはできないと思いますが、自分が知らないだけという可能性を否定しきれませんので、そこはちょっと置いといて)、たとえ取得できたとしてそれから現地時間が取得できるのでしょうか?

    たとえば、en-US であることが分かったとして、時差(米国は東海岸と西海岸で 3 時間時差があります)とか夏時間とかはどう対応できるのでしょうか? 米国で日本語 OS の PC を使っていたらどうなるのでしょうか? Culture はプログラムで任意に書き換えられるのですが、そこのところはどう考えていますか?

    キャンセル

  • 2017/03/02 10:07 編集

    ロケールが取得できても(そもそもJsでは取得できないようですが)JavaScriptでは現地時間は取得できないと思います。
    夏時間とかはどう対応できるかについてはC#ですとTimeZoneInfo.CreateCustomTimeZone()を使えるのなら対応できるとしか答えられません。
    Culture は「プログラム」で書き換えられることは無視でよいです。そこまでされたらどんなプログラムでも同じだと思います。

    キャンセル

  • 2017/03/02 10:55

    > JavaScriptでは現地時間は取得できないと思います。

    質問者さんの言う「現地時間」というのが何だか分かりませんが、ブラウザを動かしている PC の時間(Windows や Android の場合「日付と時刻」に設定された日時)なら JavaScript で取得できます。

    上の回答で紹介した記事の下の方に「実験室」と書いたリンク先がありますが、そこで実際に試すことができますのでやってみてください。

    さらに、coco_bauer さんの回答によると UTC も取得できるそうです。それで十分ではないかと思いますが。

    どうしても ja-JP とか en-US などのカルチャ情報がほしければ、ブラウザからの要求ヘッダに含まれる Accept-Language を見るという手はあるかもしれません。でも、国内に時差のない国ならともかく、前のコメントに書きましたように、en-US では取得しても意味はなさそうですよ。

    キャンセル

  • 2017/03/02 14:05

    「現地時間」というのは上記のコメントでSurferOnWwwさまがおっしゃったことなのですが、、

    それはさておきやりたいことは「サーバーの時刻」を「クライアントのロケールの時刻」に変換したいのです。ブラウザを動かしている PC の時間を取得したいわけではありません。
    意図が伝わりづらかったようなら申し訳ございません。

    キャンセル

  • 2017/03/02 16:58

    > やりたいことは「サーバーの時刻」を「クライアントのロケールの時刻」に変換

    「クライアントのロケールの時刻」というのが意味不明です。「ブラウザを動かしている PC の時間」ではないということですが、では一体何なのでしょう?

    質問者さんの前のコメントで、

    > クライアントの時刻をそのまま使ってしまうと時間がズレていたり意図的に変えられてしまう

    という懸念がありましたが、そういうことがなければ「ブラウザを動かしている PC の時間」=「クライアントのロケールの時刻」でいいのですかね?

    であれば、JavaScript で取得する UTC とサーバーで取得する UTC を比較してズレがなければその懸念はないということで、「ブラウザを動かしている PC の時間」を使えばいいのでは?

    ズレていたらお手上げになるかもしれませんが、質問者さんの言う「クライアントのロケールの時刻」は取得できそうもありませんし、他に方法はないと思います。

    キャンセル

  • 2017/03/02 17:48

    「ロケール」にあたるものとしては時間帯の設定があるでしょうが、たとえ時間帯の設定がわかったとしても、それに基づく時刻を計算するのは大変だと思います。

    そんなことをしなくても、クライアントでのUTCとローカルタイムの差を取得することでUTCからの時差を求め、サーバの時刻を基準にローカルタイムを計算してやるという方法 (coco_bauerさんがおっしゃっている方法) で充分ではないかと思います。

    キャンセル

  • 2017/03/02 19:00

    ikedas さん>
    誰のどの部分に対するコメントですか?

    キャンセル

  • 2017/03/02 19:55 編集

    日本語ロケールで Date#toString() すると日本時間になる事から誤解が生まれた気がしますが、JavaScript はロケールを扱えます。
    内部的にUTC時間(1970/01/01からのミリ秒)に変換されたプリミティブ値を持っています。
    それが中国時間であってもアメリカ時間であっても ISO 8601 形式で入力すれば、UTC時間としての正しい値を持ちます。
    new Date(yyyy, mm, dd) で日本時刻として扱われてしまうのは new Date がブラウザのロケールに合わせた値として認識してしまうからです。
    サーバから生のデータをJavaScriptに入力したいのなら ISO 8601 が選択肢になると思います。

    キャンセル

  • 2017/03/02 20:08

    > SurferOnWwwさん
    質問者さんの発言へのコメントです。

    キャンセル

  • 2017/03/02 22:24 編集

    ikedas さん>
    であれば、私の回答のコメントではなく ikedas さんご自身の回答として別に書いていただくというわけにはいきませんか?

    キャンセル

  • 2017/03/02 22:26

    think49 さん>
    誰のどの部分に対するコメントですか?

    キャンセル

  • 2017/03/02 23:25

    To: SurferOnWww さん
    SurferOnWww さん、ikedas さんは共に時差の計算はいろいろと小難しい計算をしなければならない、というニュアンスの意見のように読めましたが、それほど大変ではないと指摘しました。
    new Date('2017-03-01T15:00:00+08:00').toString(); // "Wed Mar 01 2017 16:00:00 GMT+0900 (東京 (標準時))" (クライアント側のロケールで出力)

    それと、質問者の要件である「サーバの時刻を使用する要件」に否定的のようですが、そこを否定してしまうと質問に対する回答としては適切ではないようにも思っています。
    例えば、掲示板の記事の投稿日時など、クライアント側の現在時刻を使う事が意図されていない可能性も考えられます。
    通常の掲示板ではサーバが出力した日付フォーマットをそのまま出力するだけですが、クライアントのロケール時刻の自動的に変換されるならそれはそれで面白いのではないかと思います。

    キャンセル

  • 2017/03/02 23:38

    think49 さん>
    話が噛み合ってないような気がします。質問者さんのやりたいことが分かっていますか? 私は分からないのですが。

    キャンセル

  • 2017/03/02 23:47

    think49 さん>
    あ、そういうことを聞く前に、「誰のどの部分に対するコメントですか?」に答えていただきたいとお願いするのが先でした。

    キャンセル

  • 2017/03/02 23:58

    think49さんのコメントで得心しました (たぶん)。Dateでは時刻が内部的にUTCで正規化されており、UTCを与えても地方時の時刻情報を得ることができる、ということですね。私が求めていたのはそれでした (「まず時差を得て…」とか考える必要はなく、クライアントではUTCを与えられればダイレクトに地方時を得られる、ということと理解しました)。

    なお、時刻のロケールと時間帯の設定は別のものなので、JavaScriptの仕様としてどう折り合いをつけているのかは気になりました。そのうち調べてみようと思います。

    キャンセル

0

こんにちは。

タイムスタンプであれば、サーバからクライアントまで、データ上は全てUTCで取り扱うというのはどうでしょう?
記録するときはサーバ上でUTC時刻を生成すれば、クライアントとの時差やサーバの設置場所による影響などは一切ないです。
そして、クライアント上で時刻を表示したいときに、生データのUTC時刻をクライアント上で自ロケール表現に変換すればいいのではないでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/02 13:51

    tamotoさま、ご回答ありがとうございます。

    はい、全ての時刻をUTCで扱うというのはその通りだと思います。
    ですが、「生データのUTC時刻をクライアント上で自ロケール表現に変換」というところがポイントでして、JavaScriptではロケール情報が取得できないため「自ロケール表現に変換」ということができないのかなと思い行き詰まっています。

    キャンセル

  • 2017/03/02 13:58

    javascriptには余り詳しくなくて申し訳ないですが、質問の通りの「ロケール情報を取得しサーバに送る」という情報は見つかりませんでしたが、「javascript上でUTCの時刻データをローカル時刻に変換する」というtipsなら調べるといくつか引っかかりました。タイムスタンプの用途であれば、こちらで対応できないものでしょうか?

    キャンセル

  • 2017/03/02 14:10

    ありがとうございます。
    やりたいこととしてはまさにその通りです。
    調査してみたいと思います!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    16389questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • C#

    7102questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • ASP.NET MVC Framework

    59questions

    ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。