引自:https://blog.csdn.net/yeshang_lady/article/details/102836308
1.日期類數據類型
| 類型 | ZERO值 | 有效值 | 其他 |
|---|---|---|---|
| DATE | '0000-00-00' | ’1000-01-01’~‘9999-12-31’ | 允許使用字符串或數字向date類型的列賦值 |
| TIME | '00:00:00' | '-838:59:59'~'838:59:59' | 即可以表示時間(小於24)或者表示兩個時間點之間的時間間隔 |
| DATETIME | '0000-00-00 00:00:00' | '1000-01-01 00:00:00'~‘9999-12-31 00:00:00’ | 占8個字節。與時區無關。可以使用now()對該字段進行填充。 |
| TIMESTAMP | '0000-00-00 00:00:00' | '1970-01-01 00:00:00' UTC~‘2038-01-19 03:14:07' UTC | 占4個字節。存儲時對當前的時區進行轉化,檢索時再轉化為默認時區。可以使用current_timestramp()進行填充。 |
| YEAR | 0000 | 4位數字:1901-2155 2位:00-99(1970-2069) |
2. 日期類函數
2.1 獲取系統當前時間
MySQL中可以獲取系統當前時間的函數有很多,按照這個這些函數返回值類型的不同,可以分為三類:返回TIMESTAMP、返回DATE類型,返回TIME類型。
| 函數 | 說明 |
|---|---|
| NOW() | 返回函數開始執行的日期和時間 |
| CURDATE() | 返回當前日期 |
| CURTIME() | 返回當前時間 |
| CURRENT_DATE()\CURRENT_DATE | 與CURDATE()相同 |
| CURRENT_TIEMSTAMP()\CURRENT_TIMESTAMP | 與NOW()相同 |
| CURRENT_TIME()\CURRENT_TIME | 與CURTIME()相同 |
| LOCALTIME()\LOCALTIME | 與NOW()相同 |
| LOCALTIMESTAMP()\LOCALTIMESTAMP | 與NOW()相同 |
-
SELECT
-
'TIMESTAMP' AS r_type, NOW( ) AS r1,CURRENT_TIMESTAMP( ) AS r2,CURRENT_TIMESTAMP AS r3
運行結果如下:

-
SELECT
-
'DATE' AS r_type,CURDATE( ) AS r1,CURRENT_DATE ( ) AS r2,CURRENT_DATE AS r3
運行結果如下:
![]()
-
SELECT
-
'TIME' AS r_type,CURTIME( ) AS r1,CURRENT_TIME ( ) AS r2,CURRENT_TIME AS r3
運行結果如下:

-
SELECT
-
'TIMESTAMP' AS r_type, LOCALTIME() AS R1,LOCALTIME AS R2,LOCALTIMESTAMP() AS R3,LOCALTIMESTAMP AS R4
運行結果如下:

2.2 時區相關
| 函數 | 說明 |
|---|---|
| UTC_DATE() | 返回UTC時區的日期 |
| UTC_TIME() | 返回UTC時區的時間 |
| UTC_TIMESTAMP() | 返回UTC時區的日期和時間 |
| CONVERT_TZ() | 從一個時區轉到另一個時區 |
SELECT UTC_DATE(),UTC_TIME(),UTC_TIMESTAMP(),CURRENT_TIMESTAMP()
運行結果如下:

注:UTC時區又稱世界同一時間、師姐協調時間,不屬於任意時區。而中國北京所在的東八區要比UTC時間早8個小時。
SELECT CONVERT_TZ('2004-01-01 12:00:00','+01:00','+10:00')
運行結果如下:

注: convert_tz(dt,from_tz,to_tz)這個函數再執行時,現將dt從from_tz轉到UTC,再從UTC轉到to_tz。
SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET') AS r_1
運行結果如下:
![]()
注意,如果想要在convert_tz()函數中使用GMT或者MET等命名時區的時候,需要在mysql.time_zone_name表中事先指定好時區及其名稱。如果沒有事先指定,在運行上述代碼的時候會返回NULL。
2.3 抽取部分
| 函數 | 說明 |
|---|---|
| DATE() | 抽取DATE或DATETIME的日期部分 |
| HOUR() | 抽取小時 |
| TIME() | 抽取時間 |
| EXTRACT() | 抽取日期或時間中的單獨部分,其語法形式為EXTRACT(unit FROM date)。 其中unit的取值類型為:MICROSECOND(微秒)、SECOND(秒)、MINUTE(分)、HOUR(小時)、DAY(天)、WEEK(周)、MONTH(月)、QUARTER(季度)、YEAR(年)、SECOND_MICROSECOND(秒_微秒)、MINUTE_MICROSECOND(分_微秒)、MINUTE_SECOND(分_秒)、HOUR_MICROSECOND(小時_微秒)、HOUR_SECOND(小時_秒)、HOUR_MINUTE(小時_分)、DAY_MICROSECOND(天_微秒)、DAY_SECOND(天_秒)、DAY_MINUTE( 天_分)、DAY_HOUR(天_小時)、YEAR_MONTH(年_月) |
| DAYNAME() | 返回Monday、Tuesday、Wednesday、Thursday、Friday、Saturday、Sunday |
| DAYOFWEEK() | 返回一周的第幾天(取值范圍從1到7)。注意,Sunday為第1天,Monday為第2天,依次類推 |
| DAYOFMONTH() | 返回日期為當月的第幾天。取值范圍從1到31 |
| DAY() | 與DAYOFMONTH()相同 |
| DAYOFYEAR() | 返回日期I為當年的第幾天。取值范圍從1到366 |
| LAST_DAY() | 返回日期所在月份的最后一天,返回日期類型 |
| MICROSECOND() | 返回日期的微秒。如果日期中沒有精確到微秒,則返回0 |
| MINUTE() | 返回時間部分的分鍾數。minute(current_date())返回0,可能是因為current_date()沒有時間部分。 |
| MONTH() | 返回月份,取值范圍從1到12. |
| MONTHNAME() | 返回月份的英文名稱:January(一月)、February(二月) 、March(三月)、April (四月)、May(五月)、June(六月)、July(七月)、August(八月)、September(九月)、October(十月)、November(十一月) 、December(十二月) |
| QUARTER() | 返回季度。取值范圍從1到4. |
| SECODN() | 返回秒數。 |
| WEEK() | 返回當前日期是該年的第幾周。 |
| WEEKDAY() | 返回日期在一周中的索引。取值范圍從0到6,Monday為0,Sunday為6. 其索引開始方式與DAYOFWEEK()不同 |
| WEEKOFYEAR() | 返回當前日期是改年的第幾周。 |
| YEAR() | 返回日期的年份 |
| YEARWEEK() | 返回日期的年份和周數。 |
-
select DATE(NOW()) as r_1,HOUR(NOW()) AS r_2, TIME(NOW()) AS r_3
-
union all
-
select DATE(CURRENT_DATE()) as r_1,HOUR(CURRENT_DATE()) AS r_2, TIME(CURRENT_DATE()) AS r_3
-
union all
-
select DATE(CURTIME()) as r_1,HOUR(CURTIME()) AS r_2,TIME(CURTIME()) as r_3
代碼運行結果如下:

注意: DATE(CURTIME())的結果。(從結果上看好像返回是當天的日期。具體原因,暫且不明)
-
select current_timestamp(),
-
extract(year_month from current_timestamp()) as r_1,
-
extract(day_hour from current_timestamp()) as r_2,
-
extract(day_second from current_timestamp()) as r_3,
-
extract(HOUR_MICROSECOND from current_timestamp()) as r_4,
-
extract(MINUTE_MICROSECOND from current_timestamp())as r_5,
-
extract(month from current_timestamp()) as r_6,
-
extract(QUARTER from current_timestamp()) as r_7,
-
extract(week from current_timestamp()) as r_8,
-
extract(hour from current_timestamp()) as r_9
代碼運行結果如下:

從上述代碼運行結果可以看出,extract()函數的返回類型應當都是整數類型。其余的函數用法比較簡單的就不介紹了。
下面介紹幾個關於week相關函數的用法。week()函數的完整語法形式為week(date,[mode])。mode決定了每周的第一天從星期一開始還是從星期天開始。在不同的模式下,同一日期返回的week數是不同的。具體的mode有如下8種。
| Mode | First day of week | Range | Week 1 is the first week … |
|---|---|---|---|
| 0 | Sunday | 0-53 | with a Sunday in this year |
| 1 | Monday | 0-53 | with 4 or more days this year |
| 2 | Sunday | 1-53 | with a Sunday in this year |
| 3 | Monday | 1-53 | with 4 or more days this year |
| 4 | Sunday | 0-53 | with 4 or more days this year |
| 5 | Monday | 0-53 | with a Monday in this year |
| 6 | Sunday | 1-53 | with 4 or more days this year |
| 7 | Monday | 1-53 | with a Monday in this year |

說明一下上述實驗結果怎么得到的。代碼太多,貼上去影響用戶體驗。首先我選了7個不同你那份的1月1號,這7個元旦分別發生在周一到周日,label字段就是用來說明這個1月1號是星期幾的。1代表周一,以此類推。r1\r3\r5\r7\r9\r11\r13\r15字段的值分別代表這7個不同元旦日期在8種模式下的week標號。r2\r4\r6\r8\r10\r12\r14\r16則分別代表該元旦日期的前一天(即上一年的12月31號)對應的week標號。通過分析以上結果可以發現:
- fisrt day of week:決定了week()函數返回值發生跳變的位置。
- Week 1 is the first week :決定了第1周應滿足的條件。
- Range:如果range可以從0開始,如果新年的前幾天不能滿足對應的week 1的條件的話,則對應日期的標號為0。如果Rang從1開始,則不滿足week 1標准的新的一年的前幾天沿用上一年的最后一周的標號。
weekofyear(date)等價於week(data,3),在mode=3這種模式下,每周開始的第一天為周一。range編號從1開始。
2.4 日期運算
| 函數 | 說明 |
|---|---|
| ADDDATE() | 有兩種形式,ADDDATE(date,interval expr unit)和ADDDATE(date,days)。注意使用interval時,后面的unit。猜測這里能使用的unit和extract()函數中的unit差不多。當unit是secon等類型是,返回datetime形式的數據。expr可正可負。 |
| ADDTIME() | ADDTIEM(expr1,expr2)。 expr1是datetime或time形式。expr2是時間形式 |
| DATE_ADD() | DATE_ADD(date,intervar expr unit)等價於ADDDATE(date,interval expr unit) |
| DATE_SUB() | DATE_SUB(date,interval expr unit)等價與SUBDATE() |
| DATE_DIFF() | DATE_DIFF(expr1,expr2)求兩個日期之間的差值(expr1-expr2)。如果expr1和expr2中有time部分,該部分不參與計算。 |
| PERIOD_ADD() | PERIOD_ADD(P,N)返回P+N。其中N代表月份數 P要使用YYYY或YYYYMM形式。 |
| PERIOD_DIFF() | PERIOD_DIFF(P1,P2) 返回兩個日期之間的月份數。P1和P2要使用YYYY或YYYYMM形式。 |
| SUBDATE() | 與ADDDATE()用法類似,作用相反。 |
| SUBTIME() | 與ADDTIME()用法類似,作用相反。 |
| TIMEDIFF() | TIMEDIFF(expr1,expr2)返回expr1和expr2的間隔的時間形式,expr1和expr2可以是time或date-time類型。但兩者類型必須一致。 |
| TIMESTAMPADD() | TIMESTAMPADD(unit, interval, datetime_expr)。返回datetime_expr+(interval)*unit表示的時間。 |
| TIMESTAMPDIFF() | TIMESTAMPDIFF(unit, datetime_expr1,datetime_expr2)返回(datetime_expr2-datetime_expr1)/unit |
關於union all要說明的一點是: 如果要union all的各個部分中名稱的相同的字段類型不同的話,union all會對字段類型進行統一。
相關資料:
1.https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html
