存儲時間的幾種方式
一般情況下:數據庫可以這樣存儲時間:
- bigint(存毫秒數Long)
- 存儲時間戳,然後
new Date(long date)
轉化爲時間
- 存儲時間戳,然後
- DateTime
- TimeStamp時間戳
閱讀官方文檔
1、DATE, DATETIME, TIMESTAMP三者的區別:
首先說一下三者的不同之處:
The
DATE
type is used for values with a date part but no time part. MySQL retrieves and displaysDATE
values in'*
YYYY-MM-DD*'
format. The supported range is'1000-01-01'
to'9999-12-31'
.Date只表示日期,年-月-日,不表示具體的時間
The
DATETIME
type is used for values that contain both date and time parts. MySQL retrieves and displaysDATETIME
values inYYYY-MM-DD hh:mm:ss
format. The supported range is'1000-01-01 00:00:00'
to'9999-12-31 23:59:59'
.DateTime即表示日期,又表示時間,YYYY-MM-DD hh:mm:ss,它更像是一個·字符串表示
The
TIMESTAMP
data type is used for values that contain both date and time parts.TIMESTAMP
has a range of'1970-01-01 00:00:01'
UTC to'2038-01-19 03:14:07'
UTC.
TIMESTAMP
和DateTime類似,即表示時間,又表示日期,A
DATETIME
orTIMESTAMP
value can include a trailing fractional seconds part in up to microseconds (6 digits) precision. In particular, any fractional part in a value inserted into aDATETIME
orTIMESTAMP
column is stored rather than discarded. With the fractional part included, the format for these values is'*
YYYY-MM-DD hh:mm:ss*[.*
fraction*]'
, the range forDATETIME
values is'1000-01-01 00:00:00.000000'
to'9999-12-31 23:59:59.999999'
, and the range forTIMESTAMP
values is'1970-01-01 00:00:01.000000'
to'2038-01-19 03:14:07.999999'
. The fractional part should always be separated from the rest of the time by a decimal point; no other fractional seconds delimiter is recognized. For information about fractional seconds support in MySQL, see Section 11.2.6, “Fractional Seconds in Time Values”.DATETIME或TIMESTAMP值可以包含最高達微秒(6位)精度的尾隨小數秒部分。特別是,插入DATETIME或TIMESTAMP列的值中的任何小數部分都將被存儲而不是丟棄。包含小數部分時,這些值的格式爲“YYYY-MM-DD hh:MM:ss[.fraction]”,
DATETIME值的範圍爲“1000-01-01 00:00:00.000000”到“9999-12-31 23:59:59.999999”,TIMESTAMP值的範圍爲“1970-01-01 00:00:01.000000”到“2038-01-19 03:14:07.999999”。
小數部分應始終與其餘時間用小數點分隔;不能識別其他小數秒分隔符
2、TIMESTAMP
與TimeZone的關係
MySQL converts
TIMESTAMP
values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such asDATETIME
.)存儲時,MySQL將
TIMESTAMP
值從當前時區轉換爲UTC時間進行存儲,查詢時,將數據從UTC轉換爲檢索的當前時區。(其他類型(如DATETIME)不會發生這種情況。)By default, the current time zone for each connection is the server’s time. The time zone can be set on a per-connection basis. As long as the time zone setting remains constant, you get back the same value you store.
默認情況下,每個連接的當前時區是服務器的時間。時區可以根據每個連接進行設置。只要時區設置保持不變,就可以得到存儲的相同值。
If you store a
TIMESTAMP
value, and then change the time zone and retrieve the value, the retrieved value is different from the value you stored. This occurs because the same time zone was not used for conversion in both directions. The current time zone is available as the value of thetime_zone
system variable. For more information, see Section 5.1.13, “MySQL Server Time Zone Support”.如果存儲
TIMESTAMP
值,然後更改時區並檢索該值,則檢索到的值與存儲的值不同。發生這種情況的原因是沒有使用同一時區在兩個方向上進行轉換。當前時區可用作時區系統變量的值。有關詳細信息,請參閱第5.1.13節“MySQL服務器時區支持”。
3、關於Mysql中TimeZone的簡介:
MySQL Server maintains several time zone settings:
MySQL Server維護幾個時區設置:
The system time zone. When the server starts, it attempts to determine the time zone of the host machine automatically and uses it to set the
system_time_zone
system variable. The value does not change thereafter.系統時區。服務器啓動時,它將嘗試自動確定主機的時區,並使用它來設置
system_time_zone
系統變量。此後該值不變。To explicitly specify the system time zone for MySQL Server at startup, set the
TZ
environment variable before you start mysqld. If you start the server using mysqld_safe, its--timezone
option provides another way to set the system time zone. The permissible values forTZ
and--timezone
are system dependent. Consult your operating system documentation to see what values are acceptable.要在啓動時爲MySQL Server明確指定系統時區,請在啓動mysqld
TZ
之前設置環境變量。如果使用mysqld_safe啓動服務器,則其 選項提供了另一種設置系統時區的方法。對於允許值和 是取決於系統。請查閱操作系統文檔,以瞭解可以接受的值。--timezone
TZ
--timezone
The server current time zone. The global
time_zone
system variable indicates the time zone the server currently is operating in. The initialtime_zone
value is'SYSTEM'
, which indicates that the server time zone is the same as the system time zone.服務器當前時區。全局
time_zone
系統變量指示服務器當前正在運行的時區。初始time_zone
值爲'SYSTEM'
,指示服務器時區與系統時區相同。Per-session time zones. Each client that connects has its own session time zone setting, given by the session
time_zone
variable. Initially, the session variable takes its value from the globaltime_zone
variable, but the client can change its own time zone with this statement:會話時區。每個連接的客戶端都有自己的會話時區設置,由會話
time_zone
變量指定。最初,會話變量從全局變量獲取其值time_zone
,但是客戶端可以使用以下語句更改其自己的時區:
關鍵就是會話TimeZone,每個客戶端
數據庫默認的時區都是System
。
4、如何修改timezone的值
timezone
值可以以幾種格式給出,都不區分大小寫:
- 作爲值
'SYSTEM'
,指示服務器時區與系統時區相同。- 作爲表示一個字符串的從表單的UTC偏移 ,帶有前綴
+
或-
,例如,+10:00
,'-6:00'
, or+05:30
,例如我們是東八區+8:00
- MySQL 8.0.19之前,該值必須在範圍
'-12:59'
到'+13:00'
,包容性;- MySQL 8.0.19之後,允許範圍爲
'-14:00'
到'+14:00'
,包容性。- 作爲命名的時區,例如
'Europe/Helsinki'
,'US/Eastern'
或'MET'
。僅當mysql
已經創建並填充了數據庫中的時區信息表時,才能使用命名時區 。
-- 設置session時區
SET time_zone = 'Asia/Shanghai';
-- 查詢系統時區和session時區
SELECT @@global.time_zone, @@session.time_zone;
-- 當前session時區
show VARIABLES like '%time_zone%';
5、TimeZone的影響
The session time zone setting affects display and storage of time values that are zone-sensitive. This includes the values displayed by functions such as
NOW()
orCURTIME()
, and values stored in and retrieved fromTIMESTAMP
columns. Values forTIMESTAMP
columns are converted from the session time zone to UTC for storage, and from UTC to the session time zone for retrieval.會話時區設置會影響對時區敏感的時間值的顯示和存儲。這包括由諸如
NOW()
或 的函數顯示的值CURTIME()
,以及存儲在TIMESTAMP
列中並從列中檢索的值。TIMESTAMP
列的值從會話時區轉換爲UTC以進行存儲,並從UTC轉換爲會話時區以進行檢索。The session time zone setting does not affect values displayed by functions such as
UTC_TIMESTAMP()
or values inDATE
,TIME
, orDATETIME
columns. Nor are values in those data types stored in UTC; the time zone applies for them only when converting fromTIMESTAMP
values. If you want locale-specific arithmetic forDATE
,TIME
, orDATETIME
values, convert them to UTC, perform the arithmetic, and then convert back.會話時區設置不會影響
UTC_TIMESTAMP()函數
、DATE
、TIME
,或DATETIME
列中的或值 。這些數據類型中的值也不會像TimeStamp轉換爲UTC存儲;時區僅在從TIMESTAMP
值轉換時適用 。如果要針對DATE
,TIME
或DATETIME
值進行語言環境特定的算術 ,請將其轉換爲UTC,執行該算術,然後再轉換回去。
demo測試
可能上邊的大段文字,你沒有讀懂,那我現在給你舉一個例子:
有一個user
表如圖所示:
當前會話時區爲+8:00
即東八區,查詢所有用戶:
用set time_zone=‘+0:00’修改時區
,再次查詢發現TimeStamp
類型的gmt_create
發生了變化。
總結
Date
、Time
、DateTime
類型不支持時區轉換。TimeStamp
列的值從會話時區轉換爲UTC以進行存儲,並從UTC轉換爲會話時區以進行檢索。- 可以理解爲它存儲時區,而
DateTime
不存儲時區。 - 且從
DateTime
和TimeStamp
的表示範圍上,我們就能看出來DateTime
有點字符串的意思,而TimeStamp
則不是。
- 可以理解爲它存儲時區,而
參考資料
https://developer.aliyun.com/article/728315
https://segmentfault.com/a/1190000016426048
https://dev.mysql.com/doc/refman/8.0/en/time-zone-support.html
https://dev.mysql.com/doc/refman/8.0/en/time-zone-support.html