Unix タイムスタンプは、1970 年 1 月 1 日 UTC からの整数秒数です。
データベースにこの数値の整数列があると仮定すると、データベース サーバーのタイム ゾーンは関係ありません。
最初にタイムスタンプを datetime
に変換します タイプ:
SELECT DATEADD(second, yourTimeStamp, '1970-01-01')
これは UTC datetime
になります
次に、この値をターゲット タイム ゾーンに調整する方法を知る必要があります。世界のほとんどの地域では、夏時間のため、1 つのゾーンに複数のオフセットが設定される場合があります。
残念ながら、SQL Server にはタイム ゾーンを直接操作する機能がありません。たとえば、米国太平洋時間を使用している場合、7 時間または 8 時間を差し引く必要があるかどうかを知る方法はありません。他のデータベース (Oracle、Postgres、MySql など) にはこれを処理する方法が組み込まれていますが、残念ながら SQL Server にはありません。したがって、汎用的なソリューションを探している場合は、次のいずれかを実行する必要があります:
- <リ>
タイム ゾーン データをテーブルにインポートし、タイム ゾーン ルールの変更に合わせてそのテーブルを維持します。そのテーブルを一連のカスタム ロジックと共に使用して、特定の日付のオフセットを解決します。
<リ>
xp_regread
を使用 タイム ゾーン データを含む Windows レジストリ キーを取得し、一連のカスタム ロジックを使用して特定の日付のオフセットを解決します。もちろん、xp_regread
これは悪いことであり、付与された特定の権限が必要であり、サポートも文書化もされていません。
TimeZoneInfo
を使用する SQLCLR 関数を記述します。 .Net のクラス。残念ながら、この 「安全でない」SQLCLR アセンブリが必要です
、悪いことが起こる可能性があります。
IMHO、これらのアプローチはどれも非常に優れたものではなく、これを SQL で直接行うための適切な解決策はありません。最善の解決策は、UTC 値 (元の整数または datetime
のいずれか) を返すことです。 UTC で) 呼び出し元のアプリケーション コードに変換し、代わりにそこでタイムゾーン変換を行います (たとえば、TimeZoneInfo
を使用)。 .Net または他のプラットフォームの同様のメカニズムで)。
ただし、クウェートは夏時間に変更されないゾーンにあるという点で幸運です (そして常にそうでした)。常に UTC+03:00 です。したがって、単純に 3 時間を加算して結果を返すことができます:
SELECT DATEADD(hour, 3, DATEADD(second, yourTimeStamp, '1970-01-01'))
ただし、これはどのタイム ゾーンでも機能する汎用ソリューションではないことを認識してください。
必要に応じて、datetimeoffset
など、他の SQL データ型のいずれかを返すことができます。 、しかし、これは、値が誰にとっても3時間のオフセットであることを反映するのに役立ちます.変換プロセスが変わったり、良くなったりすることはありません。
更新された回答
SQL Server でタイム ゾーンをサポートするためのプロジェクトを作成しました。 こちら からインストールできます .次に、次のように簡単に変換できます:
SELECT Tzdb.UtcToLocal('2015-07-01 00:00:00', 'Asia/Kuwait')
IANA tz データベースの任意のタイム ゾーン を使用できます 、夏時間を使用するものを含みます。
上記の方法を使用して、UNIX タイムスタンプから変換することもできます。両方をまとめると:
SELECT Tzdb.UtcToLocal(DATEADD(second, yourTimeStamp, '1970-01-01'), 'Asia/Kuwait')
再更新
SQL Server 2016 では、 を使用したタイム ゾーンのサポートが組み込まれています。 AT TIME ZONE
声明。これは、Azure SQL データベース (v12) でも利用できます。
SELECT DATEADD(second, yourTimeStamp, '1970-01-01') AT TIME ZONE 'Arab Standard Time'