なか日記

一度きりの人生、楽しく生きよう。

Azure上のアプリと日付をどうやり取りするのがいい?

いい歳してこっ恥ずかしいけど、こういうおっさんも居るんだと生暖かい目で見て欲しいと思います。

Azureに配置したアプリケーションで日付を取得するとUTC(協定世界時)で取得されます。これは、サーバが世界中に分散されており、場所が特定出来ないから日付はUTCで扱うということなのだと思います*1

日本国内にあるレンタルサーバ等なら、JSTに設定されてたりしてタイムゾーンを意識しなくてもいい感じに動いてくれたりしますが、Azureを使うとなるとちゃんと考えてないとダメですね。

というわけで、誰かクライアントとサーバ間でどうやりとりするのが良いか教えて~。

前提

サーバ側ではUTCで日時を扱うこととします。

レスポンス(UTCからJSTへ)

日本にいる人しか使わない前提であれば、表示(ブラウザへのレスポンス)は以下の様な方法で変換できると [C#] Windows Azure アプリケーションで時刻を処理する in C# に紹介されていましたので、以下に引用します。

DateTime AzureTime; 
DateTime JapaneseTime; 
 
AzureTime = DateTime.Now; 
TimeZoneInfo tst = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time"); 
JapaneseTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.Now.ToUniversalTime(),tst); 
 
Label1.Text = String.Format("Azure 上では {0:F} です。", AzureTime); 
Label2.Text = String.Format("日本では {0:F} です。",JapaneseTime);

DateTime.Now.ToUniversalTime()がポイントでしょうか。敢えてUTCに変換することで、ローカル(日本)で実行した場合にも正しく動作するようになっています。

疑問、そして自己解決

そもそも、日本でしか使わないと限定するなら、DateTime.Now.ToUniversalTime().AddHours(9) でも良いような気がします。 そうしていないのは複数の地域で使うことを考えると安直に+9なんてしちゃダメよってことなんでしょうね。

リクエスト(JSTからUTCへ)

ここがよくわからないところ。 ブラウザで日付を入力させる際、タイムゾーンなんて意識させないですよね。基本、日本にいる場合は日本の時間(JST)で入力することになると思います。

例えば、サーバに「2013/11/29 19:00」という日時が送信されてきたとします。この時、この日時はUTCなのか、JSTなのか、それとも他の地域の時刻なのか、どう判断させるのが良いのでしょうか?

考えてみた

というわけで、いくつか方法を考えてみました。

  1. タイムゾーンをユーザーに設定してもらう
    一番確実な方法だと思います。でも、ユーザーからするとちょっと面倒くさいですよね。タイムゾーンって何?って人もいるだろうし…

  2. サーバへ送信する際、ブラウザ側でISO形式に変換する
    サーバ側で判断させるのが難しいなら、クライアント側で形式を統一すればいいじゃない。というわけで、 JavaScript の Date オブジェクトが持ってる toISOString メソッドでISO形式に変換してサーバへ送信ればいいんじゃない?*2

  3. 日時と一緒にUTCとの時差を送信する
    JavaScript の Date オブジェクトが持ってる getTimezoneOffset メソッドでクライアントの時刻とUTCの時差を送ってあげれば、サーバ側では送られてきた日時と時差でUTC日時が計算できますね。

で、一般的にはどうするの?

多少ググったりはした物の、これだ!という情報には行き着きませんでした。

個人的には、1パラメータで送信するときは2で、年・月・日・時・分・秒をそれぞれ別々のパラメータとして送信するときは3かなぁ。

それにしても、知らない事が多すぎる…

*1:逆にUTCで扱ってくれないとくそめんどくさそう

*2:Choromeで確認したところ、日時はUTCになるみたい