OutSystemsサーバのタイムゾーンとユーザの端末のタイムゾーンが異なっている場合、補正を行わなければなりません。
日時(DateTime, Date, Time)を使う箇所が少なければ、コード内で計算してもいいですが、いちいち実装するのは面倒だし、他のタイムゾーン対応が必要になると大変なので、UIとDBに保存する値の間で日時をきれいに変換する方法を考えてみます。
クラウドのSQL Server環境だとUTC固定(OutSystems Cloud and time zones)だったりする問題もあります。
Time Zone (Version: 6.0.0)
動作確認環境
Platform Version:11.0.108.0
Service Studio Version:11.0.208.0
サーバのタイムゾーンを取得する
Time Zoneコンポーネントに含まれているGetCurrentTimeZone Actionで取得できます。
戻り値はコンポーネントの提供するStructure TimeZoneです。
GetCurrentTimeZone().TimeZone.UtcOffset
でサーバタイムゾーンのUTCからの差分を分単位の整数で取得できます。
Personal EnvironmentではUTCなので0でした。
サーバのタイムゾーンは実行時に変わることがないので、Site Propertyに定義した方がいいかもしれません。
このコンポーネントはExtensionなので、C#のソースが処理の本体になっています。GetCurrentTimeZone Actionのタイムゾーンは、
TimeZoneInfo tzi = TimeZoneInfo.Local;
で取得されます。
プロパティのドキュメントによると実行するコンピュータローカルのタイムゾーンをそのまま返すようです。
クライアントのタイムゾーンを取得する
クライアント環境(ユーザのブラウザ・OS)のタイムゾーンなので、サーバの処理で取得することはできません。
以下のような方法が考えられます。
- 開発するアプリケーションで全てのユーザが同じタイムゾーンを使う場合、Siteプロパティに事前に設定しておく方法があります
- ユーザごとなど、一定のグループごとに違うタイムゾーンを使うなら、設定をEntityに保持する方法もあります
- 完全に動的にクライアントの実行環境からJavaScriptで取得することもできます
ForgeのTime Zoneコンポーネントを紹介するブログ記事(OUTSYSTEMS: HOW TO HANDLE MULTI TIME ZONE APPLICATIONS?)に3の場合のサンプルコードがあります。
タイムゾーンのオフセットを取得するJavaScriptコード
new Date().getTimezoneOffset()
Chromeで実行すると、-540と言う結果が得られました。
分単位でUTCのDateTime – クライアント環境のDateTimeで算出するオフセットがとれるようですね。
JavaScriptで取得するので、サーバで利用するためには、Ajax Submitのボタン等を利用してサーバにデータを渡してあげる必要があります。ブックマークから来た場合のことを考えて、ヘッダ等の共通Blockでとるのがいいですね。
タイムゾーンは変わらないでしょうから、一度取得したらセッションやEntityに保存しておきたい。