📣新登場!TiDB Cloud BYOC、TiDB Cloud Filesystem、PostgreSQL-compatible TiDB Cloud Starter がパブリックプレビュー中。このページは自動翻訳されたものです。原文はこちらからご覧ください。

日付と時刻



概要

名前エイリアスストレージサイズ精度最小値最大値形式
DATE4 バイト日0001-01-019999-12-31YYYY-MM-DD
TIMESTAMPDATETIME8 バイトマイクロ秒0001-01-01 00:00:00.0000009999-12-31 23:59:59.999999 UTCYYYY-MM-DD hh:mm:ss[.fraction]、表示にはセッションのタイムゾーンを使用
TIMESTAMP_TZTIMESTAMP WITH TIME ZONE8 バイトマイクロ秒0001-01-01 00:00:00.0000009999-12-31 23:59:59.999999 UTCYYYY-MM-DD hh:mm:ss[.fraction]±hh:mm、UTC 値とオフセットを保存

DATE はカレンダー値のみを保持し、TIMESTAMP は内部的には UTC で保存されますが、現在のセッションのタイムゾーンを通して表示されます。TIMESTAMP_TZ は、監査やレプリケーションのシナリオで必要となる元のオフセットを保持します。

例

DATE

CREATE TABLE events (event_date DATE); INSERT INTO events VALUES ('2024-01-15'), ('2024-12-31'); SELECT * FROM events;

結果:

┌────────────┐ │ event_date │ ├────────────┤ │ 2024-01-15 │ │ 2024-12-31 │ └────────────┘

TIMESTAMP

CREATE TABLE meetings ( meeting_id INT, meeting_time TIMESTAMP ); INSERT INTO meetings VALUES (1, '2024-01-15 14:00:00+08:00'); SETTINGS (timezone = 'UTC') SELECT meeting_id, meeting_time FROM meetings; SETTINGS (timezone = 'America/New_York') SELECT meeting_id, meeting_time FROM meetings;

結果 (timezone = 'UTC'):

┌────────────┬──────────────────────┐ │ meeting_id │ meeting_time │ ├────────────┼──────────────────────┤ │ 1 │ 2024-01-15T06:00:00 │ └────────────┴──────────────────────┘

結果 (timezone = 'America/New_York'):

┌────────────┬──────────────────────┐ │ meeting_id │ meeting_time │ ├────────────┼──────────────────────┤ │ 1 │ 2024-01-15T01:00:00 │ └────────────┴──────────────────────┘

TIMESTAMP_TZ

CREATE TABLE system_logs ( log_id INT, log_time TIMESTAMP_TZ ); INSERT INTO system_logs VALUES (1, '2024-01-15 14:00:00+08:00'), (2, '2024-01-15 06:00:00+00:00'), (3, '2024-01-15 01:00:00-05:00'); SETTINGS (timezone = 'UTC') SELECT log_id, TO_STRING(log_time) AS log_time FROM system_logs; SETTINGS (timezone = 'Asia/Shanghai') SELECT log_id, TO_STRING(log_time) AS log_time FROM system_logs;

結果 (timezone = 'UTC'):

┌────────┬────────────────────────────────────────────┐ │ log_id │ log_time │ ├────────┼────────────────────────────────────────────┤ │ 1 │ 2024-01-15 14:00:00.000000 +0800 │ │ 2 │ 2024-01-15 06:00:00.000000 +0000 │ │ 3 │ 2024-01-15 01:00:00.000000 -0500 │ └────────┴────────────────────────────────────────────┘

結果 (timezone = 'Asia/Shanghai'):

┌────────┬────────────────────────────────────────────┐ │ log_id │ log_time │ ├────────┼────────────────────────────────────────────┤ │ 1 │ 2024-01-15 14:00:00.000000 +0800 │ │ 2 │ 2024-01-15 06:00:00.000000 +0000 │ │ 3 │ 2024-01-15 01:00:00.000000 -0500 │ └────────┴────────────────────────────────────────────┘

オフセットは保存される値の一部であるため、表示は変化しません。

適切な型の選択

  • 時刻を含まないカレンダー値には DATE を使用します。
  • 異なるセッションで同じ時点をそれぞれのローカルタイムゾーンで表示する必要がある場合は、TIMESTAMP を使用します。
  • コンプライアンス対応やデバッグのために入力時のオフセットを保持する必要がある場合は、TIMESTAMP_TZ を使用します。

夏時間調整

enable_dst_hour_fix を有効にすると、夏時間によってその日の一部の時間がスキップされる場合に、TiDB Cloud Lake は存在しない時刻を自動的に次の有効な時刻へ繰り上げます。

SET enable_dst_hour_fix = 1; SETTINGS (timezone = 'America/Toronto') SELECT to_datetime('2024-03-10 02:01:00');

結果:

┌────────────────────────────────────┐ │ to_datetime('2024-03-10 02:01:00') │ ├────────────────────────────────────┤ │ 2024-03-10T03:01:00 │ └────────────────────────────────────┘

存在しない時刻に対してエラーを返すデフォルトの動作に戻したい場合は、SET enable_dst_hour_fix = 0 を使用します。

無効な値の処理

サポート範囲外の日付は、自動的にその最小値に丸められます。

SELECT ADD_DAYS(TO_DATE('9999-12-31'), 1) AS overflow_date, SUBTRACT_MINUTES(TO_DATE('1000-01-01'), 1) AS underflow_timestamp;

結果:

┌───────────────┬──────────────────────────┐ │ overflow_date │ underflow_timestamp │ ├───────────────┼──────────────────────────┤ │ 0001-01-01 │ 0999-12-31T18:41:28 │ └───────────────┴──────────────────────────┘

エラーを返す代わりに、値は表現可能な最小の日付またはタイムスタンプに折り返されます。

日付と時刻の書式設定

TO_DATE や TO_TIMESTAMP などの関数は、明示的な書式文字列を受け付けます。date_format_style と week_start を調整することで、値の解析方法や表示方法を制御できます。

日付フォーマットスタイル

date_format_style を使用すると、2 つのフォーマット語彙を切り替えられます。

  • MySQL(デフォルト)は %Y、%m、%d のような指定子を使用します。
  • Oracle は ANSI スタイルのマスクに合わせて、YYYY、MM、DD のような指定子を使用します。
-- Oracle-style mask SETTINGS (date_format_style = 'Oracle') SELECT to_string('2024-04-05'::DATE, 'YYYY-MM-DD');

結果(Oracle):

┌──────────────────────────────────────┐ │ to_string('2024-04-05'::DATE, 'YYYY-MM-DD') │ ├──────────────────────────────────────┤ │ 2024-04-05 │ └──────────────────────────────────────┘
-- Back to MySQL-style mask SETTINGS (date_format_style = 'MySQL') SELECT to_string('2024-04-05'::DATE, '%Y-%m-%d');

結果(MySQL):

┌──────────────────────────────────────┐ │ to_string('2024-04-05'::DATE, '%Y-%m-%d') │ ├──────────────────────────────────────┤ │ 2024-04-05 │ └──────────────────────────────────────┘

週の開始日の設定

week_start は、WEEK 精度を使用する際に、DATE_TRUNC や TRUNC などの関数で週の開始日をどの曜日にするかを定義します。

SETTINGS (week_start = 0) SELECT DATE_TRUNC(WEEK, to_date('2024-04-05')); -- Sunday SETTINGS (week_start = 1) SELECT DATE_TRUNC(WEEK, to_date('2024-04-05')); -- Monday

結果(week_start = 0):

┌────────────────────────────────┐ │ DATE_TRUNC(WEEK, TO_DATE('2024-04-05')) │ ├────────────────────────────────┤ │ 2024-03-31 │ └────────────────────────────────┘

結果(week_start = 1):

┌────────────────────────────────┐ │ DATE_TRUNC(WEEK, TO_DATE('2024-04-05')) │ ├────────────────────────────────┤ │ 2024-04-01 │ └────────────────────────────────┘

MySQL フォーマット指定子

日付と時刻のフォーマットを処理するために、TiDB Cloud Lake は chrono::format::strftime モジュールを使用します。これは Rust の chrono ライブラリが提供する標準モジュールです。このモジュールにより、日付と時刻のフォーマットを精密に制御できます。以下の内容は https://docs.rs/chrono/latest/chrono/format/strftime/index.html からの抜粋です。

指定子例説明
日付指定子:
%Y2001先発グレゴリオ暦の年を 4 桁でゼロ埋めして表します。chrono は -262144 から 262143 までの年をサポートします。注: 紀元前 1 年より前、または西暦 9999 年より後の年では、先頭に符号(+/-)が必要です。
%C20先発グレゴリオ暦の年を 100 で割った値を 2 桁でゼロ埋めして表します。
%y01先発グレゴリオ暦の年を 100 で割った余りを 2 桁でゼロ埋めして表します。
%m07月番号(01–12)を 2 桁でゼロ埋めして表します。
%bJul省略形の月名です。常に 3 文字です。
%BJuly完全な月名です。解析時には対応する省略形も受け付けます。
%hJul%b と同じです。
%d08日番号(01–31)を 2 桁でゼロ埋めして表します。
%e8%d と同じですが、空白埋めです。%_d と同じです。
%aSun省略形の曜日名です。常に 3 文字です。
%ASunday完全な曜日名です。解析時には対応する省略形も受け付けます。
%w0日曜日 = 0、月曜日 = 1、…、土曜日 = 6。
%u7月曜日 = 1、火曜日 = 2、…、日曜日 = 7。(ISO 8601)
%U28日曜日始まりの週番号(00–53)を 2 桁でゼロ埋めして表します。
%W27%U と同じですが、週 1 はその年の最初の月曜日から始まります。
%G2001%Y と同じですが、ISO 8601 の週日付における年番号を使用します。
%g01%y と同じですが、ISO 8601 の週日付における年番号を使用します。
%V27%U と同じですが、ISO 8601 の週日付における週番号(01–53)を使用します。
%j189年内通算日(001–366)を 3 桁でゼロ埋めして表します。
%D07/08/01月-日-年形式です。%m/%d/%y と同じです。
%x07/08/01ロケールの日付表現です(例: 12/31/99)。
%F2001-07-08年-月-日形式(ISO 8601)です。%Y-%m-%d と同じです。
%v8-Jul-2001日-月-年形式です。%e-%b-%Y と同じです。
時刻指定子:
%H00時番号(00–23)を 2 桁でゼロ埋めして表します。
%k0%H と同じですが、空白埋めです。%_H と同じです。
%I1212 時間制の時番号(01–12)を 2 桁でゼロ埋めして表します。
%l12%I と同じですが、空白埋めです。%_I と同じです。
%Pam12 時間制の am または pm。
%pAM12 時間制の AM または PM。
%M34分番号(00–59)を 2 桁でゼロ埋めして表します。
%S60秒番号(00–60)を 2 桁でゼロ埋めして表します。
%f026490000直前の整数秒からの小数秒(ナノ秒単位)です。TiDB Cloud Lake では、この指定子を使う代わりに、Integer 文字列をまず Integer に変換することを推奨しています。例については Integer から Timestamp への変換 を参照してください。
%.f.026490.%f に似ていますが、左寄せです。これらはすべて先頭のドットを消費します。
%.3f.026.%f に似ていますが、左寄せで、長さを 3 に固定します。
%.6f.026490.%f に似ていますが、左寄せで、長さを 6 に固定します。
%.9f.026490000.%f に似ていますが、左寄せで、長さを 9 に固定します。
%3f026%.3f に似ていますが、先頭のドットは付きません。
%6f026490%.6f に似ていますが、先頭のドットは付きません。
%9f026490000%.9f に似ていますが、先頭のドットは付きません。
%R00:34時-分形式です。%H:%M と同じです。
%T00:34:60時-分-秒形式です。%H:%M:%S と同じです。
%X00:34:60ロケールの時刻表現です(例: 23:13:48)。
%r12:34:60 AM12 時間制の時-分-秒形式です。%I:%M:%S %p と同じです。
タイムゾーン指定子:
%ZACSTローカルタイムゾーン名です。解析時には空白以外のすべての文字をスキップします。
%z+0930ローカル時刻から UTC へのオフセットです(UTC は +0000)。
%:z+09:30%z と同じですが、コロン付きです。
%::z+09:30:00秒を含む、ローカル時刻から UTC へのオフセットです。
%:::z+09分を含まない、ローカル時刻から UTC へのオフセットです。
%#z+09解析専用: %z と同じですが、分が省略されていても存在していても受け付けます。
日付と時刻の指定子:
%cSun Jul 8 00:34:60 2001ロケールの日付と時刻です(例: Thu Mar 3 23:05:25 2005)。
%+2001-07-08T00:34:60.026490+09:30ISO 8601 / RFC 3339 の日付と時刻形式です。
%s994518299UNIX タイムスタンプです。1970-01-01 00:00 UTC からの秒数を表します。TiDB Cloud Lake では、この指定子を使う代わりに、Integer 文字列をまず Integer に変換することを推奨しています。例については Integer から Timestamp への変換 を参照してください。
特殊指定子:
%tリテラルのタブ(\t)。
%nリテラルの改行(\n)。
%%リテラルのパーセント記号です。

数値指定子 %? のデフォルトの埋め込み動作は上書きできます。これは他の指定子では許可されておらず、BAD_FORMAT エラーになります。

修飾子説明
%-?空白やゼロを含むすべての埋め込みを抑制します。(例: %j = 012、%-j = 12)
%_?埋め込みに空白を使用します。(例: %j = 012、%_j = 12)
%0?埋め込みにゼロを使用します。(例: %e = 9、%0e = 09)
  • %C, %y: これは切り捨て除算です。そのため、紀元前 100 年(年番号 -99)はそれぞれ -1 と 99 と表示されます。

  • %U: 週 1 はその年の最初の日曜日から始まります。最初の日曜日より前の日は週 0 になる可能性があります。

  • %G, %g, %V: 週 1 は、その年に少なくとも 4 日含まれる最初の週です。週 0 は存在しないため、これらは %G または %g と一緒に使用する必要があります。

  • %S: うるう秒を考慮するため、60 になることがあります。

  • %f, %.f, %.3f, %.6f, %.9f, %3f, %6f, %9f:

    デフォルトの %f は右寄せで、glibc などとの互換性のため常に 9 桁にゼロ埋めされます。そのため、常に直前の整数秒からのナノ秒数を表します。たとえば、直前の秒から 7ms 後は 007000000 と表示され、7000000 を解析しても同じ結果になります。

    バリアント %.f は左寄せで、精度に応じて 0、3、6、9 桁の小数部を出力します。たとえば、直前の秒から 70ms 後を %.f で表すと .070 と表示されます(注: .07 ではありません)。また、.07 や .070000 などを解析しても同じ結果になります。小数部が 0 の場合、または次の文字が . でない場合は、何も出力または読み取りしないことがあります。

    バリアント %.3f、%.6f、%.9f は左寄せで、f の前の数字に応じて 3、6、9 桁の小数部を出力します。たとえば、直前の秒から 70ms 後を %.3f で表すと .070 と表示されます(注: .07 ではありません)。また、.07 や .070000 などを解析しても同じ結果になります。小数部が 0 の場合、または次の文字が . でない場合は何も読み取らないことがありますが、出力時には指定された長さで表示されます。

    バリアント %3f、%6f、%9f は左寄せで、f の前の数字に応じて 3、6、9 桁の小数部を出力しますが、先頭のドットは付きません。たとえば、直前の秒から 70ms 後を %3f で表すと 070 と表示されます(注: 07 ではありません)。また、07 や 070000 などを解析しても同じ結果になります。小数部が 0 の場合は、何も読み取らないことがあります。

  • %Z: 解析されたデータからオフセットは設定されず、検証もされません。タイムゾーンは完全に無視されます。これは glibc の strptime におけるこのフォーマットコードの扱いに似ています。

    省略形からオフセットへ確実に変換できません。たとえば、CDT は Central Daylight Time(北米)を意味する場合もあれば、China Daylight Time を意味する場合もあります。

  • %+: %Y-%m-%dT%H:%M:%S%.f%:z と同じです。つまり、秒の小数部は 0、3、6、9 桁で、タイムゾーンオフセットにはコロンが入ります。

    この形式では、%:z の代わりに Z または UTC を使用することもサポートしています。これらは +00:00 と等価です。

    なお、T、Z、UTC はすべて大文字小文字を区別せずに解析されます。

    一般的な strftime 実装では、この指定子に対して異なる形式(かつロケール依存)を使用します。Chrono における %+ の形式ははるかに安定していますが、出力を厳密に制御したい場合は、この指定子の使用を避けるのが最善です。

  • %s: これは埋め込みされず、負の値になることがあります。Chrono の目的上、これはうるう秒以外の秒のみを考慮するため、ISO C strftime の動作とはわずかに異なります。

Oracle フォーマット指定子

date_format_style が 'Oracle' に設定されている場合、以下のフォーマット指定子がサポートされます。

Oracle 形式説明出力例('2024-04-05 14:30:45.123456' の場合)
YYYY4 桁の年2024
YY2 桁の年24
MMMM月の完全名April
MON月の省略名Apr
MM月番号 (01-12)04
DD日 (01-31)05
DY曜日の省略名Fri
HH2424 時間形式の時 (00-23)14
HH1212 時間形式の時 (01-12)02
AM/PM午前/午後インジケーターPM
MI分 (00-59)30
SS秒 (00-59)45
FF小数秒123456
UUUUISO 週番号ベースの年2024
TZH:TZMコロン付きのタイムゾーン時・分+08:00
TZHタイムゾーンの時+08

同じデータを使用した MySQL と Oracle のフォーマットスタイルの比較例を以下に示します。

-- MySQL format style (default) SELECT to_string('2022-12-25'::DATE, '%m/%d/%Y'); ┌────────────────────────────────┐ │ to_string('2022-12-25', '%m/%d/%Y') │ ├────────────────────────────────┤ │ 12/25/2022 │ └────────────────────────────────┘ -- Oracle format style (same data as MySQL example above) SETTINGS (date_format_style = 'Oracle') SELECT to_string('2022-12-25'::DATE, 'MM/DD/YYYY'); ┌────────────────────────────────┐ │ to_string('2022-12-25', 'MM/DD/YYYY') │ ├────────────────────────────────┤ │ 12/25/2022 │ └────────────────────────────────┘

このページは役に立ちましたか?