第4章 関数

日付と時刻関数

日付と時刻関数

日付と時刻関数には、使い勝手の良い関数が多数あります。現在の日付や時刻、2つの期間の差を問い合わせたり、日付の演算や日付のフォーマットを処理したりすることが可能です。また、WHERE句で利用することもできるので、検索条件で利用することもできます。

コンテキストとは

コンテキストとは、たとえば数値が求められている場合は数値コンテキスト、複数の値が求められているときはリストコンテキストというように、様々な値を扱うときの概念のようなものです。

CURDATE() / CURRENT_DATE() 
現在の日付を返す

CURRENT_DATE()は、現在の日付を返します。CURRENT_DATE()はコンテキストによって返却値が変わる関数で、数値コンテキストの場合はYYYYMMDD形式、それ以外はYYYY-MM-DD形式で返します。CURDATE()は、CURRENT_DATE()の別名です。

現在の時刻はCURRENT_TIME()、日付と時刻の両方はCURRENT_TIMESTAMP()で取得できます。

現在の日付を取得します。

SELECT CURDATE();
-> 2007-10-29

数値コンテキストの場合、返却値はYYYYMMDD形式です。

SELECT CURDATE() + 0;
-> 20071029

CURTIME() / CURRENT_TIME()
現在の時刻を返す

CURRENT_TIME()は、現在の時刻を返します。CURRENT_TIME()はコンテキストによって返却値が変わる関数で、数値コンテキストの場合はHHMMSS形式、それ以外はHH:MM:SS形式で返します。CURTIME()は、CURRENT_TIME()の別名です。

現在の日付はCURRENT_DATE()、日付と時刻の両方はCURRENT_TIMESTAMP()で取得できます。

現在の時刻を取得します。

SELECT CURRENT_TIME();
-> 14:39:09

数値コンテキストの場合、返却値はYYYYMMDD形式です。

SELECT CURTIME() + 0;
-> 143909

CURRENT_TIMESTAMP() / NOW() / SYSDATE()
現在の日時を返す

CURRENT_TIMESTAMP()は、現在の日時を返します。CURRENT_TIMESTAMP()はコンテキストによって返却値が変わる関数で、数値コンテキストの場合はYYYYMMDDHHMMSS形式、それ以外は YYYY-MM-DD HH:MM:SS形式で返します。NOW()、SYSDATE()はCURRENT_TIMESTAMP()の別名です。

現在の日付はCURRENT_DATE()、現在の時刻はCURRENT_TIME()で取得できます。

現在の時刻を取得します。

SELECT CURRENT_TIMESTAMP();
-> 2007-10-29 12:33:16 

数値コンテキストの場合、返却値はYYYYMMDD形式です。

SELECT CURRENT_TIMESTAMP() + 0;
-> 20071029123343

DATE_ADD(DATE, interval EXPR TYPE) / ADDDATE(DATE, interval EXPR TYPE)

DATE_SUB(DATE, interval EXPR TYPE) / SUBDATE(DATE, interval EXPR TYPE)
日付の演算

DATE_ADD()、DATE_SUB()はMySQL独自の関数です。

DATE_ADD()、DATE_SUB()は日付の演算を行います。ADDDATE()はDATE_ADD()、DATE_SUB()はSUBDATE()の別名です。+ と - をDATE_ADD()、DATE_SUB()の代わりに使用することもできます。

引数DATEにはDATETIME値またはDATE値で開始日を指定します。引数EXPRは、開始日に対して加算または減算する期間を表す値です。EXPRの前にマイナス(-)をつけて、負の期間を指定することもできます。TYPEは式をどのように解釈するかを指定します。

以下の表に、引数TYPEと引数EXPRの関連を示します。

日付指定要素一覧
日付要素 TYPE EXPR
SECOND SS
MINUTE MM
HOUR HH
DAY DD
MONTH MM
YEAR YYYY
分秒 MINUTE_SECOND "MM:SS"
時分 HOUR_MINUTE "HH:MM"
日時 DAY_HOUR "DD HH"
年月 YEAR_MONTH "YYYY-MM"
時分秒 HOUR_SECOND "HH:MM:SS"
日時分 DAY_MINUTE "DD HH:MM"
日時分秒 DAY_SECOND "DD HH:MM:SS"

引数DATEがDATE値で、YEAR、MONTH、DAYの部分のみを含む計算をする場合は、DATE値が返されます。それ以外はDATETIME値が返されます。

SELECT "2007-12-31 23:59:59" + INTERVAL
1 SECOND;
-> 2008-01-01 00:00:00

SELECT INTERVAL 1 DAY + "2007-12-31";
-> 2008-01-01

SELECT "2008-01-01" - INTERVAL 1 SECOND;
-> 2007-12-31 23:59:59

SELECT DATE_ADD("2007-12-31 23:59:59", INTERVAL 1
SECOND);
-> 2008-01-01 00:00:00

SELECT DATE_ADD("2007-12-31 23:59:59", INTERVAL 1 DAY);
-> 2008-01-01 23:59:59

SELECT DATE_ADD("2007-12-31 23:59:59", INTERVAL "1:1"
MINUTE_SECOND);
-> 2008-01-01 00:01:00

SELECT DATE_SUB("2007-01-01 00:00:00", INTERVAL "1
1:1:1" DAY_SECOND);
-> 2006-12-30 22:58:59

SELECT DATE_ADD("2008-01-01 00:00:00", INTERVAL "-1 10"
DAY_HOUR);
-> 2007-12-30 14:00:00

SELECT DATE_SUB("2008-01-02", INTERVAL 31 DAY);
-> 2007-12-02

もし INTERVAL値が短すぎる場合、INTERVAL値の先頭部分が指定されていないと仮定して処理されます。

UPDATE構文に使っても便利です。

UPDATE テーブル名 SET add_dtime=DATE_ADD(日付フィールド名, INTERVAL id SECOND);

上記の例では、指定したテーブルの日付フィールド名の値に、idというフィールドの値を加算しています。CSVからデータをインポートした際など、登録日が秒数まで同じになることがありますが、上記方法ですべての登録日を別の値にできます。

DATE_FORMAT(DATE, FORMAT) 
日付のフォーマット

DATE_FORMAT()は、引数DATEで指定した日付の値を、引数FORMATの指示通りに整形して返します。

次の指示子が引数FORMATに使用できます。

DATE_FORMATの書式指示子一覧
書式指示子 解説
%Y 4桁で暦年を表示
%y 2桁で暦年を表示
%c 月(1~12)
%m 月(01~12)
%b 月(Jan、Feb、Mar ・・・)。
%M 月(January、February ・・・)
%j 年始からの日数(001~366)
%e 日(0~31)
%d 日(00~31)
%D 序数つきの日付(1st、2nd・・・)。
%U 年間の通算週(0~53)で、週の始まりが日曜日
%u 年間の通算週(0~53)で、週の始まりが月曜日
%V 年間の通算週(1~53)で、週の始まりが日曜日
%v 年間の通算週(1~53)で、週の始まりが月曜日
%w 曜日(0~6) 0 が日曜日
%a 曜日(Sun、Mon・・・)。
%W 曜日(Sunday、Monday・・・)。
%p AM または PM
%k 時(0~23)
%H 時(00~23)
%h / %I 時(01~12)
%i 分(00~59)
%S 秒(00~59)
%s 秒(0~59)
%r 12時間単位の総時間(hh:mm:ss AM/PM)
%T 24時間単位の総時間(hh:mm:ss)
%l 12時間単位の時刻
%% パーセント( % )のエスケープ
SELECT DATE_FORMAT( '2007-5-30 17:30:00', '%Y/%m/%d %H:%i:%S' );
-> 2007/05/30 17:30:00

SELECT DATE_FORMAT( '2007-5-30
17:30:00', '%W %M %Y' );
-> Wednesday May 2007

DAYNAME(DATE)
曜日を文字列で返す

DAYNAME()は、引数DATEで指定した日の曜日名を返します。

曜日を数値で取得するには、DAYOFWEEK()、もしくはWEEKDAY()を使います。

SELECT DAYNAME( '2007-05-30' );
-> Wednesday

DAYOFMONTH(DATE)
月の何日目かを返す

DAYOFMONTH()は、引数DATEで指定した日がその月の何日目であるかを返します。値の範囲は 1 から 31 です。

年を取得するにはYEAR()を、月を取得するにはMONTH()を使います。

SELECT DAYOFMONTH( '2007-05-30' );
-> 30

DAYOFWEEK(DATE) 
週の何日目かを返す

DAYOFWEEK()は、引数DATEで指定した日がその週の何日目であるかを返します。返却値は、1~7までの数値で、1が日曜日になります(1 = 日曜日、2 = 月曜日、 ... 7 = 土曜日)。

曜日を文字列として取得するにはDAYNAME()を使います。

SELECT DAYOFWEEK( '2007-05-30' );
-> 4

DAYOFYEAR(DATE)
年の何日目かを求める

DAYOFYEAR()は、引数DATEで指定した日がその年の何日目であるかを返します。返却値は、1~366までの数値です。

年を取得するには#YEARを、月を取得するにはMONTH()を、日を取得するにはDAY()、もしくはDAYOFMONTH()を使います。

SELECT DAYOFYEAR( '2007-05-30' );
-> 150

EXTRACT(TYPE from DATE)
日付値から指定した日付要素を取得

EXTRACT()は、日付値から指定した日付要素の値を返します。引数TYPEには、必要な日付要素を指定します。

日付要素一覧
日付要素 TYPE
SECOND
MINUTE
HOUR
DAY
MONTH
YEAR
分秒 MINUTE_SECOND
時分 HOUR_MINUTE
日時 DAY_HOUR
年月 YEAR_MONTH
時分秒 HOUR_SECOND
日時分 DAY_MINUTE
日時分秒 DAY_SECOND

EXTRACTの使い方は下記のとおりです。

SELECT EXTRACT( YEAR FROM '2007-05-30' );
-> 2007

SELECT EXTRACT( YEAR_MONTH FROM '2007-05-30' );
-> 200705

SELECT EXTRACT( DAY_MINUTE FROM '2007-05-30
12:00:00' ); 
-> 301200

引数DATEにCURRENT_TIMESTAMP()といった関数を指定することもできます。

SELECT EXTRACT( YEAR FROM CURRENT_TIMESTAMP );
-> 2007 

FROM_DAYS(N)
0年からの日数を日付に変換する

FROM_DAYS()は、紀元0年からの日数Nを日付にして返します。グレゴリオ暦の登場(1582年)以前の値は考慮されていません。

SELECT FROM_DAYS( 729669 );
-> '1997-10-07'

FROM_UNIXTIME(unix_timestamp)
グリニッジ標準時からの日数を返す

FROM_UNIXTIME()は、引数UNIX_TIMESTAMPで指定された値(グリニッジ標準時の1970年1月1日から何秒たったかを示す秒数)に対応する日付を返します。FROM_UNIXTIME()はコンテキストによって返却値が変わる関数で、数値コンテキストの場合はYYYYMMDDHHMMSS形式、それ以外はYYYY-MM-DD
HH:MM:SS形式で返します。

SELECT FROM_UNIXTIME( 875996580 );
-> 1997-10-05 05:23:00

数値コンテキストの場合、返却値はYYYYMMDD形式です。

SELECT FROM_UNIXTIME( 875996580 ) + 0;
-> 19971005052300
FROM_UNIXTIME(UNIX_TIMESTAMP, FORMAT) 
UNIXのタイムスタンプを返す

FROM_UNIXTIME()に引数FORMATを指定すると、引数UNIX_TIMESTAMPをそのフォーマットに従って整形して返します。

SELECT FROM_UNIXTIME( UNIX_TIMESTAMP(),'%Y
%D %M %h:%i:%s %x' );
-> 2007 29th October 02:47:16 2007

HOUR(X)
時間を返す

HOUR()は、引数Xの時にあたる値を返します。値の範囲は 0 から 23 です。

分を取得するにはMINUTE()、秒を取得するにはSECOND()を使います。

SELECT HOUR( '10:05:03' );
-> 10

MINUTE(X)
分を返す

MINUTEは、引数Xの分にあたる値を返します。値の範囲は 0 から 59 です。

時間を取得するにはHOUR()、秒を取得するにはSECOND()を使います。

SELECT MINUTE( '07-05-30 17:30:00' );
-> 30

MONTH(X)
月を返す

MONTH()は、引数Xの月にあたる値を返します。値の範囲は 1 から 12 までです。

年を取得するにはYEAR()、日を取得するにはDAYOFMONTH()を使います。

SELECT MONTH( '2007-05-30' );
-> 5

MONTHNAME(X)
月名を文字列で返す

MONTHNAME()は、引数Xの月の名前を返します。

年を取得するにはYEAR()、日を取得するにはDAYOFMONTH()を使います。

SELECT MONTHNAME( '2007-05-30' );
-> May

PERIOD_ADD(P, N)
Nヶ月をYYMMに加える

PERIOD_ADD()は、引数P(値はYYMM形式、またはYYYYMM形式)で指定した日付に、引数Nで指定した月を加算し、YYYYMM形式で返します。 引数Pは日付値ではありません。

SELECT PERIOD_ADD( 0710, 1 );
-> 200711

PERIOD_DIFF(P1, P2)
2つの期間の差を月数で返す

PERIOD_DIFF()は、引数P1で指定した日付に、引数P2で指定した日付との差を返します。引数P1と引数P2の値は、YYMM形式、またはYYYYMM形式です。引数P1と引数P2は日付値ではありません。

SELECT PERIOD_DIFF( 0710, 200801 );
-> -3

QUARTER(X)
第何四半期か返す

QUARTER()は、引数Xが属する四半期を表す数を返します。四半期は、1月~3月までが第1四半期、4月~6月が第2四半期、7月~9月が第3四半期、10月~12月が第4四半期です。

年を取得するにはYEAR()、つきを取得するにはMONTH()を、日を取得するにはDAYOFMONTH()を使います。

SELECT QUARTER( '07-10-01' );
-> 4

SECOND(TIME)
秒を返す

SECOND()は、引数TIMEの秒を返します。値の範囲は 0 から 59 です。

時間を取得するにはHOUR()、分を取得するにはMINUTE()を使います。

SELECT SECOND( '10:05:03' );
-> 3

SEC_TO_TIME(SECONDS)
秒数を時:分:秒形式で返す

SEC_TO_TIME()は、引数SECONDSを時、分、秒に変換します。SEC_TO_TIME()はコンテキストによって返却値が変わる関数で、数値コンテキストの場合はHHMMSS形式、それ以外はHH:MM:SS形式で返します。

SELECT SEC_TO_TIME( 2378 );
-> 00:39:38

数値コンテキストの場合、返却値はYYYYMMDD形式です。

SELECT SEC_TO_TIME( 2378 )+0;
-> 003938

TIME_FORMAT(TIME, FORMAT) 
時刻の整形

TIME_FORMAT()は、DATE_FORMAT()のように使用できますが、引数FORMATオプションは時、分、秒だけです。他のオプションを使った場合は、NULL、もしくは 0 を生成します。 

TIME_TO_SEC(TIME)
時:分:秒を秒数で返す

TIME_TO_SEC()は、引数TIMEで指定した時間を秒に変換して返します。

SELECT TIME_TO_SEC( '17:30:00' );
-> 63000

TO_DAYS(DATE)
日付を0年からの日数に変換

TO_DAYS()は、指定した日付を紀元0年からの日数にして返します。グレゴリオ暦の登場(1582年)以前の値は考慮されていません。

SELECT TO_DAYS( 950501 );
-> 728779

SELECT TO_DAYS( '2007-05-30' );
-> 733191

UNIX_TIMESTAMP() 

UNIX_TIMESTAMP(DATE) 
UNIXのタイムスタンプを返す

UNIX_TIMESTAMP()は、引数なしで呼び出された場合は、UNIX のタイムスタンプ(GMT '1970-01-01
00:00:00' からの秒数)を返します。引数DATEはローカル時刻でのDATE文字列、DATETIME文字列、またはYYMMDD形式、YYYYMMDD形式の数値です。 

SELECT UNIX_TIMESTAMP();
-> 1193648650

SELECT UNIX_TIMESTAMP( '2007-05-30 17:30:00' );
-> 1180513800
TIMESTAMPデータ型は現在の時刻を格納するために使用され、32ビットマシンでは1970(年)0101000000 から 2030(年)0101000000までの値(符号付きの値)をサポートします。このように、TIMESTAMPデータ型は扱える範囲が決まっています。
DATE、DATETIEMは9999年までの日付に対応しています。

WEEK(DATE, [FIRST])
年の第何週か返す

WEEK()は、引数が1つの場合は、その日付が年の何週目であるかを示す 0 から 53 までの値を返します。引数が2つの場合は、2番目の引数で、週の始まりを日曜(0)とするか月曜(1)とするかを指定できます。

年間のデータを週ごとに集計するといったようとに利用することができます。曜日を取得するにはDAYOFWEEK()を使います。

SELECT WEEK( '2007-05-30' );
-> 21

引数FIRSTに1を指定して、週の始まりを月曜日とした場合は下記のとおりです。

SELECT WEEK( '2007-05-30', 1 );
-> 22

WEEKDAY(X)
曜日を数字で返す

WEEKDAY()は、引数Xで指定した日付の曜日索引を返します。(0 = 月曜日, ... 6 = 日曜日)。

SELECT WEEKDAY( '2007-05-30 17:30:00' );
-> 2

SELECT WEEKDAY( '2007-05-30' );
-> 2

YEAR(DTE)
年を返す

YEAR()は、引数Xで指定した日付の年にあたる値を返します。値の範囲は 1000 から 9999 です。

月を取得するにはMONTH()を、日を取得するにはDAYOFMONTH()を使います。

SELECT YEAR( '07-05-30' );
-> 2007

YEARWEEK(DATE)
YEARWEEK(DATE, FIRST)
年と週を返す

YEARWEEK()は、引数DATEの年と週に当たる値を返します。第2引数はWEEK()の第2引数とまったく同じように働きます。注意: 年の最初と最後の週では、年がDATE引数内の年とは異なることがあります。

SELECT YEARWEEK( '2007-05-30' );
-> 200721

関連記事