intra-mart Accel Platform スクリプト開発モデル プログラミングガイド 第17版 2021-12-01

ユーザのタイムゾーン、日付と時刻の形式を利用する

前提

  • 各種設定値
設定項目 設定値
ユーザ・タイムゾーン (GMT+09:00) 日本 / 東京
システム・タイムゾーン (GMT+00:00) UTC
日付と時刻の形式 英語形式
日付(標準表示) MMM d, yyyy
日付(簡易表示) MMM d
日付(入力) yyyy/MM/dd
時刻(標準表示) h:mm a
時刻(タイムスタンプ表示) h:mm:ss a
時刻(入力) | HH:mm
  • テーブル定義

    CREATE TABLE example_table (
        user_cd     VARCHAR(100) NOT NULL,
        update_date TIMESTAMP  NOT NULL,
        PRIMARY KEY (user_cd)
    );
    

画面から送信された日時データを DB に保存する

画面から入力された日時データをサーバ側で解析して、DB に保存するまでの流れを説明します。
ユーザが以下の日時データを入力し、サーバに送信したとします。
2012/09/19 03:46

1. 画面から送信された日時文字列を解析する

function init(request) {
    var inputDateStr = request.inputDate; //画面から送信された日時文字列
    var inputDate = AccountDateTimeFormatter.parseToDate(inputDateStr,
            AccountDateTimeFormatter.IM_DATETIME_FORMAT_DATE_INPUT,
            AccountDateTimeFormatter.IM_DATETIME_FORMAT_TIME_INPUT);
}
日時文字列がユーザの日付と時刻の入力形式に沿っている場合、AccountDateTimeFormatter を使用します。
AccountDateTimeFormatter は、ログインユーザのタイムゾーンを使って解析を行います。

2. DB へ日時データを保存する

var db = new TenantDatabase();
var userCd = Contexts.getAccountContext().userCd;
Transaction.begin(function() {
    db.execute('INSERT INTO example_table values(?, ?)', [DbParameter.string(userCd), DbParameter.timestamp(inputDate)]);
});
DB には、システム・デフォルト・タイムゾーンに変換された日時データを保存します。
Date 型オブジェクトは、タイムゾーンを持たないため、DB の TIMESTAMP 型カラムには JDK のタイムゾーンに変換された日時データが保存されます。
JDK のタイムゾーンとシステム・デフォルト・タイムゾーンは同じです。

画面から送信された日付データを DB に保存する

画面から入力された日付データをサーバ側で解析して、DB に保存するまでの流れを説明します。

注意

画面から日付のみを入力させる場合でも、次の例のように、通常は時刻まで考慮しなければなりません。

(例)交通費申請の締め切り日

「締め切り日」には、23時59分59秒(または、営業時間)まで、という時刻に関する意味が含まれています。
例えば、本社のある日本(GMT+09:00)の9月19日が締め切り日だとすると、ホノルル(GMT-10:00)支社では、9月19日 午前5時までに交通費申請を終わらせなければなりません。

画面には、ユーザの日付入力形式で次の値が入力され、サーバに送信されたとします。
2012/09/19

1. 画面から送信された日付文字列を解析する

function init(request) {
    var inputDateStr = request.inputDate; //画面から送信された日付文字列
    var inputDate = AccountDateTimeFormatter.parseToDate(inputDateStr, AccountDateTimeFormatter.IM_DATETIME_FORMAT_DATE_INPUT);
}
日付文字列の場合、時刻部分は「00:00:00」として解析されます。

2. DB へ日付を保存する

「DB へ日時データを保存する」と同様です。

DB に保存されている日時データをユーザの画面に表示する

DB に保存されている日時データを、ユーザのタイムゾーン、日付と時刻の表示形式を使って日時文字列に整形し、画面に表示するまでの流れを説明します。

1. DB から日時データを取得する

var db = new TenantDatabase();
var userCd = Contexts.getAccountContext().userCd;
var result = db.select('SELECT update_date FROM example_table WHERE user_cd=?', [DbParameter.string(userCd)]);
if (result.error) {
    return;
}
var outputDate = result.data[0];
DB には、システム・デフォルト・タイムゾーンに変換された日時データが保存されています。

2. 日時文字列に整形する

var outputDateStr = AccountDateTimeFormatter.format(outputDate,
        AccountDateTimeFormatter.IM_DATETIME_FORMAT_DATE_STANDARD,
        AccountDateTimeFormatter.IM_DATETIME_FORMAT_TIME_STANDARD);
ユーザの日付と時刻の表示形式で整形する場合、AccountDateTimeFormatter を使用します。
AccountDateTimeFormatter は、ログインユーザのタイムゾーンで時刻を計算します。
以下の結果が得られます。
Sep 19, 2012 3:46 AM

DB に保存されている日付をユーザの画面に表示する

DB に保存されている日付を、ユーザのタイムゾーン、日付の表示形式を使って日付文字列に整形し、画面に表示するまでの流れを説明します。

1. DB から日付を取得する

「DB から日時データを取得する」と同様です。

2. 日付文字列に整形する

var outputDateStr = AccountDateTimeFormatter.format(outputDate, AccountDateTimeFormatter.IM_DATETIME_FORMAT_DATE_STANDARD);
「日時文字列に整形する」と同様です。
以下の結果が得られます。
Sep 19, 2012

クライアント側で、ユーザ・タイムゾーンの今日から3日間の日付を生成し、最後の日付をサーバ側へ送信する

このサンプルを通して、csjs で日時データを扱う際に注意する点を理解します。

1. ユーザ・タイムゾーンの今日を取得する

ユーザ・タイムゾーンとは、ユーザが intra-mart Accel Platform に登録したタイムゾーンのことです。
ユーザ・タイムゾーンにおける「今日」を csjs で取得するためには、intra-mart Accel Platform から提供されている ImDate を使用します。

注意

ユーザ・タイムゾーンにおける「今日」の取得に、csjs の new Date を利用しないでください。
csjs の new Date はクライアント OS のタイムゾーンにおける現在日時データを返しますが、ユーザ・タイムゾーンがクライアント OS のタイムゾーンと一致しているとは限りません。
<script type="text/javascript" src="im_i18n/timezone/im_date_timezone.js"></script>
<script type="text/javascript">
var firstDate = ImDate.now();
</script>

2. 今日から3日間の日付を生成する

Date に標準で用意されているメソッドを使用して構いません。
var dateArray = new Array();
var date = firstDate;
for (var i = 0; i < 3; i++) {
    dateArray[i] = date;
    date.setDate(date.getDate() + 1);
}

3. 最後の日付をサーバ側へ送信する

年月日の値から日付文字列を作ります。
var lastDate = dateArray[2];
var lastDateStr = lastDate.getFullYear() + "-" + (lastDate.getMonth() + 1) + "-" + lastDate.getDate();

注意

ImDate.now() で生成した Date のエポックミリ秒は送信しないでください。

ImDate.now() の返す Date は、ユーザ・タイムゾーンにおける「今日」の年月日時分秒を持っていますが、エポックミリ秒は正しいとは限りません。
理由は、クライアント側で Date を生成しているためです。
Date の持つエポックミリ秒は、クライアント OS のタイムゾーンで計算された値となり、ユーザ・タイムゾーンで計算された値と一致しない可能性があります。

注意

サーバ側でユーザ・タイムゾーンの日時データを生成する場合は、Date ではなく、DateTime を使用してください。
Date はシステム・デフォルトのタイムゾーンで計算するため、ユーザ・タイムゾーンとの時差を考慮して扱う必要があります。
DateTime はタイムゾーンを指定しない限り、ユーザ・タイムゾーンで計算します。
//ユーザ・タイムゾーンにおける1996年9月19日3時47分の日時データ
var dateTime = new DateTime(1996, DateTime.SEPTEMBER, 19, 3, 47, 0);

4. クライアント側から送信された日付文字列から Date を生成する

function init(request) {
    var inputDateStr = request.inputDate; //画面から送信された日付文字列
    var inputDate = DateTimeFormatter.parseToDate('yyyy-MM-dd', inputDateStr);
}
日時文字列がユーザの日付と時刻の入力形式に沿っていない場合、DateTimeFormatter を使用します。
DateTimeFormatter は、直接フォーマットパターンを指定できます。
DateTimeFormatter は、ユーザのタイムゾーンを使って解析を行います。