0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プリザンターのタイムゾーンの考え方を詳しくみてみる[第3回:API編]

0
Posted at

はじめに

プリザンターの API で日時を送受信するとき、そのタイムゾーンはどうやって決まるのでしょうか。DB にはタイムゾーン情報なしの DateTime が格納されているため、API 側で何らかの基準が必要になります。

本記事では、API での日時変換の仕組みと、知っておくべきポイントを紹介します。

テーマ
第 1 回 アーキテクチャ編 — 全体設計と変換の仕組み
第 2 回 サーバスクリプト編 — SS 固有の変換方式と注意点
第 3 回(本記事) API 編 — API でのタイムゾーンの取り扱い
第 4 回 タイムゾーン混在環境編 — ユーザーのタイムゾーンが混在する場合の問題と対策

バージョン 1.5.1.0 を対象にしています

API のタイムゾーン基準

API の日時処理で最も重要なポイントは、API キーに紐づくユーザーのタイムゾーンが基準になるということです。

リクエスト側でタイムゾーンを指定する手段はありません。同じ日時文字列を送信しても、API キーの所有ユーザーのタイムゾーン設定によって異なるサーバーローカル日時に変換されます。

API リクエスト時の変換フロー

API でレコードを作成・更新する際の日時変換は、フォーム入力と同じ ToUniversal(context) が使われます。

例えば API キーの所有ユーザーのタイムゾーンが JST(+9)で、サーバータイムゾーンが UTC の場合、"2024/01/15 09:00" という入力値は 2024/01/15 00:00(UTC)として DB に保存されます。

API レスポンス時の変換フロー

API レスポンスでも、API キーの所有ユーザーのタイムゾーンで日時が返却されます

入力と出力で対称的な変換が行われるため、同じ API キーで操作する限り日時のズレは発生しません

API キーのユーザータイムゾーンが異なる場合

ここで気をつけたいのが、異なるタイムゾーンのユーザーが同じレコードを API 経由で操作するケースです。

例: ユーザー A(JST)で登録、ユーザー B(PST)で取得

これは日時として正しい変換です。JST の 1/15 09:00 と PST の 1/14 16:00 は同じ瞬間を指しています。ただし、日付のみのフィールド(Ymd 形式)では日付が変わってしまうことがあり、これは第 4 回で詳しく扱います。

CSV インポートのタイムゾーン

CSV インポートも API と同様に、インポート実行ユーザーのタイムゾーンで日時が解釈されます。

Implem.Pleasanter/Libraries/Settings/Column.cs
else if (TypeName == "datetime")
{
    return value?.ToDateTime(format: RecordingFormat)
        .ToUniversal(context: context).ToString()
        ?? string.Empty;
}

context はインポートを実行したユーザーのコンテキストです。つまり同じ CSV ファイルでも、インポートするユーザーのタイムゾーンが異なれば、DB に格納される日時が変わります。

例: 同じ CSV を異なるタイムゾーンのユーザーがインポート

CSV の値 ユーザータイムゾーン ToUniversal 結果(サーバータイムゾーン=UTC) DB 値
2024/01/15 09:00 JST (+9) 2024/01/15 00:00 2024/01/15 00:00
2024/01/15 09:00 PST (-8) 2024/01/15 17:00 2024/01/15 17:00

同じ 09:00 という値でも、ユーザータイムゾーンによって DB に格納される値が異なります。

CSV インポートを行う際は、CSV 内の日時がどのタイムゾーンを想定しているかを意識し、インポート実行ユーザーのタイムゾーン設定を確認しましょう。

API 連携時の実践的な注意点

1. API キーのタイムゾーンを統一する

外部システムとの連携で複数の API キーを使う場合、すべての API キーのユーザータイムゾーンを統一することで日時の混乱を防げます。

2. サーバータイムゾーンと API ユーザータイムゾーンを合わせる

API キーの所有ユーザーのタイムゾーンがサーバーローカルタイムゾーンと同一であれば、ToUniversal / ToLocal がスキップされ、送信した日時がそのまま DB に格納されます。

Implem.Pleasanter/Libraries/Server/Times.cs
public static DateTime ToUniversal(this DateTime value, Context context)
{
    var timeZoneInfo = context.TimeZoneInfo;
    if (timeZoneInfo == null || timeZoneInfo.Id == TimeZoneInfo.Local.Id)
        return value;  // 同一タイムゾーンならスキップ
    return TimeZoneInfo.ConvertTime(value, timeZoneInfo, TimeZoneInfo.Local);
}

3. 日時形式に注意する

API で日時を送信する際は、プリザンターが受け付ける形式で指定します。タイムゾーン情報(Z+09:00 など)を付与しても、リクエスト内のタイムゾーン情報は無視され、API キーのユーザータイムゾーンが使われます

4. バックグラウンド処理のタイムゾーン

バックグラウンドサーバスクリプトのスケジュール評価では、以下の優先順位でタイムゾーンが決定されます。

優先順位 設定値 説明
1 schedule.ScheduleTimeZoneId スケジュール個別設定
2 TimeZoneDefault Service.json のシステムデフォルト
3 UTC いずれも未設定時のフォールバック
Implem.Pleasanter/Libraries/Settings/BackgroundServerScriptUtilities.cs
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(
    !schedule.ScheduleTimeZoneId.IsNullOrEmpty()
        ? schedule.ScheduleTimeZoneId
        : !Parameters.Service.TimeZoneDefault.IsNullOrEmpty()
            ? Parameters.Service.TimeZoneDefault
            : TimeZoneInfo.Utc.Id);

フロントエンドへのタイムゾーン情報伝達

補足として、画面表示の際にはユーザータイムゾーンの情報がフロントエンドにも伝達されています。

Implem.Pleasanter/Libraries/HtmlParts/HtmlTemplates.cs
.Hidden(
    controlId: "TimeZoneOffset",
    value: context.TimeZoneInfoOffset())  // 例: "+09:00"

この値は HTML の hidden 要素として埋め込まれ、フロントエンドの JavaScript で日付ピッカーなどの表示補正に使用されます。API 連携ではこの仕組みは無関係ですが、タイムゾーン情報の伝達方法として知っておくと役立ちます。

入力経路ごとのタイムゾーン基準の比較

ここまでの内容を含め、各入力経路でタイムゾーン基準がどう決まるかをまとめます。

入力経路 タイムゾーン基準の決定要因 注意点
フォーム入力 ログインユーザーのタイムゾーン ユーザーの画面操作なので直感的
API リクエスト API キー所有ユーザーのタイムゾーン リクエスト側でタイムゾーン指定不可
CSV インポート インポート実行ユーザーのタイムゾーン CSV 内の日時がどのタイムゾーンかを意識
サーバスクリプト(通常) UTC 固定 ユーザータイムゾーンを一切使わない
計算式サーバスクリプト 操作ユーザーのタイムゾーン フォーム入力と同じ方式

まとめ

API でのタイムゾーン処理のポイントをまとめます。

  • API では API キーに紐づくユーザーのタイムゾーンが基準になる
  • リクエスト側でタイムゾーンを指定する手段はない
  • 入出力は ToUniversal / ToLocal で対称変換されるため、同じ API キーで操作する限り日時のズレは発生しない
  • CSV インポートもインポート実行ユーザーのタイムゾーンが基準になる
  • 外部連携では API キーのタイムゾーンを統一するのが安全
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?