DATETIME
、DATE
、そして
TIMESTAMP
型は関連しています。この節では、それらがどのように似ているのか、そしてどのような点で異なっているのかなどの、特徴について説明しています。
DATETIME
型は、日付と時刻の両方の情報を含む値が必要なときに利用します。MySQL
では、DATETIME
型の値の取り出しと表示は
'YYYY-MM-DD HH:MM:SS'
形式で行われます。サポートしている範囲は
'1000-01-01 00:00:00'
から
'9999-12-31 23:59:59'
です。
DATE
型は時刻の部分は無く、日付の値だけが必要なときに利用します。MySQL
では、DATE
型の値の取り出しと表示は
'YYYY-MM-DD'
形式で行われます。サポートしている範囲は
'1000-01-01'
から
'9999-12-31'
です。
DATETIME
と
DATE
範囲の説明では、「サポートする」というのは、以前の値が有効であったとしても、その保障はないという意味になります。
TIMESTAMP
データ型の範囲は、'1970-01-01
00:00:01'
UTC から
'2038-01-19 03:14:07'
UTC
です。このデータ型には、MySQL
のバージョンと、サーバーが動作している SQL
モードに応じてさまざまな特性があります。これらの特性については、この節のあとの方で説明します。
DATETIME
、DATE
、そして
TIMESTAMP
値を、フォーマットの共通セットを利用して、指定することができます。
'YYYY-MM-DD HH:MM:SS'
または 'YY-MM-DD
HH:MM:SS'
形式の文字列として。「柔軟な」
構文が許可されています。句読点文字が、日付部分と時刻部分の区切り文字として利用されることがあります。たとえば、'98-12-31
11:30:45'
、'98.12.31
11+30+45'
、'98/12/31
11*30*45'
、および
'98@12@31 11^30^45'
はどれも同じです。
YYYY-MM-DD
または
YY-MM-DD
形式の文字列として。「柔軟な」
構文がここでも許可されています。たとえば、'98-12-31'
、'98.12.31'
、'98/12/31'
、および
'98@12@31'
はどれも同じです。
'YYYYMMDDHHMMSS'
または 'YYMMDDHHMMSS'
形式の、区切り文字がない文字列
(日付として適切なもの)
として。たとえば、'20070523091528'
と '070523091528'
は
'2007-05-23 09:15:28'
として解釈されますが、'071122129015'
は正しくないため (分の部分が不適切)
、'0000-00-00 00:00:00'
になります。
'YYYYMMDD'
または
'YYMMDD'
形式の、区切り文字がない文字列
(日付として適切なもの)
として。たとえば、'20070523'
と '070523'
は
'2007-05-23'
として解釈されますが、'071332'
は正しくないため
(月と日の部分が不適切)、'0000-00-00'
になります。
YYYYMMDDHHMMSS
または
YYMMDDHHMMSS
形式の数値 (日付として適切なもの)
として。たとえば、19830905132800
と 830905132800
は
'1983-09-05 13:28:00'
として解釈されます。
YYYYMMDD
または
YYMMDD
形式の数値
(日付として適切なもの)
として。たとえば、19830905
と 830905
は
'1983-09-05'
として解釈されます。
DATETIME
、DATE
、または
TIMESTAMP
コンテキストで許容される値を返す、NOW()
や
CURRENT_DATE
などの関数の結果として。
マイクロ秒の部分は、リテラル値や、一部の時間を表す関数に渡される引数またはそのような関数から返される戻り値など、一部のコンテキストの時間値で許容されます。マイクロ秒は、値の末尾の
.uuuuuu
部分として指定されます。次に例を示します。
mysql> SELECT MICROSECOND('2010-12-10 14:12:09.019473');
+-------------------------------------------+
| MICROSECOND('2010-12-10 14:12:09.019473') |
+-------------------------------------------+
| 19473 |
+-------------------------------------------+
ただし、マイクロ秒を時間を表すデータ型のカラムに格納することはできません。マイクロ秒の部分はすべて破棄されます。
TIME
値または
DATETIME
値を数値形式に変換すると
(+0
を追加するなどして)、.000000
というマイクロ秒の部分を持つ double
値が生成されます。
mysql>SELECT CURTIME(), CURTIME()+0;
+-----------+---------------+ | CURTIME() | CURTIME()+0 | +-----------+---------------+ | 10:41:36 | 104136.000000 | +-----------+---------------+ mysql>SELECT NOW(), NOW()+0;
+---------------------+-----------------------+ | NOW() | NOW()+0 | +---------------------+-----------------------+ | 2007-11-30 10:41:47 | 20071130104147.000000 | +---------------------+-----------------------+
不正な
DATETIME
、DATE
、または
TIMESTAMP
値は、適切な型の「ゼロ」値
('0000-00-00 00:00:00'
か
'0000-00-00'
)
に変換されます。
日にち部分の区切り文字を含む文字列として指定された値には、月か日にちの値に
10
以下の 2
桁の値を指定する必要はありません。'1979-6-9'
は '1979-06-09'
と同じです。同じように、時刻部分の区切り文字を含む文字列として指定された値には、時、分、または秒の値に
10
以下の 2
桁の値を指定する必要はありません。'1979-10-30
1:2:3'
は '1979-10-30
01:02:03'
と同じです。
数値として指定する値は、6、8、12、14
のいずれかの桁数にするようにしてください。数値を
8 桁または 14
桁の長さにすると、YYYYMMDD
または YYYYMMDDHHMMSS
形式であり、最初の 4
桁が年であると想定されます。数値を 6
桁または 12
桁の長さにすると、YYMMDD
または YYMMDDHHMMSS
形式であり、最初の 2
桁が年であると想定されます。これらの長さではない数字は後ろがゼロで詰められ、これらの中の一番近い桁数と仮定して判断されます。
区切り文字のない文字列として指定した値は、その文字列の長さに基づいて解釈されます。もしその文字列が
8 か 14 文字なら、年は最初の 4
文字で表されていると判断されます。そうでなければ、年は最初の
2
文字で表されていると判断されます。文字列は、左から右に順番に、年、月、日、時、分、そして秒として、その文字列に存在するかぎりの情報が読み取られます。これは、6
文字以下の文字列は利用してはいけないということを意味します。たとえば、1999
年 3 月を表す数値として
'9903'
を指定すると、MySQL
では日付値として「ゼロ」がテーブルに挿入されます。年と月の値は
99
と
03
ですが、日付の部分がまったくないのでこのようなことが起こります。ですので、この値は不当な値ということになります。しかし、欠落している月や日付の部分をゼロの値を使って明確に指定することができます。たとえば、'990300'
と指定することで、'1999-03-00'
という日付値を挿入できます。
1 つの日付型の値を異なる日付型のオブジェクトに割り当てることがある程度可能です。しかし、値の変更や情報の損失などが起こる可能性があります。
DATE
型の値を
DATETIME
または
TIMESTAMP
型のオブジェクトに割り当てた場合、DATE
値に時刻情報が含まれていないため、結果として得られる値の時刻部分は
'00:00:00'
に設定されます。
もし
DATETIME
か
TIMESTAMP
値を DATE
オブジェクトに割り当てると、DATE
値は時刻の情報を格納しないので、その結果の時刻の部分は削除されます。
DATETIME
、DATE
、そして
TIMESTAMP
値は、すべて同じフォーマットの組み合わせを利用して指定することができますが、それらの型はすべて同じ範囲の値を持つわけではないことを覚えておいてください。たとえば、TIMESTAMP
型の値は、1970
UTC
よりも前にしたり、'2038-01-19
03:14:07'
UTC
よりもあとにすることはできません。つまり、'1968-01-01'
のような日付は、DATETIME
型や DATE
型の値としては有効ですが、TIMESTAMP
型の値としては有効ではないため、0
に変換されます。
日付値を指定する際には、次の問題点に注意してください。
文字列として指定された値に許容される柔軟なフォーマットはまぎらわしいことがあります。たとえば、'10:11:12'
などの値は、「:
」区切り文字のせいで時刻値のように見えますが、日付のコンテキストで使用した場合は、年
'2010-11-12'
として解釈されます。値
'10:45:15'
は、'45'
が正しい月を表す値ではないため、'0000-00-00'
に変換されます。
サーバーは、それぞれが 1 から 12、または 1
から 31
であることはもちろん、月と日の値が正しい値であることを要求します。厳密モードが無効になっていると、'2004-04-31'
のような無効な日付は
'0000-00-00'
に変換され、警告メッセージが表示されます。厳密モードが有効なときは、無効な日付はエラーを発生させます。そのような日付を許容するには、ALLOW_INVALID_DATES
を有効にしてください。詳細については、Server SQL Modes
を参照してください。
MySQL
は、日付か月のカラムにゼロを含むタイムスタンプ値や、有効でない日付値は許容しません。この規則の唯一の例外は、特殊な値
'0000-00-00 00:00:00'
です。
2 桁の年を含む日付の値は、世紀が不明なためあいまいです。MySQL は 2 桁の年の値を次の規則に従って解釈します。
00-69
の範囲の年の値は
2000-2069
に変換されます。
70-99
の範囲の年の値は
1970-1999
に変換されます。