テーブル定義内のTIMESTAMP型のデータについて。
こんにちは、皆さま。
業務でIRISを用いて開発を行っている者です。
TIMESTAMP型のデータを持つテーブルの扱いについて教えてください。
現在Ens_Util.Logを参照するシステムを開発しようとしております。
このテーブルの中にTimeLoggedというTIMESTAMP型のデータがあるのですが、
それをSELECTした際、CASTの有無で表示されるデータに差異が出ます。
SELECT
DATE(TimeLogged),
CAST(TimeLogged AS TIME),
TimeLogged
FROM
Ens_Util.Log
Expression_1|Expression_2|TimeLogged |
------------+------------+-------------------+
2022-01-25| 15:00:01|2022-01-26 00:00:01|
2022-01-25| 15:00:01|2022-01-26 00:00:01|
2022-01-25| 15:00:01|2022-01-26 00:00:01|
確認する限り9時間の差があるため、UTC時刻との時差が出ているものと考えていますが、ここで何点か疑問があります。
①
テーブルに格納されているタイムスタンプはUTC時刻か、ローカル時刻かどちらでしょうか?
⇒おそらくローカル時刻と考えています。
②
何故CASTの有無で、ローカル時刻の適応(or 除外?)の差分が出るのでしょうか?
私のIRIS側の設定の問題なのでしょうか。。
③
上記の例ではSELECTでしたが、WHEREの条件にTimeLoggedを入れたときも-9時間された値で条件に含まれる挙動をしています。
これを実際にテーブルの中に格納されている、-9時間されていない状態で扱う方法はありませんでしょうか?
力技ですが、以下のようなやり口しか思い浮かんでいません。
> WHERE $PIECE(DATEADD(hh, 9, TimeLogged), ' ', 1) >= '2022-01-26'
何かヒントがありましたら、ご教示いただけますと幸いです。
Ohataさん
こんばんは。
Ens.Util.LogテーブルのTimeLoggedカラムを見ると、Ens.DataType.UTCとなっていました。これはUTCで保管されているのですが、表示するときにLogicalToDisplay()などでローカル時刻に変換しています。
従いまして、①については、実体としてUTCで保管されています。
②についてはEns.DataType.UTCは表示するときにローカル時刻に変換されますが、キャストしたものは型が異なるので変換されずに表示されるからだと思います。
③についても、WHERE句の条件はUTCで計算されますので、記載されたようにDATEADDで変換するしかなさそうです。
ただTimeLoggedカラムに変換をかけるよりも、指定したパラメータをUTCに変換する方が、DBのインデックスも使用できるので効率が良いかと思います。
WHERE timelogged >= DATEADD('hh',-9,'2022-01-26')
Minamotoさん
こんにちは。ご回答いただきありがとうございます!
丁寧に教えていただきありがとうございます。
ローカル時刻で扱おうとすると、なかなか癖があるものなんですね。。
一度記載いただいた方法で試してみます!
Ohataさん
こんにちは。
APIでは、$SYSTEM.Util.UTCtoLocalWithZTIMEZONE()、$SYSTEM.Util.LocalWithZTIMEZONEtoUTC() などがあるみたいです。タイムゾーンが正しく設定されていれば、"-9" 等の固定値を使わなくても良いかもしれませんね。
Hashimoto さん
こんにちは。
コメントいただきありがとうございます!
確かに、ObjectScript内ではそのようなAPIも使えそうですね!
SQL関数として同様の振舞をするものがあればもっと良かったのですが、
自分の方ではなかなか見つけられませんでした。
Ohataさん
こんにちは。
ユーザー定義関数で準備すればSQLから使えるのではないかと思います。
ObjectScriptで処理した方がいい場合や使いたいコマンド等に、よく使います。
Hashimoto さん
こんにちは。
なるほど、この辺のお話ですね。
https://irisdocs.intersystems.com/iris20211/csp/docbookj/DocBook.UI.Page...
実行パフォーマンスとか気にして、今まで利用したことなかったですが、
一度実験してみようと思います。ありがとうございます!
Ohataさん
こんにちは。
$ZTIMEZONEを使えるかもしれません。
SAMPLES>w $ZTIMEZONE
-540
SELECT DATEADD(MI,$ZTIMEZONE,'2022-01-26 00:00:01')
Iwamotoさん
こんにちは。
情報共有いただきありがとうございます!
$ZTIMEZONEは秒のオフセットを返してくれるのですね!
オフセットの単位がわからず使いこなせなかったのですが、
頂いた方法で対応できそうです。