[Linux/MYSQL/Java] 时间与时区(UTC/GMT/CST/Timestamp)
序
- MYSQL JDBC 版本 : 8.0.28
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.jdbc.version}</version>
</dependency>
- MYSQL 版本:
MYSQL 5.7.38-221001-log
基本概念
GMT(格林尼治标准时间、世界时间) 与 UTC(协调世界时间)
GMT(格林尼治标准时间、世界时间) 【不推荐】、UTC(协调世界时间) 【推荐】
- GMT(Greenwich Mean Time,格林威治标准时间):GMT是基于地球自转和对恒星的观测来定义的时间标准,将地球划分为24个时区。
它以英国伦敦郊区的格林尼治天文台为参考点,当太阳在每年的某一天通过格林尼治子午线的时刻为中午12点。
GMT曾经是国际上主要的时间标准,但由于地球自转速度会有微小的变化,GMT并不是一个非常精确的时间标准。
- UTC(Coordinated Universal Time,协调的世界时间):UTC是在GMT的基础之上,基于原子时钟的测量,让世界各地的时差保持一致。
这些原子时钟的精度非常高,几乎不受环境因素影响。
UTC由国际时间标准组织(法国人发起)维护,并通过增加或减少闰秒来校正地球自转速度的微小变化,以保持与GMT的一致性。)维护,并通过增加或减少闰秒来校正地球自转速度的微小变化,以保持与GMT的一致性。
UTC是当前国际上最广泛使用的时间标准**,被用于全球的时间服务、互联网、航空等领域。
UTC比GMT更为精确,误差值必须保持在0.9秒以内。
-- mysql 5.7
> set time_zone = 'UTC';
> select CURTIME()
CURTIME()|
---------+
12:53:29|
> set time_zone = 'GMT';
> select CURTIME()
CURTIME()|
---------+
12:53:29|
- 时间偏移的对比
由于地球自转轴的倾斜和地球公转轨道的椭圆形状,地球上不同地区的太阳高度角和白昼时间会有所不同。
这导致了GMT
在跨越经度较大的地区时,时间会出现较大的偏差。
而UTC
则能较好地反映地球的真实形状,因此在跨越经度较大的地区时,时间偏差较小。
- 在实际应用中,UTC通常被认为是更现代和精确的时间标准,尤其是在需要高精度时间的情况下,UTC是首选的时间标准。
尽管GMT和UTC之间通常差异很小,但在需要高精度的时间应用中,UTC更为适用。
在互联网中,UTC时间系统被应用与许多互联网和万维网的标准中,网络时间协议就是协调世界时(UTC)的一种使用方式。
在军事中,UTC时区会使用Z
来表示。又由于Z
在无线电联络中使用Zulu
作代称,协调世界时也会被称为Zulu time
yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
- 推荐文献
可直观地了解GMT和UTC的区别
美国时间(American Time
) : 东部EST/中部CST/山地MST/西部(太平洋)PST
一般被认为是美国本土及2个海外州的时间。
美国本土横跨西五区至西八区,共4个时区,每个时区对应一个标准时间。从东向西分别为:
- 东部时间(
EST
)西五区时间- 中部时间(CST)西六区时间
- 山地时间(MST)西七区时间
- 太平洋时间(西部时间)(PST)(西八区时间)
2个海外州为阿拉斯加州和夏威夷州,时间分别是:
- 阿拉斯加时间(
AKST
)(西九区时间)- 夏威夷时间(HST)(西十区时间)
因此,美国时间包括6个时区,每个时区对应一个标准时间,按照“东早西晚”的规律,各递减一小时。
美国从每年3月的第二个星期日至11月的第一个星期日采用夏令时,夏令时比正常时间快一小时。
UTC+10 夏莫罗标准时区
UTC-11 美属萨摩亚标准时区
UTC-10HST夏威夷-阿留申标准时区
UTC-9AKST阿拉斯加标准时区
UTC-8PST太平洋标准时区
UTC-7MST山地标准时区
UTC-6CST中部标准时区
UTC-5EST东部标准时区
UTC-4AST大西洋标准时区
CST(中国、美国、澳大利亚、古巴的标准时间)
CST
时间(默认指,China Standard Time, 中国标准时间)
在时区划分上,属东八区,比协调世界时早8小时,记为UTC+8。
CST时间:China Standard Time,即中国标准时间。在时区划分上,属东八区,比协调世界时早8小时,记为UTC+8。
恶心的CST
问题(4个同名CST时区/mysql/java/...)
-
结论:重新配置MYSQL
system_time_zone
为非CST
,或 修改time_zone
改成非SYSTEM
) -
CST同名的有4个时区
Central Standard Time (USA) UT-6:00 美国标准时间
Central Standard Time (Australia) UT+9:30 澳大利亚标准时间
China Standard Time UT+8:00 中国标准时间
Cuba Standard Time UT-4:00 古巴标准时间
- 这个不仅仅是重名的问题,而且在某些情况下会造成
bug
,详细看另一篇博文。这里简单说一下:
CST
时区是个非常坑的概念,因为在mysql
里被理解为China Standard Time
(GMT+8
)
但在Java
里被理解为Central Standard Time
(USA
)(GMT-6
),这就是造成坑的原因。
- 解决办法:
mysql
就别用CST
时区,改成+08:00
以免造成误解。(肯定改mysql啦,你改得了jdk源码吗?)- 如果
mysql
的time_zone
变量是SYSTEM
,而system_time_zone
是CST
的值,system_time_zone的CST这个字符串会造成bug。
- mysql jdbc
mysql的jdbc驱动的代码里会设置时区,这个时区是通过 TimeZone.getTimeZone(canonicalTimezone) 读取,其中 canonicalTimezone 是字符串, TimeZone.getTimeZone("CST") 返回-6时区,即美国的时区。
Java
中的CST
时区问题坑
java.util.TimeZone
TimeZone.getTimeZone("Asia/Shanghai").getRawOffset() : 28800000 (单位:毫秒,即 +8h,即 中国东八区)
TimeZone.getTimeZone("CST").getRawOffset() : -21600000 (单位:毫秒,即 -6h,即美国西六时区,代表城市芝加哥、新奥尔良与北京时间有15小时的时差)
java.text.SimpleDateFormat
/java.util.TimeZone
@Test
public void test() {
String str = "1989-05-29 00:00:00";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 不加时区有问题 : date : Mon May 29 00:00:00 CDT 1989 | ts : 612370800000 (个人理解,等效于: 1989-05-29 00:00:00 UTC+8)
// 加时区(GMT+08)后,修正结果 : date : Sun May 28 23:00:00 GMT+08:00 1989 | ts : 612370800000 (个人理解,等效于: 1989-05-29 00:00:00 UTC+8) | 不兼容中国夏令时
// 加时区(UTC+08)后,修正结果 : date : Sun May 28 15:00:00 GMT 1989 | ts : 612370800000 (个人理解,等效于: 1989-05-29 00:00:00 UTC+8)
// 加时区(UTC)后,修正结果 : date : Sun May 28 15:00:00 UTC 1989 | ts : 612370800000 (个人理解,等效于: 1989-05-29 00:00:00 UTC+8)
// 加时区(Asia/Shanghai)后,修正结果 : date : Mon May 29 00:00:00 CDT 1989 | ts : 612370800000 (个人理解,等效于: 1989-05-29 00:00:00 UTC+8) | 兼容中国夏令时
//TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));//"GMT+08" / "UTC+08" / "UTC" / "Asia/Shanghai"
Date date = simpleDateFormat.parse(str);
System.out.println("date : " + date.toString() + " | ts : "+ date.toInstant().toEpochMilli());
}
打印获取到日期,发现两个日期存在了时区的不同,一个为
CDT
,一个为CST
;
CDT
:为夏令时时间(中华人民共和国在1986
年~1991
年实行了夏令时制度,每年夏令时实行时间如下:1986年5月4日至9月14日(1986年因是实行夏令时的第一年,从5月4日开始到9月14日结束)
1987年4月12日至9月13日
1988年4月10日至9月11日
1989年4月16日至9月17日
1990年4月15日至9月16日
1991年4月14日至9月15日
-
CST
:为美国、澳大利亚、古巴或中国的标准时间。 -
CST
的时间和CDT
的时间是相差了13个小时。 -
解决方法:需根据实际情况,选择使用何时的时区
常用的
GMT+8
的时区设置,并不兼容夏令时。
使用TimeZone = Asia/Shanghai
,则会兼容夏令时。
当mysql的url
,修改为配置serverTimezone=Asia/Shanghai
,可解决插入数据库时间错误问题
当java应用返回给前端的时候,设置JsonFormat
的timeZone
的时候,也需要使用此配置:@JsonFormat(timezone = “Asia/Shanghai”, pattern = “yyyy/MM/dd”)
这样才可以保证前端的数据展示正确。
(UNIX)时间戳
UNIX
时间戳(timestamp
):计算机中的UNIX时间戳,是以GMT
/UTC
时间1970-01-01T00:00:00
为起点,到当前具体时间的秒数(不考虑闰秒)。
这样做的目的,主要是通过“整数计算”来简化计算机对时间操作的复杂度。
时间单位换算
- 1分钟(min) = 60秒(s)
- 1秒(s) = 1000 毫秒(ms)
- 1毫秒(ms) = 1000微秒(μs)
- 1000微秒(μs) = 1000 纳秒(ns)
Linux 的时间操作
获取时间
- 获取本地时间
root@xxx:~# date
Wed Nov 27 09:12:59 PM CST 2024
root@xxx:~# date +'%Y-%m-%d %H:%M:%S.%s'
2024-11-27 21:13:20.1732713200
- 获取UTC时间
root@xxx:~# date +'%Y-%m-%d %H:%M:%S.%s' -u
2024-11-27 13:14:04.1732713244
root@xxx:~# date; date -u
Wed Nov 27 09:14:46 PM CST 2024
Wed Nov 27 01:14:46 PM UTC 2024
可见,与本地时间(UTC+8)确实相差8小时
date
命令的参数
%T
时间(24小时制)(hh:mm:ss)%y
年的最后两个数字( 1999则是99)%Y
年(例如:1970,1996等)%m
月(01..12)%d
日、一个月的第几天(01..31)%D
日期(mm/dd/yy)%j
一年的第几天(001..366)%H
小时(00..23)%M
分(00..59)%S
秒(00..59)%s
从1970年1月1日00:00:00到目前经历的秒数%N
从1970年1月1日00:00:00到目前经历的纳秒
> date +%s.%N
1715409477.512093100
> DATE_STR=$(date +'%Y-%m-%d %H:%M:%S')
> DATE_STR=$(date +'%Y%m%d%H%M%S')
> echo $DATE_STR
2023-04-15 21:08:35
# 字符串拼接方式(秒级时间戳 + 毫秒级的3位)
> echo $(date +%s)$(( "$(echo $(date +%N) | awk '{print $0+0}' )/1000000" ))
> echo $(date +%s)$( echo $(( "$(echo $(date +%N) | awk '{print $0+0}' )/1000000" )) | awk '{printf("%03d\n",$0)}' )
1715409575298
# 字符串拼接方式(秒级时间戳 + 毫秒级的3位) + 字符串转为数值
> echo $( expr $(( $(date +%s)$( echo $(( "$(echo $(date +%N) | awk '{print $0+0}' )/1000000" )) | awk '{printf("%03d\n",$0)}' ) )) \* 1 )
1715409575298
获取时间戳
获取时间戳,不管是UTC时间还是北京时间 时间戳都是一样
是以GMT/UTC
时间1970-01-01T00:00:00
为起点,到当前具体时间的秒数(不考虑闰秒)
root@xxx:~# date +%s;date +%s -u
1732713357
1732713357
将【时间戳】转为时间字符串
[root@chb1 ~]# date -d @1682137164
Sat Apr 22 12:19:24 CST 2023
[root@chb1 ~]# date -d @1682137164 +'%Y-%m-%d %H:%M:%S.%s'
2023-04-22 12:19:24.1682137164
[root@chb1 ~]# date -d @1682137164 +'%Y-%m-%d %H:%M:%S.%s' -u
2023-04-22 04:19:24.1682137164
获取当前系统时区
- 可以通过
date +%Z
或者timedatectl
root@xxx:~# date +%Z
CST
root@xxx:~# date +%z
+0800
root@xxx:~# timedatectl
Local time: Wed 2024-11-27 21:11:04 CST
Universal time: Wed 2024-11-27 13:11:04 UTC
RTC time: Wed 2024-11-27 13:11:04
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
查看时区配置文件:/etc/localtime
root@xxx:~# ls -l /etc/localtime
lrwxrwxrwx 1 root root 33 Jul 7 12:11 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai
Java 的时间操作
java.time.Instant : 时间戳常量
- java.time.Instant
Java 8 新增 API
所谓的Instant
类代表的是某个时间(有点像java.util.Date
),它是精确到纳秒的(而不是象旧版本的Date
精确到毫秒)。
如果使用纳秒去表示一个时间则原来使用一位Long
类型是不够的,需要占用更多一点的存储空间。
实际上,Instant
的内部是由两个Long
字段组成:
- 第1个部分保存的是自标准Java计算时代(就是1970年1月1日开始)到现在的秒数
- 第2部分保存的是纳秒数(永远不会超过999,999,999)。
- API:
long toEpochMilli()
用于将此
Instant
转换为自1970-01-01T00:00:00Z
以来的Java时期标准格式的毫秒数。
//获得当前时间
Instant instant = Instant.now();
Long ms = instant.toEpochMilli(); //1732774113958
- 将
java.util.Date/Calendar
转换为Instant
java.util.Calendar calendar = Calendar.getInstance();
java.util.Date now = calendar.getTime();
long ts = now.getTime();//13位、毫秒级时间戳
Instant instant = Instant.ofEpochMilli( ts );
- 从时间字符串类型中创建
Instant
类型的时间
Instant instant = Instant.parse("1995-10-23T10:12:35Z"); // UTC+0 格式的时间字符串
instant.toEpochMilli();//8144 4315 5000 (单位: 毫秒) => 换算为 UTC+8时,则对应时间为: 1995-10-23 18:12:35
注意,在上面这个例子中,有一个时间字符串中创建
Instant
类型的时间,但Instant
代表的是一个时间,并不包括时区的概念,所以必须传入的是符合UTC
格式的时间字符串。
- 允许使用 Instant 和其他包中的类进行一些运算
Instant instant = Instant.parse("1995-10-23T10:12:35Z");
Instant instant2 = instant.plus(Duration.ofHours(5).plusMinutes(4));
instant2.toEpochMilli();//8144 6139 5000 (毫秒级时间戳) => 相当于 1995-10-23 23:16:35 (UTC+8)
java.time.LocalDateTime : 本地时间
- 定义
它是
LocalDate
和LocalTime
的组合体,表示的是不带时区的日期及时间。
包含了年、月、日、时、分、秒等信息,可以精确到纳秒级别。
与Date类不同,LocalDateTime 不受时区的影响,更适合处理应用程序中不涉及时区转换的日期和时间。
-
最主要的特性:
(1) 不可变性(Immutability): LocalDateTime 是不可变的,这意味着一旦创建了对象,就无法更改其内容。任何对日期和时间的修改都会返回一个新的LocalDateTime对象。
(2) 线程安全性: 由于不可变性,LocalDateTime 是线程安全的。多个线程可以同时访问对象而无需担心并发问题。
(3) 工厂方法: 除了使用of方法创建 LocalDateTime 对象外,还有一些静态工厂方法,如now、ofInstant、ofEpochSecond等,用于根据不同的情况创建实例。
(4) 日期时间调整: LocalDateTime 提供了 plus、minus 等方法,用于执行日期和时间的调整操作。这些方法返回新的对象,而不是修改原始对象。
(5) 格式化和解析: LocalDateTime 支持 DateTimeFormatter 用于格式化和解析日期时间。你可以创建自定义的格式化模式。 -
API:
LocalDateTime : static now()
//获取当前日期时间:
LocalDateTime currentDateTime = LocalDateTime.now();
- API:
of(int var0, Month var1, int var2, int var3, int var4)
//创建指定日期时间:
LocalDateTime specificDateTime = LocalDateTime.of(2022, Month.JANUARY, 1, 12, 30);
-
API:
Instant toInstant(ZoneOffset var1)
-
API:
long toEpochSecond(ZoneOffset var1)
返回10位的秒级时间戳
LocalDateTime localDateTime = LocalDateTime.now();
localDateTime.toEpochSecond(ZoneOffset.of("+08")); //10位的秒级时间戳
- API :
ZonedDateTime atZone(ZoneId var1)
atZone()
方法用于通过将此LocalDateTime
(日期时间) 合并到给定区域来创建ZonedDateTime
。
LocalDateTime localDateTime = LocalDateTime.parse("2024-01-01T00:00:00");
ZonedDateTime utc8ZonedDateTime = localDateTime.atZone(ZoneId.of("+08"));
utc8ZonedDateTime.toInstant().toEpochMilli();//1704038400000 => 相当于: 2024-01-01 00:00:00 (UTC+8)
ZonedDateTime utc0ZonedDateTime = localDateTime.atZone(ZoneId.of("+00"));
utc0ZonedDateTime.toInstant().toEpochMilli();//1704067200000 => 相当于: 2024-01-01 08:00:00 (UTC+8)
java.time.LocalDateTime#now()
方法的源码分析
java.time.LocalDateTime
//java.time.LocalDateTime#now()
public static LocalDateTime now() { // 分析入口
return now(Clock.systemDefaultZone());
}
//java.time.LocalDateTime#now(java.time.ZoneId)
public static LocalDateTime now(ZoneId var0) {
return now(Clock.system(var0));
}
//java.time.LocalDateTime#now(java.time.Clock)
public static LocalDateTime now(Clock var0) {
Objects.requireNonNull(var0, "clock");
Instant var1 = var0.instant();
ZoneOffset var2 = var0.getZone().getRules().getOffset(var1);
return ofEpochSecond(var1.getEpochSecond(), var1.getNano(), var2);
}
java.time.Clock
//java.time.Clock#systemDefaultZone
public static Clock systemDefaultZone() {
return new SystemClock(ZoneId.systemDefault());
}
java.time.ZoneId
//java.time.ZoneId#systemDefault
public static ZoneId systemDefault() {
// TimeZone.getDefault() 返回的对象 := java.util.TimeZone
// 例如: TimeZone.getDefault().getID() = "Asia/Shanghai" | TimeZone.getDefault().getDisplayName() := "中国标准时间"
// 例如: TimeZone.getDefault().getRawOffset() := 28800000 (单位: 毫秒)
// 例如: 支持主动设置时区 | TimeZone.setDefaultZone(); or TimeZone.setDefault(TimeZone.getTimeZone("UTC")); // "UTC" or "+00" or ...
return TimeZone.getDefault().toZoneId();
}
ZonedDateTime : 时区时间
- API:
ChronoZonedDateTime withZoneSameInstant(ZoneId zone)
返回值: 该方法根据请求区域的日期时间返回一个时区数据。
异常:此方法抛出日期时间异常:如果结果超出支持的日期范围。
ChronoZonedDateTime zonedDT = ZonedDateTime.parse( "2018-12-06T19:21:12.123+05:30[Asia/Calcutta]");
ZoneOffset f = zonedDT.getOffset(); // id = "+05:30" / totalSeconds = 19800
获取系统默认时区 : ZoneId.systemDefault()
/ TimeZone#getDefault
/ TimeZone#setDefaultZone
java.time.ZoneId#systemDefault
: 分析入口
public static ZoneId systemDefault() {//获取系统默认时区
return TimeZone
.getDefault() // java.util.TimeZone#getDefault
.toZoneId(); // java.util.TimeZone#toZoneId
}
java.util.TimeZone#toZoneId
public ZoneId toZoneId() {
String var1 = this.getID();
if (ZoneInfoFile.useOldMapping() && var1.length() == 3) {
if ("EST".equals(var1)) {
return ZoneId.of("America/New_York");
}
if ("MST".equals(var1)) {
return ZoneId.of("America/Denver");
}
if ("HST".equals(var1)) {
return ZoneId.of("America/Honolulu");
}
}
return ZoneId.of(var1, ZoneId.SHORT_IDS);
}
java.util.TimeZone#getDefault
public static TimeZone getDefault() {
return (TimeZone)getDefaultRef().clone();//java.util.TimeZone#getDefaultRef
}
java.util.TimeZone#getDefaultRef
static TimeZone getDefaultRef() {
TimeZone var0 = defaultTimeZone;//defaultTimeZone : TimeZone 的 静态属性 : private static volatile TimeZone defaultTimeZone;
if (var0 == null) {
var0 = setDefaultZone();//java.util.TimeZone#setDefaultZone
assert var0 != null;
}
return var0;
}
java.util.TimeZone#setDefaultZone
private static synchronized TimeZone setDefaultZone() {
final String var1 = (String)AccessController.doPrivileged(new GetPropertyAction("user.timezone"));
String var2;
if (var1 == null || var1.isEmpty()) {
var2 = (String)AccessController.doPrivileged(new GetPropertyAction("java.home"));
try {
var1 = getSystemTimeZoneID(var2);// java.util.TimeZone#getSystemTimeZoneID : private static native String getSystemTimeZoneID(String var0);
if (var1 == null) {
var1 = "GMT";
}
} catch (NullPointerException var4) {
var1 = "GMT";
}
}
TimeZone var0 = getTimeZone(var1, false);
if (var0 == null) {
var2 = getSystemGMTOffsetID();
if (var2 != null) {
var1 = var2;
}
var0 = getTimeZone(var1, true);
}
assert var0 != null;
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
System.setProperty("user.timezone", var1);
return null;
}
});
defaultTimeZone = var0;
return var0;
}
- 补充:设置 java 默认时区的方式
- 方式1
// 设置时区为 Asia/Shanghai
System.setProperty("user.timezone", "Asia/Shanghai");
这行代码用于设置系统的默认时区为 “Asia/Shanghai”。
或者 通过 JVM参数(
VM Options
)
java -Duser.timezone=Asia/Shanghai YourMainClass
- 方式2
// 应用时区设置
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
- 案例:使用系统默认时区
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class TimeExample {
public static void main(String[] args) {
Instant instant = Instant.now();
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = zonedDateTime.format(formatter);
System.out.println("Current Date and Time: " + formattedDateTime);
}
}
获取可用的时区
Java一共定义了 603个 时区,这些时区的名字是不需要你去背的,在
java.time.ZoneId
这个类中有一个方法可以获取到:getAvailableZoneIds()
这个方法是 static 静态方法,因此我们直接用类名直接调用就行了。
- 获取所有可用的时区
static Set<string> getAvailableZoneIds() // 获取Java中支持的所有时区名称
["Asia/Aden","America/Cuiaba","Etc/GMT+9","Etc/GMT+8","Africa/Nairobi","America/Marigot","Asia/Aqtau","Pacific/Kwajalein","America/El_Salvador","Asia/Pontianak","Africa/Cairo","Pacific/Pago_Pago","Africa/Mbabane","Asia/Kuching","Pacific/Honolulu","Pacific/Rarotonga","America/Guatemala","Australia/Hobart","Europe/London","America/Belize","America/Panama","Asia/Chungking","America/Managua","America/Indiana/Petersburg","Asia/Yerevan","Europe/Brussels","GMT","Europe/Warsaw","America/Chicago","Asia/Kashgar","Chile/Continental","Pacific/Yap","CET","Etc/GMT-1","Etc/GMT-0","Europe/Jersey","America/Tegucigalpa","Etc/GMT-5","Europe/Istanbul","America/Eirunepe","Etc/GMT-4","America/Miquelon","Etc/GMT-3","Europe/Luxembourg","Etc/GMT-2","Etc/GMT-9","America/Argentina/Catamarca","Etc/GMT-8","Etc/GMT-7","Etc/GMT-6","Europe/Zaporozhye","Canada/Yukon","Canada/Atlantic","Atlantic/St_Helena","Australia/Tasmania","Libya","Europe/Guernsey","America/Grand_Turk","US/Pacific-New","Asia/Samarkand","America/Argentina/Cordoba","Asia/Phnom_Penh","Africa/Kigali","Asia/Almaty","US/Alaska","Asia/Dubai","Europe/Isle_of_Man","America/Araguaina","Cuba","Asia/Novosibirsk","America/Argentina/Salta","Etc/GMT+3","Africa/Tunis","Etc/GMT+2","Etc/GMT+1","Pacific/Fakaofo","Africa/Tripoli","Etc/GMT+0","Israel","Africa/Banjul","Etc/GMT+7","Indian/Comoro","Etc/GMT+6","Etc/GMT+5","Etc/GMT+4","Pacific/Port_Moresby","US/Arizona","Antarctica/Syowa","Indian/Reunion","Pacific/Palau","Europe/Kaliningrad","America/Montevideo","Africa/Windhoek","Asia/Karachi","Africa/Mogadishu","Australia/Perth","Brazil/East","Etc/GMT","Asia/Chita","Pacific/Easter","Antarctica/Davis","Antarctica/McMurdo","Asia/Macao","America/Manaus","Africa/Freetown","Europe/Bucharest","Asia/Tomsk","America/Argentina/Mendoza","Asia/Macau","Europe/Malta","Mexico/BajaSur","Pacific/Tahiti","Africa/Asmera","Europe/Busingen","America/Argentina/Rio_Gallegos","Africa/Malabo","Europe/Skopje","America/Catamarca","America/Godthab","Europe/Sarajevo","Australia/ACT","GB-Eire","Africa/Lagos","America/Cordoba","Europe/Rome","Asia/Dacca","Indian/Mauritius","Pacific/Samoa","America/Regina","America/Fort_Wayne","America/Dawson_Creek","Africa/Algiers","Europe/Mariehamn","America/St_Johns","America/St_Thomas","Europe/Zurich","America/Anguilla","Asia/Dili","America/Denver","Africa/Bamako","Europe/Saratov","GB","Mexico/General","Pacific/Wallis","Europe/Gibraltar","Africa/Conakry","Africa/Lubumbashi","Asia/Istanbul","America/Havana","NZ-CHAT","Asia/Choibalsan","America/Porto_Acre","Asia/Omsk","Europe/Vaduz","US/Michigan","Asia/Dhaka","America/Barbados","Europe/Tiraspol","Atlantic/Cape_Verde","Asia/Yekaterinburg","America/Louisville","Pacific/Johnston","Pacific/Chatham","Europe/Ljubljana","America/Sao_Paulo","Asia/Jayapura","America/Curacao","Asia/Dushanbe","America/Guyana","America/Guayaquil","America/Martinique","Portugal","Europe/Berlin","Europe/Moscow","Europe/Chisinau","America/Puerto_Rico","America/Rankin_Inlet","Pacific/Ponape","Europe/Stockholm","Europe/Budapest","America/Argentina/Jujuy","Australia/Eucla","Asia/Shanghai","Universal","Europe/Zagreb","America/Port_of_Spain","Europe/Helsinki","Asia/Beirut","Asia/Tel_Aviv","Pacific/Bougainville","US/Central","Africa/Sao_Tome","Indian/Chagos","America/Cayenne","Asia/Yakutsk","Pacific/Galapagos","Australia/North","Europe/Paris","Africa/Ndjamena","Pacific/Fiji","America/Rainy_River","Indian/Maldives","Australia/Yancowinna","SystemV/AST4","Asia/Oral","America/Yellowknife","Pacific/Enderbury","America/Juneau","Australia/Victoria","America/Indiana/Vevay","Asia/Tashkent","Asia/Jakarta","Africa/Ceuta","Asia/Barnaul","America/Recife","America/Buenos_Aires","America/Noronha","America/Swift_Current","Australia/Adelaide","America/Metlakatla","Africa/Djibouti","America/Paramaribo","Asia/Qostanay","Europe/Simferopol","Europe/Sofia","Africa/Nouakchott","Europe/Prague","America/Indiana/Vincennes","Antarctica/Mawson","America/Kralendijk","Antarctica/Troll","Europe/Samara","Indian/Christmas","America/Antigua","Pacific/Gambier","America/Indianapolis","America/Inuvik","America/Iqaluit","Pacific/Funafuti","UTC","Antarctica/Macquarie","Canada/Pacific","America/Moncton","Africa/Gaborone","Pacific/Chuuk","Asia/Pyongyang","America/St_Vincent","Asia/Gaza","Etc/Universal","PST8PDT","Atlantic/Faeroe","Asia/Qyzylorda","Canada/Newfoundland","America/Kentucky/Louisville","America/Yakutat","Asia/Ho_Chi_Minh","Antarctica/Casey","Europe/Copenhagen","Africa/Asmara","Atlantic/Azores","Europe/Vienna","ROK","Pacific/Pitcairn","America/Mazatlan","Australia/Queensland","Pacific/Nauru","Europe/Tirane","Asia/Kolkata","SystemV/MST7","Australia/Canberra","MET","Australia/Broken_Hill","Europe/Riga","America/Dominica","Africa/Abidjan","America/Mendoza","America/Santarem","Kwajalein","America/Asuncion","Asia/Ulan_Bator","NZ","America/Boise","Australia/Currie","EST5EDT","Pacific/Guam","Pacific/Wake","Atlantic/Bermuda","America/Costa_Rica","America/Dawson","Asia/Chongqing","Eire","Europe/Amsterdam","America/Indiana/Knox","America/North_Dakota/Beulah","Africa/Accra","Atlantic/Faroe","Mexico/BajaNorte","America/Maceio","Etc/UCT","Pacific/Apia","GMT0","America/Atka","Pacific/Niue","Australia/Lord_Howe","Europe/Dublin","Pacific/Truk","MST7MDT","America/Monterrey","America/Nassau","America/Jamaica","Asia/Bishkek","America/Atikokan","Atlantic/Stanley","Australia/NSW","US/Hawaii","SystemV/CST6","Indian/Mahe","Asia/Aqtobe","America/Sitka","Asia/Vladivostok","Africa/Libreville","Africa/Maputo","Zulu","America/Kentucky/Monticello","Africa/El_Aaiun","Africa/Ouagadougou","America/Coral_Harbour","Pacific/Marquesas","Brazil/West","America/Aruba","America/North_Dakota/Center","America/Cayman","Asia/Ulaanbaatar","Asia/Baghdad","Europe/San_Marino","America/Indiana/Tell_City","America/Tijuana","Pacific/Saipan","SystemV/YST9","Africa/Douala","America/Chihuahua","America/Ojinaga","Asia/Hovd","America/Anchorage","Chile/EasterIsland","America/Halifax","Antarctica/Rothera","America/Indiana/Indianapolis","US/Mountain","Asia/Damascus","America/Argentina/San_Luis","America/Santiago","Asia/Baku","America/Argentina/Ushuaia","Atlantic/Reykjavik","Africa/Brazzaville","Africa/Porto-Novo","America/La_Paz","Antarctica/DumontDUrville","Asia/Taipei","Antarctica/South_Pole","Asia/Manila","Asia/Bangkok","Africa/Dar_es_Salaam","Poland","Atlantic/Madeira","Antarctica/Palmer","America/Thunder_Bay","Africa/Addis_Ababa","Asia/Yangon","Europe/Uzhgorod","Brazil/DeNoronha","Asia/Ashkhabad","Etc/Zulu","America/Indiana/Marengo","America/Creston","America/Punta_Arenas","America/Mexico_City","Antarctica/Vostok","Asia/Jerusalem","Europe/Andorra","US/Samoa","PRC","Asia/Vientiane","Pacific/Kiritimati","America/Matamoros","America/Blanc-Sablon","Asia/Riyadh","Iceland","Pacific/Pohnpei","Asia/Ujung_Pandang","Atlantic/South_Georgia","Europe/Lisbon","Asia/Harbin","Europe/Oslo","Asia/Novokuznetsk","CST6CDT","Atlantic/Canary","America/Knox_IN","Asia/Kuwait","SystemV/HST10","Pacific/Efate","Africa/Lome","America/Bogota","America/Menominee","America/Adak","Pacific/Norfolk","Europe/Kirov","America/Resolute","Pacific/Tarawa","Africa/Kampala","Asia/Krasnoyarsk","Greenwich","SystemV/EST5","America/Edmonton","Europe/Podgorica","Australia/South","Canada/Central","Africa/Bujumbura","America/Santo_Domingo","US/Eastern","Europe/Minsk","Pacific/Auckland","Africa/Casablanca","America/Glace_Bay","Canada/Eastern","Asia/Qatar","Europe/Kiev","Singapore","Asia/Magadan","SystemV/PST8","America/Port-au-Prince","Europe/Belfast","America/St_Barthelemy","Asia/Ashgabat","Africa/Luanda","America/Nipigon","Atlantic/Jan_Mayen","Brazil/Acre","Asia/Muscat","Asia/Bahrain","Europe/Vilnius","America/Fortaleza","Etc/GMT0","US/East-Indiana","America/Hermosillo","America/Cancun","Africa/Maseru","Pacific/Kosrae","Africa/Kinshasa","Asia/Kathmandu","Asia/Seoul","Australia/Sydney","America/Lima","Australia/LHI","America/St_Lucia","Europe/Madrid","America/Bahia_Banderas","America/Montserrat","Asia/Brunei","America/Santa_Isabel","Canada/Mountain","America/Cambridge_Bay","Asia/Colombo","Australia/West","Indian/Antananarivo","Australia/Brisbane","Indian/Mayotte","US/Indiana-Starke","Asia/Urumqi","US/Aleutian","Europe/Volgograd","America/Lower_Princes","America/Vancouver","Africa/Blantyre","America/Rio_Branco","America/Danmarkshavn","America/Detroit","America/Thule","Africa/Lusaka","Asia/Hong_Kong","Iran","America/Argentina/La_Rioja","Africa/Dakar","SystemV/CST6CDT","America/Tortola","America/Porto_Velho","Asia/Sakhalin","Etc/GMT+10","America/Scoresbysund","Asia/Kamchatka","Asia/Thimbu","Africa/Harare","Etc/GMT+12","Etc/GMT+11","Navajo","America/Nome","Europe/Tallinn","Turkey","Africa/Khartoum","Africa/Johannesburg","Africa/Bangui","Europe/Belgrade","Jamaica","Africa/Bissau","Asia/Tehran","WET","Europe/Astrakhan","Africa/Juba","America/Campo_Grande","America/Belem","Etc/Greenwich","Asia/Saigon","America/Ensenada","Pacific/Midway","America/Jujuy","Africa/Timbuktu","America/Bahia","America/Goose_Bay","America/Virgin","America/Pangnirtung","Asia/Katmandu","America/Phoenix","Africa/Niamey","America/Whitehorse","Pacific/Noumea","Asia/Tbilisi","America/Montreal","Asia/Makassar","America/Argentina/San_Juan","Hongkong","UCT","Asia/Nicosia","America/Indiana/Winamac","SystemV/MST7MDT","America/Argentina/ComodRivadavia","America/Boa_Vista","America/Grenada","Asia/Atyrau","Australia/Darwin","Asia/Khandyga","Asia/Kuala_Lumpur","Asia/Famagusta","Asia/Thimphu","Asia/Rangoon","Europe/Bratislava","Asia/Calcutta","America/Argentina/Tucuman","Asia/Kabul","Indian/Cocos","Japan","Pacific/Tongatapu","America/New_York","Etc/GMT-12","Etc/GMT-11","America/Nuuk","Etc/GMT-10","SystemV/YST9YDT","Europe/Ulyanovsk","Etc/GMT-14","Etc/GMT-13","W-SU","America/Merida","EET","America/Rosario","Canada/Saskatchewan","America/St_Kitts","Arctic/Longyearbyen","America/Fort_Nelson","America/Caracas","America/Guadeloupe","Asia/Hebron","Indian/Kerguelen","SystemV/PST8PDT","Africa/Monrovia","Asia/Ust-Nera","Egypt","Asia/Srednekolymsk","America/North_Dakota/New_Salem","Asia/Anadyr","Australia/Melbourne","Asia/Irkutsk","America/Shiprock","America/Winnipeg","Europe/Vatican","Asia/Amman","Etc/UTC","SystemV/AST4ADT","Asia/Tokyo","America/Toronto","Asia/Singapore","Australia/Lindeman","America/Los_Angeles","SystemV/EST5EDT","Pacific/Majuro","America/Argentina/Buenos_Aires","Europe/Nicosia","Pacific/Guadalcanal","Europe/Athens","US/Pacific","Europe/Monaco"]
- 获取系统默认时区
static ZoneId systemDefault() // 获取当前系统默认时区
- 指定时区
static Zoneld of(string zoneld) // 指定一个时区
如:
ZoneId.of("Asia/Shanghai")
ZoneId.of("Asia/Tokyo")
ZoneId.of("UTC+08")
ZoneId.of("UTC")
ZoneId.of("GMT")
获取当前UTC时间
import java.time.ZonedDateTime;
import java.time.ZoneOffset;
public class TimeExample {
public static void main(String[] args) {
// 获取当前UTC时间
ZonedDateTime utcNow = ZonedDateTime.now(ZoneOffset.UTC);// ZoneOffset.UTC or ZoneOffset.of("Asia/Shanghai") or ...
System.out.println("Current UTC Time: " + utcNow);//Current UTC Time: 2024-11-27T13:29:36.840Z
}
}
将本地时间转换为UTC时间
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class LocalToUTCTimeExample {
public static void main(String[] args) {
// 获取当前本地时间
LocalDateTime localNow = LocalDateTime.now();
// 将本地时间转换为UTC时间
ZonedDateTime utcTime = localNow.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC);
System.out.println("Local Time to UTC: " + utcTime);
}
}
时间字符串的解析(转为时间对象、转时间戳)
public static datetimeStrParse(){
final ZoneId ZONE_CST = ZoneId.of("Asia/Shanghai");
final DateTimeFormatter CST_PARSER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZONE_CST);
String dateTimeString = "2024-11-24 08:40:00";
ZonedDateTime dateTime = ZonedDateTime.parse(dateTimeString, CST_PARSER);
Long ts = dateTime.toInstant().toEpochMilli();//获取时间戳
System.out.println("ts: "+ ts + " dateTime: " + dateTime);//ts: 1732408800000 dateTime: 2024-11-24T08:40+08:00[Asia/Shanghai]
}
DateTimeFormatter#Pattern
的参数
- y:年份,例如"2022"
- M:月份,例如"01"
- d:天数,例如"01"
- H:小时(24小时制),例如"10"
- h:小时(12小时制),例如"10"或"10 PM"
- m:分钟数,例如"00"
- s:秒数,例如"00"
- S:毫秒数,例如"000"
- a:上午/下午标记,例如"AM"或"PM"
- E:星期几
- Z:时区
获取时间戳(毫秒级、纳秒级)
- 获取毫秒级时间戳
Long ts = System.currentTimeMillis();
//1733923968525
- 获取纳秒级时间戳 【不推荐使用】
- nanoTime返回的可能是任意时间,甚至可能是负数
Long ts = System.nanoTime();
//25793292985600
long startTime = System.nanoTime();
// 某个算法,例如:线性查找算法
long endTime = System.nanoTime();
double timeConsuming = (endTime - startTime) / 1000000000.0 // 将纳秒转换为秒
System.out.println(timeConsuming + "s");
- 扩展应用场景:纳秒数转毫秒级时间戳
/**
* 纳秒数转毫秒级时间戳
* @param targetNanoTime
* eg: long targetNanoTime = System.nanoTime(); // 获取当前时间的 nano time,例如 : 87277522042200
* @return
*/
public static long nanoTimeToMillisTimestamp(long targetNanoTime){
//待转换的纳秒时间(targetNanoTime)
//long targetNanoTime = System.nanoTime(); // 获取当前时间的 nano time,例如 : 87277522042200
//获取当前的毫秒数(currentTimeMillis) 和 纳秒数(currentNanoTime)
long currentTimeMillis = System.currentTimeMillis();//例如: 1733985453227
long currentNanoTime = System.nanoTime();//例如 : 87277522044200
//计算 currentNanoTime 与 targetNanoTime 的差值(nanoTimeDiff)
long nanoTimeDiff = currentNanoTime - targetNanoTime;//例如: 2000
// 利用 currentNanoTime 和 nanoTimeDiff ,向前推算出 targetNanoTime当时对应的毫秒级时间戳
long targetMillisTime = currentTimeMillis - ( nanoTimeDiff / 1000000L);//13位的毫秒级时间戳,例如: 1733985453227
//Date date = new Date(targetMillisTime); // 创建日期对象
//System.out.println("date : " + date.toString());//例如: date : Thu Dec 12 14:37:33 CST 2024
return targetMillisTime;
}
MYSQL 时间与时区概述
MYSQL 支持的时区
方式1:查看操作系统
在mysql文档中发现可用的时区都在
/usr/share/zoneinfo
目录下
lewis@lewis-dzwww:/usr/share/zoneinfo$ ll
总用量 308
drwxr-xr-x 21 root root 4096 5月 27 12:54 ./
drwxr-xr-x 334 root root 12288 6月 21 15:11 ../
drwxr-xr-x 2 root root 4096 5月 27 12:56 Africa/
drwxr-xr-x 6 root root 4096 5月 27 12:56 America/
drwxr-xr-x 2 root root 4096 5月 27 12:56 Antarctica/
drwxr-xr-x 2 root root 4096 5月 27 12:56 Arctic/
drwxr-xr-x 2 root root 4096 5月 27 12:56 Asia/
drwxr-xr-x 2 root root 4096 5月 27 12:56 Atlantic/
drwxr-xr-x 2 root root 4096 5月 27 12:56 Australia/
drwxr-xr-x 2 root root 4096 5月 27 12:56 Brazil/
drwxr-xr-x 2 root root 4096 5月 27 12:56 Canada/
-rw-r--r-- 1 root root 2102 4月 21 02:09 CET
drwxr-xr-x 2 root root 4096 5月 27 12:56 Chile/
-rw-r--r-- 1 root root 2294 4月 21 02:09 CST6CDT
-rw-r--r-- 1 root root 2437 4月 21 02:09 Cuba
-rw-r--r-- 1 root root 1876 4月 21 02:09 EET
-rw-r--r-- 1 root root 1972 4月 21 02:09 Egypt
-rw-r--r-- 1 root root 3559 4月 21 02:09 Eire
-rw-r--r-- 1 root root 127 4月 21 02:09 EST
-rw-r--r-- 1 root root 2294 4月 21 02:09 EST5EDT
drwxr-xr-x 2 root root 4096 5月 27 12:56 Etc/
drwxr-xr-x 2 root root 4096 5月 27 12:56 Europe/
-rw-r--r-- 1 root root 264 4月 21 02:09 Factory
-rw-r--r-- 1 root root 3687 4月 21 02:09 GB
lrwxrwxrwx 1 root root 2 5月 27 09:07 GB-Eire -> GB
-rw-r--r-- 1 root root 127 4月 21 02:09 GMT
lrwxrwxrwx 1 root root 3 5月 27 09:07 GMT0 -> GMT
lrwxrwxrwx 1 root root 3 5月 27 09:07 GMT-0 -> GMT
lrwxrwxrwx 1 root root 3 5月 27 09:07 GMT+0 -> GMT
lrwxrwxrwx 1 root root 3 5月 27 09:07 Greenwich -> GMT
-rw-r--r-- 1 root root 1189 4月 21 02:09 Hongkong
-rw-r--r-- 1 root root 128 4月 21 02:09 HST
-rw-r--r-- 1 root root 1190 4月 21 02:09 Iceland
drwxr-xr-x 2 root root 4096 5月 27 12:56 Indian/
-rw-r--r-- 1 root root 1678 4月 21 02:09 Iran
-rw-r--r-- 1 root root 4475 2月 24 17:01 iso3166.tab
-rw-r--r-- 1 root root 2265 4月 21 02:09 Israel
-rw-r--r-- 1 root root 507 4月 21 02:09 Jamaica
-rw-r--r-- 1 root root 355 4月 21 02:09 Japan
-rw-r--r-- 1 root root 237 4月 21 02:09 Kwajalein
-rw-r--r-- 1 root root 10384 2月 22 23:58 leap-seconds.list
-rw-r--r-- 1 root root 655 4月 21 02:09 Libya
lrwxrwxrwx 1 root root 14 5月 27 09:07 localtime -> /etc/localtime
-rw-r--r-- 1 root root 2102 4月 21 02:09 MET
drwxr-xr-x 2 root root 4096 5月 27 12:56 Mexico/
-rw-r--r-- 1 root root 127 4月 21 02:09 MST
-rw-r--r-- 1 root root 2294 4月 21 02:09 MST7MDT
-rw-r--r-- 1 root root 2453 4月 21 02:09 Navajo
-rw-r--r-- 1 root root 2460 4月 21 02:09 NZ
-rw-r--r-- 1 root root 2057 4月 21 02:09 NZ-CHAT
drwxr-xr-x 2 root root 4096 5月 27 12:56 Pacific/
-rw-r--r-- 1 root root 2705 4月 21 02:09 Poland
-rw-r--r-- 1 root root 3453 4月 21 02:09 Portugal
drwxr-xr-x 19 root root 4096 5月 27 12:56 posix/
-rw-r--r-- 1 root root 3545 4月 21 02:09 posixrules
-rw-r--r-- 1 root root 414 4月 21 02:09 PRC
-rw-r--r-- 1 root root 2294 4月 21 02:09 PST8PDT
drwxr-xr-x 19 root root 4096 5月 27 12:56 right/
-rw-r--r-- 1 root root 800 4月 21 02:09 ROC
-rw-r--r-- 1 root root 571 4月 21 02:09 ROK
-rw-r--r-- 1 root root 428 4月 21 02:09 Singapore
drwxr-xr-x 2 root root 4096 5月 27 12:56 SystemV/
-rw-r--r-- 1 root root 2747 4月 21 02:09 Turkey
-rw-r--r-- 1 root root 127 4月 21 02:09 UCT
lrwxrwxrwx 1 root root 4 5月 27 09:07 Universal -> Zulu
drwxr-xr-x 2 root root 4096 5月 27 12:56 US/
lrwxrwxrwx 1 root root 4 5月 27 09:07 UTC -> Zulu
-rw-r--r-- 1 root root 1873 4月 21 02:09 WET
-rw-r--r-- 1 root root 1528 4月 21 02:09 W-SU
-rw-r--r-- 1 root root 17533 4月 13 16:01 zone1970.tab
-rw-r--r-- 1 root root 19014 4月 13 16:01 zone.tab
-rw-r--r-- 1 root root 127 4月 21 02:09 Zulu
方式2: mysql.time_zone_name
表
> SELECT * FROM mysql.time_zone_name;
Name |Time_zone_id|
--------------------------------+------------+
Africa/Abidjan 37
Africa/Accra 159
Africa/Addis_Ababa 499
Africa/Algiers 230
Africa/Asmara 191
Africa/Asmera 590
Africa/Bamako 150
Africa/Bangui 256
Africa/Banjul 154
Africa/Bissau 26
Africa/Blantyre 329
Africa/Brazzaville 567
Africa/Bujumbura 94
Africa/Cairo 359
Africa/Casablanca 474
Africa/Ceuta 479
Africa/Conakry 216
Africa/Dakar 489
Africa/Dar_es_Salaam 353
Africa/Djibouti 449
Africa/Douala 368
Africa/Freetown 24
Africa/Gaborone 533
Africa/Harare 148
Africa/Johannesburg 455
Africa/Juba 49
Africa/Kampala 346
Africa/Khartoum 358
Africa/Kigali 564
Africa/Kinshasa 180
Africa/Lagos 574
Africa/Libreville 22
Africa/Lome 559
Africa/Luanda 356
Africa/Lubumbashi 269
Africa/Lusaka 204
Africa/Malabo 162
Africa/Maputo 524
Africa/Maseru 9
Africa/Mbabane 174
Africa/Mogadishu 492
Africa/Monrovia 480
Africa/Nairobi 145
Africa/Ndjamena 232
Africa/Niamey 471
Africa/Nouakchott 476
Africa/Ouagadougou 295
Africa/Porto-Novo 286
Africa/Sao_Tome 90
Africa/Timbuktu 363
Africa/Tripoli 304
Africa/Tunis 534
Africa/Windhoek 226
America/Adak 257
America/Anchorage 587
America/Anguilla 539
America/Antigua 258
America/Araguaina 32
America/Argentina/Buenos_Aires 52
America/Argentina/Catamarca 552
America/Argentina/ComodRivadavia 170
America/Argentina/Cordoba 225
America/Argentina/Jujuy 313
America/Argentina/La_Rioja 260
America/Argentina/Mendoza 578
America/Argentina/Rio_Gallegos 141
America/Argentina/Salta 320
America/Argentina/San_Juan 372
America/Argentina/San_Luis 58
America/Argentina/Tucuman 219
America/Argentina/Ushuaia 186
America/Aruba 67
America/Asuncion 429
America/Atikokan 11
America/Atka 21
America/Bahia 293
America/Bahia_Banderas 374
America/Barbados 547
America/Belem 89
America/Belize 160
America/Blanc-Sablon 405
America/Boa_Vista 385
America/Bogota 190
America/Boise 116
America/Buenos_Aires 6
America/Cambridge_Bay 355
America/Campo_Grande 462
America/Cancun 500
America/Caracas 195
America/Catamarca 137
America/Cayenne 488
America/Cayman 350
America/Chicago 194
America/Chihuahua 139
America/Coral_Harbour 23
America/Cordoba 365
America/Costa_Rica 239
America/Creston 319
America/Cuiaba 203
America/Curacao 354
America/Danmarkshavn 125
America/Dawson 498
America/Dawson_Creek 463
America/Denver 529
America/Detroit 332
America/Dominica 285
America/Edmonton 161
America/Eirunepe 127
America/El_Salvador 45
America/Ensenada 79
America/Fortaleza 491
America/Fort_Nelson 20
America/Fort_Wayne 123
America/Glace_Bay 531
America/Godthab 522
America/Goose_Bay 420
America/Grand_Turk 568
America/Grenada 336
America/Guadeloupe 117
America/Guatemala 88
America/Guayaquil 235
America/Guyana 439
America/Halifax 5
America/Havana 504
America/Hermosillo 233
America/Indiana/Indianapolis 259
America/Indiana/Knox 553
America/Indiana/Marengo 478
America/Indiana/Petersburg 338
America/Indiana/Tell_City 310
America/Indiana/Vevay 545
America/Indiana/Vincennes 337
America/Indiana/Winamac 361
America/Indianapolis 70
America/Inuvik 503
America/Iqaluit 523
America/Jamaica 411
America/Jujuy 364
America/Juneau 283
America/Kentucky/Louisville 290
America/Kentucky/Monticello 496
America/Knox_IN 484
America/Kralendijk 375
America/La_Paz 199
America/Lima 390
America/Los_Angeles 418
America/Louisville 106
America/Lower_Princes 446
America/Maceio 421
America/Managua 247
America/Manaus 131
America/Marigot 445
America/Martinique 40
America/Matamoros 217
America/Mazatlan 399
America/Mendoza 165
America/Menominee 238
America/Merida 86
America/Metlakatla 525
America/Mexico_City 78
America/Miquelon 15
America/Moncton 107
America/Monterrey 589
America/Montevideo 333
America/Montreal 289
America/Montserrat 322
America/Nassau 119
America/New_York 276
America/Nipigon 12
America/Nome 571
America/Noronha 228
America/North_Dakota/Beulah 138
America/North_Dakota/Center 542
America/North_Dakota/New_Salem 518
America/Nuuk 234
America/Ojinaga 520
America/Panama 231
America/Pangnirtung 250
America/Paramaribo 266
America/Phoenix 202
America/Port-au-Prince 348
America/Porto_Acre 113
America/Porto_Velho 475
America/Port_of_Spain 301
America/Puerto_Rico 80
America/Punta_Arenas 423
America/Rainy_River 344
America/Rankin_Inlet 132
America/Recife 193
America/Regina 71
America/Resolute 543
America/Rio_Branco 129
America/Rosario 464
America/Santarem 114
America/Santa_Isabel 18
America/Santiago 51
America/Santo_Domingo 408
America/Sao_Paulo 441
America/Scoresbysund 126
America/Shiprock 334
America/Sitka 431
America/St_Barthelemy 108
America/St_Johns 585
America/St_Kitts 227
America/St_Lucia 28
America/St_Thomas 394
America/St_Vincent 210
America/Swift_Current 318
America/Tegucigalpa 112
America/Thule 105
America/Thunder_Bay 413
America/Tijuana 556
America/Toronto 291
America/Tortola 582
America/Vancouver 144
America/Virgin 299
America/Whitehorse 314
America/Winnipeg 483
America/Yakutat 573
America/Yellowknife 209
Antarctica/Casey 102
Antarctica/Davis 93
Antarctica/DumontDUrville 551
Antarctica/Macquarie 509
Antarctica/Mawson 2
Antarctica/McMurdo 109
Antarctica/Palmer 452
Antarctica/Rothera 60
Antarctica/South_Pole 297
Antarctica/Syowa 409
Antarctica/Troll 461
Antarctica/Vostok 468
Arctic/Longyearbyen 56
Asia/Aden 176
Asia/Almaty 554
Asia/Amman 422
Asia/Anadyr 275
Asia/Aqtau 155
Asia/Aqtobe 486
Asia/Ashgabat 527
Asia/Ashkhabad 481
Asia/Atyrau 64
Asia/Baghdad 218
Asia/Bahrain 526
Asia/Baku 437
Asia/Bangkok 465
Asia/Barnaul 442
Asia/Beijing 31
Asia/Beirut 140
Asia/Bishkek 316
Asia/Brunei 550
Asia/Calcutta 309
Asia/Chita 220
Asia/Choibalsan 404
Asia/Chongqing 224
Asia/Chungking 187
Asia/Colombo 347
Asia/Dacca 448
Asia/Damascus 540
Asia/Dhaka 27
Asia/Dili 173
Asia/Dubai 341
Asia/Dushanbe 252
Asia/Famagusta 163
Asia/Gaza 548
Asia/Harbin 370
Asia/Hebron 223
Asia/Hong_Kong 55
Asia/Hovd 124
Asia/Ho_Chi_Minh 146
Asia/Irkutsk 466
Asia/Istanbul 398
Asia/Jakarta 450
Asia/Jayapura 243
Asia/Jerusalem 516
Asia/Kabul 264
Asia/Kamchatka 240
Asia/Karachi 157
Asia/Kashgar 39
Asia/Kathmandu 340
Asia/Katmandu 433
Asia/Khandyga 74
Asia/Kolkata 8
Asia/Krasnoyarsk 41
Asia/Kuala_Lumpur 236
Asia/Kuching 43
Asia/Kuwait 214
Asia/Macao 560
Asia/Magadan 97
Asia/Makassar 430
Asia/Manila 362
Asia/Muscat 298
Asia/Nicosia 253
Asia/Novokuznetsk 151
Asia/Novosibirsk 561
Asia/Omsk 254
Asia/Oral 175
Asia/Phnom_Penh 246
Asia/Pontianak 328
Asia/Pyongyang 339
Asia/Qatar 248
Asia/Qostanay 415
Asia/Qyzylorda 513
Asia/Rangoon 360
Asia/Riyadh 75
Asia/Saigon 103
Asia/Sakhalin 424
Asia/Samarkand 287
Asia/Seoul 570
Asia/Shanghai 130
Asia/Singapore 321
Asia/Srednekolymsk 395
Asia/Taipei 490
Asia/Tashkent 323
Asia/Tbilisi 366
Asia/Tehran 565
Asia/Tel_Aviv 460
Asia/Thimbu 327
Asia/Thimphu 158
Asia/Tokyo 400
Asia/Tomsk 91
Asia/Ujung_Pandang 100
Asia/Ulaanbaatar 343
Asia/Ulan_Bator 249
Asia/Urumqi 335
Asia/Ust-Nera 537
Asia/Vientiane 212
Asia/Vladivostok 538
Asia/Yakutsk 427
Asia/Yangon 82
Asia/Yekaterinburg 98
Asia/Yerevan 198
Atlantic/Azores 515
Atlantic/Bermuda 99
Atlantic/Canary 1
Atlantic/Cape_Verde 111
Atlantic/Faeroe 237
Atlantic/Faroe 485
Atlantic/Jan_Mayen 192
Atlantic/Madeira 172
Atlantic/Reykjavik 432
Atlantic/South_Georgia 456
Atlantic/Stanley 393
Atlantic/St_Helena 546
Australia/ACT 470
Australia/Adelaide 351
Australia/Brisbane 506
Australia/Broken_Hill 200
Australia/Canberra 566
Australia/Currie 101
Australia/Darwin 312
Australia/Eucla 519
Australia/Hobart 281
Australia/LHI 211
Australia/Lindeman 184
Australia/Lord_Howe 371
Australia/Melbourne 7
Australia/North 473
Australia/NSW 121
Australia/Perth 447
Australia/Queensland 555
Australia/South 311
Australia/Sydney 169
Australia/Tasmania 378
Australia/Victoria 153
Australia/West 406
Australia/Yancowinna 444
Brazil/Acre 296
Brazil/DeNoronha 245
Brazil/East 376
Brazil/West 407
Canada/Atlantic 511
Canada/Central 572
Canada/Eastern 417
Canada/Mountain 349
Canada/Newfoundland 17
Canada/Pacific 128
Canada/Saskatchewan 135
Canada/Yukon 507
CET 396
Chile/Continental 458
Chile/EasterIsland 68
CST6CDT 279
Cuba 389
EET 369
Egypt 580
Eire 386
EST 562
EST5EDT 453
Etc/GMT 280
Etc/GMT+0 50
Etc/GMT+1 10
Etc/GMT+10 435
Etc/GMT+11 434
Etc/GMT+12 401
Etc/GMT+2 44
Etc/GMT+3 38
Etc/GMT+4 65
Etc/GMT+5 14
Etc/GMT+6 13
Etc/GMT+7 54
Etc/GMT+8 4
Etc/GMT+9 3
Etc/GMT-0 535
Etc/GMT-1 377
Etc/GMT-10 268
Etc/GMT-11 267
Etc/GMT-12 270
Etc/GMT-13 403
Etc/GMT-14 271
Etc/GMT-2 380
Etc/GMT-3 379
Etc/GMT-4 382
Etc/GMT-5 381
Etc/GMT-6 384
Etc/GMT-7 383
Etc/GMT-8 373
Etc/GMT-9 505
Etc/GMT0 262
Etc/Greenwich 136
Etc/UCT 133
Etc/Universal 352
Etc/UTC 583
Etc/Zulu 528
Europe/Amsterdam 29
Europe/Andorra 387
Europe/Astrakhan 288
Europe/Athens 345
Europe/Belfast 282
Europe/Belgrade 402
Europe/Berlin 85
Europe/Bratislava 274
Europe/Brussels 53
Europe/Bucharest 428
Europe/Budapest 416
Europe/Busingen 147
Europe/Chisinau 95
Europe/Copenhagen 118
Europe/Dublin 414
Europe/Gibraltar 367
Europe/Guernsey 57
Europe/Helsinki 581
Europe/Isle_of_Man 177
Europe/Istanbul 221
Europe/Jersey 87
Europe/Kaliningrad 397
Europe/Kiev 412
Europe/Kirov 201
Europe/Lisbon 215
Europe/Ljubljana 242
Europe/London 292
Europe/Luxembourg 255
Europe/Madrid 48
Europe/Malta 182
Europe/Mariehamn 179
Europe/Minsk 47
Europe/Monaco 477
Europe/Moscow 30
Europe/Nicosia 557
Europe/Oslo 110
Europe/Paris 300
Europe/Podgorica 229
Europe/Prague 120
Europe/Riga 171
Europe/Rome 482
Europe/Samara 265
Europe/San_Marino 514
Europe/Sarajevo 467
Europe/Saratov 35
Europe/Simferopol 326
Europe/Skopje 588
Europe/Sofia 577
Europe/Stockholm 61
Europe/Tallinn 307
Europe/Tirane 42
Europe/Tiraspol 143
Europe/Ulyanovsk 241
Europe/Uzhgorod 152
Europe/Vaduz 584
Europe/Vatican 325
Europe/Vienna 451
Europe/Vilnius 487
Europe/Volgograd 149
Europe/Warsaw 96
Europe/Zagreb 166
Europe/Zaporozhye 181
Europe/Zurich 510
GB 59
GB-Eire 134
GMT 46
GMT+0 213
GMT-0 575
GMT0 178
Greenwich 164
Hongkong 303
HST 197
Iceland 222
Indian/Antananarivo 426
Indian/Chagos 530
Indian/Christmas 208
Indian/Cocos 115
Indian/Comoro 586
Indian/Kerguelen 357
Indian/Mahe 308
Indian/Maldives 294
Indian/Mauritius 81
Indian/Mayotte 244
Indian/Reunion 392
Iran 457
Jamaica 342
Japan 438
Kwajalein 443
Libya 122
MET 517
Mexico/BajaNorte 563
Mexico/BajaSur 569
Mexico/General 278
MST 196
MST7MDT 330
Navajo 69
NZ 493
NZ-CHAT 251
Pacific/Apia 63
Pacific/Auckland 410
Pacific/Bougainville 532
Pacific/Chatham 168
Pacific/Chuuk 73
Pacific/Easter 331
Pacific/Efate 501
Pacific/Enderbury 104
Pacific/Fakaofo 83
Pacific/Fiji 62
Pacific/Funafuti 76
Pacific/Galapagos 188
Pacific/Gambier 502
Pacific/Guadalcanal 206
Pacific/Guam 508
Pacific/Honolulu 391
Pacific/Johnston 36
Pacific/Kiritimati 536
Pacific/Kosrae 472
Pacific/Kwajalein 541
Pacific/Majuro 34
Pacific/Marquesas 272
Pacific/Midway 419
Pacific/Nauru 591
Pacific/Niue 189
Pacific/Norfolk 277
Pacific/Noumea 459
Pacific/Pago_Pago 66
Pacific/Palau 156
Pacific/Pitcairn 315
Pacific/Pohnpei 440
Pacific/Ponape 436
Pacific/Port_Moresby 92
Pacific/Rarotonga 284
Pacific/Saipan 33
Pacific/Samoa 425
Pacific/Tahiti 261
Pacific/Tarawa 497
Pacific/Tongatapu 306
Pacific/Truk 72
Pacific/Wake 302
Pacific/Wallis 19
Pacific/Yap 16
Poland 558
Portugal 142
PRC 324
PST8PDT 167
ROK 388
Singapore 25
Turkey 183
UCT 544
Universal 84
US/Alaska 521
US/Aleutian 469
US/Arizona 512
US/Central 273
US/East-Indiana 454
US/Eastern 494
US/Hawaii 576
US/Indiana-Starke 205
US/Michigan 549
US/Mountain 77
US/Pacific 207
US/Pacific-New 317
US/Samoa 185
UTC 263
W-SU 495
WET 305
Zulu 579
数据库变量
- 查询时区配置
> show variables like '%time_zone%';
Variable_name |Value |
----------------+------+
system_time_zone|+08 |
time_zone |SYSTEM|
> SELECT @@GLOBAL.system_time_zone, @@GLOBAL.time_zone, @@SESSION.time_zone;
@@GLOBAL.system_time_zone|@@GLOBAL.time_zone|@@SESSION.time_zone|
-------------------------+------------------+-------------------+
+08 |SYSTEM |+00:00 |
system_time_zone
- 定义:
system_time_zone
是 MySQL 服务器的系统时区,即操作系统的本地时区。
这个变量反映了操作系统当前设置的时区名称,例如 UTC, CST, PST 等。
- 特点:
只读变量:
system_time_zone
是只读的,你不能在 MySQL 中直接修改它。
设置时间:该变量的值是在 MySQL 服务器启动时从操作系统中获取的,并且在服务器运行期间不会改变。
用途:主要用于初始化time_zone
变量的默认值。
- 查看方式
SELECT @@system_time_zone; -- SELECT @@GLOBAL.system_time_zone
或
SHOW VARIABLES LIKE '%time_zone%'
time_zone
- 定义:
time_zone
是MySQL
中会话级别和全局级别的【时区设置】,控制MySQL
如何将时间存储在TIMESTAMP
类型字段中,以及如何将其展示给用户。
- 特点
可修改:
time_zone
可以根据需要在全局或会话级别设置。全局时区设置影响所有连接,而会话时区设置仅影响当前连接。
默认值:在服务器启动时,time_zone 默认初始化为system_time_zone
的值,除非你在配置文件(my.cnf 或 my.ini)中显式设置了它。
会话级别控制:在一个连接中,你可以使用SET time_zone
命令来设置当前会话的时区。
time_zone
变量的值如果是SYSTEM
表示什么?
表示跟
system_time_zone
取值一样。
安装MySQL后,默认就是SYSTEM
。
- 变量值的设置:最佳实践
- 不建议设置为
SYSTEM
。避免受制于操作系统修改时区产生的影响,尽量减小风险。- 不建议设置为
CST
。避免4个同名时区,产生歧义的问题。
- 与
system_time_zone
数据库变量的关系
- 启动与初始化时:
当 MySQL 启动时,
system_time_zone
反映操作系统的时区设置,time_zone
则初始化为与system_time_zone
相同的值,除非在配置文件中设置了其他值。
- 系统与应用结合:
system_time_zone
通常是固定的、仅可读的,由操作系统控制,适合服务器级别的操作。
time_zone
则更多用于应用程序级别的操作、可修改的,允许在不同会话或用户之间使用不同的时区来处理时间数据。
- 时间操作与显示:
当你插入
TIMESTAMP
类型的数据时,MySQL 会将其转换为UTC
存储,并根据当前的time_zone
来显示它。
使用time_zone
可以灵活地在不同的时区间转换时间数据,适应全球化应用的需求。
- 要知道
mysql
当前在什么时区,看哪个变量?
看
time_zone
。不看system_time_zone
。
如要修改时区,直接修改time_zone
,无视system_time_zone
- 查看(会话级、全局级)时区
> SELECT @@session.time_zone, @@global.time_zone;
@@session.time_zone|@@global.time_zone|
-------------------+------------------+
SYSTEM |SYSTEM |
- 支持全局修改
-- SQL 错误 [1227] [42000]: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
set global time_zone = '+00:00'; -- or '+8:00' or 'Asia/Shanghai' -- 全局级
修改后(UTC+8 => UTC+0),会话未重连数据库时
> SELECT @@session.time_zone, @@global.time_zone;
mysql> SELECT @@session.time_zone, @@global.time_zone;
+---------------------+--------------------+
| @@session.time_zone | @@global.time_zone |
+---------------------+--------------------+
| +08:00 | +00:00 |
+---------------------+--------------------+
1 row in set (0.00 sec)
即 修改后,mysql session(会话) 需要重连,才会生效。
> SELECT TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()));
28800
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | |
| time_zone | +08:00 |
+------------------+--------+
2 rows in set, 1 warning (0.00 sec)
mysql> select id,createTime,unix_timestamp(createTime) as cs1,updateTime,createTimeTs, unix_timestamp(createTimeTs) as ts2 from xxx_db.tc_dimdevice;
+----+-------------------------+----------------+----------------------------+---------------------+------------+
| id | createTime | cs1 | updateTime | createTimeTs | ts2 |
+----+-------------------------+----------------+----------------------------+---------------------+------------+
| 38 | 2024-01-31 17:56:43.717 | 1706695003.717 | 2024-01-31 17:56:43.717000 | 2024-01-31 17:56:44 | 1706695004 |
+----+-------------------------+----------------+----------------------------+---------------------+------------+
1 row in set (0.00 sec)
修改后,新建会话
mysql> SELECT @@session.time_zone, @@global.time_zone;
+---------------------+--------------------+
| @@session.time_zone | @@global.time_zone |
+---------------------+--------------------+
| +00:00 | +00:00 |
+---------------------+--------------------+
1 row in set (0.00 sec)
mysql> SELECT TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()));
+-----------------------------------------------+
| TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP())) |
+-----------------------------------------------+
| 0 |
+-----------------------------------------------+
1 row in set (0.00 sec)
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | |
| time_zone | +00:00 |
+------------------+--------+
2 rows in set, 1 warning (0.01 sec)
mysql> select id,createTime,unix_timestamp(createTime) as cs1,updateTime,createTimeTs, unix_timestamp(createTimeTs) as ts2 from xxx_db.tc_dimdevice;
+----+-------------------------+----------------+----------------------------+---------------------+------------+
| id | createTime | cs1 | updateTime | createTimeTs | ts2 |
+----+-------------------------+----------------+----------------------------+---------------------+------------+
| 38 | 2024-01-31 17:56:43.717 | 1706723803.717 | 2024-01-31 17:56:43.717000 | 2024-01-31 09:56:44 | 1706695004 |
+----+-------------------------+----------------+----------------------------+---------------------+------------+
1 row in set (0.00 sec)
注: createTime[datetime(3)类型] : 未发生改变,根因:其底层是字符串,不受 mysql.time_zone / jdbc.serverTimeZone 控制
注: unix_timestamp(createTime) : 以 (createTime , utc+0) 转时间戳 (发生了改变)
注: createTimeTs[timestamp类型] : 发生改变,因: 受 mysql.time_zone / jdbc.serverTimeZone 控制
注: unix_timestamp(createTimeTs) : 未发生改变,以 (createTimeTs , 本记录本列入库时的 utc+8 时区) 转时间戳
- 支持会话级修改
set time_zone = 'SYSTEM'; -- '+00:00' / '+08:00' / 'Asia/Shanghai'
配置项
default-time-zone
: 影响 system_time_zone / time_zone 的时区设置
- mysql的配置文件
my.ini
[mysqld]
#default-time-zone = '+00:00' | 配置项值1
#default-time-zone = '+8:00' | 配置项值2
# default-time-zone = 'Asia/Shanghai' | 配置项值3
- 当不配置
default-time-zone
时:
case1 : 设置mysql所在操作系统的系统时区为 东八区,且重启mysql后:
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | |
| time_zone | SYSTEM |
+------------------+--------+
mysql> SELECT TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()))
-- 28800
case2 : 设置mysql所在操作系统的系统时区为 0时区,且不重启mysql时:
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | |
| time_zone | SYSTEM |
+------------------+--------+
mysql> SELECT TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()))
-- 28800
case3 : 设置mysql所在操作系统的系统时区为 0时区,且重启mysql后:
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | |
| time_zone | SYSTEM |
+------------------+--------+
mysql> SELECT TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()))
-- 0
- 当配置
default-time-zone
为+00:00
时:
mysql> SELECT TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()));
+-----------------------------------------------+
| TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP())) |
+-----------------------------------------------+
| 0 |
+-----------------------------------------------+
1 row in set (0.00 sec)
- 当配置
default-time-zone
为+08:00
时:
- mysql所在操作系统(windows 10)的系统时区为 0时区时
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | GMT |
| time_zone | +08:00 |
+------------------+--------+
2 rows in set, 1 warning (0.01 sec)
mysql> SELECT TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()));
+-----------------------------------------------+
| TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP())) |
+-----------------------------------------------+
| 28800 |
+-----------------------------------------------+
1 row in set (0.00 sec)
- mysql所在操作系统(windows 10)的系统时区为 东八区时区(北京,重庆,乌鲁木齐,香港)时
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | |
| time_zone | +08:00 |
+------------------+--------+
2 rows in set, 1 warning (0.00 sec)
mysql> SELECT TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()));
+-----------------------------------------------+
| TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP())) |
+-----------------------------------------------+
| 28800 |
+-----------------------------------------------+
1 row in set (0.00 sec)
JDBC URL时间时区参数: serverTimeZone
/useJDBCCompliantTimezoneShift
/useLegacyDatetimeCode
serverTimeZone
参数的作用:
- 用于指定服务器的时区,从而影响MySQL如何解释和处理时间和日期数据。通过设置不同的时区,可以确保存储和查询的时间数据符合用户的本地时区要求
- 影响 mysql
timestamp
类型字段的查询结果- 不影响 mysql
datetime
类型字段的查询结果 (从实验来看)- ...
- demo
jdbc:mysql://172.xx.xx.xx:3306/test_db?serverTimezone=UTC&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&useUnicode=true&characterEncoding=gbk&useSSL=true
jdbc.url=jdbc:mysql://localhost:3306/demo?serverTimezone=UTC&characterEncoding=utf-8
jdbc.url=jdbc:mysql://localhost:3306/demo?serverTimezone=GMT%2B8&characterEncoding=utf-8
注:%2B 即 `+`
函数
FROM_UNIXTIME(...)
: 受 time_zone
变量的影响
> set time_zone = '+08:00';
> select FROM_UNIXTIME(1617181920)
FROM_UNIXTIME(1617181920)|
-------------------------+
2021-03-31 17:12:00|
> set time_zone = '+00:00';
> select FROM_UNIXTIME(1617181920)
FROM_UNIXTIME(1617181920)|
-------------------------+
2021-03-31 17:12:00|
FROM_UNIXTIME(1617181920)|
-------------------------+
2021-03-31 09:12:00|
UNIX_TIMESTAMP(dateTimeStr|date)
: 受 time_zone 变量影响
mysql> set time_zone='+08:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT UNIX_TIMESTAMP('2021-12-31 23:59:59') AS timestamp;
+------------+
| timestamp |
+------------+
| 1640966399 |
+------------+
1 row in set (0.00 sec)
mysql> set time_zone='+07:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT UNIX_TIMESTAMP('2021-12-31 23:59:59') AS timestamp;
+------------+
| timestamp |
+------------+
| 1640969999 |
+------------+
1 row in set (0.00 sec)
STR_TO_DATE(dateTimeStr)
: 受 time_zone 影响
mysql> set time_zone='+08:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT STR_TO_DATE('2021-12-31 23:59:59', '%Y-%m-%d %H:%i:%s') AS dt;
+---------------------+
| dt |
+---------------------+
| 2021-12-31 23:59:59 |
+---------------------+
1 row in set (0.00 sec)
mysql> SELECT UNIX_TIMESTAMP(STR_TO_DATE('2021-12-31 23:59:59', '%Y-%m-%d %H:%i:%s')) AS timestamp;
+------------+
| timestamp |
+------------+
| 1640966399 |
+------------+
1 row in set (0.00 sec)
mysql> set time_zone='+07:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT STR_TO_DATE('2021-12-31 23:59:59', '%Y-%m-%d %H:%i:%s') AS dt;
+---------------------+
| dt |
+---------------------+
| 2021-12-31 23:59:59 |
+---------------------+
1 row in set (0.00 sec)
mysql> SELECT UNIX_TIMESTAMP(STR_TO_DATE('2021-12-31 23:59:59', '%Y-%m-%d %H:%i:%s')) AS timestamp;
+------------+
| timestamp |
+------------+
| 1640969999 |
+------------+
1 row in set (0.00 sec)
TIMESTAMP(dateTimeStr)
: 受 time_zone 影响
mysql> set time_zone='+08:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT TIMESTAMP('2021-12-31 23:59:59') AS timestamp;
+---------------------+
| timestamp |
+---------------------+
| 2021-12-31 23:59:59 |
+---------------------+
1 row in set (0.00 sec)
mysql> SELECT UNIX_TIMESTAMP( TIMESTAMP('2021-12-31 23:59:59') ) AS ts;
+------------+
| ts |
+------------+
| 1640966399 |
+------------+
1 row in set (0.00 sec)
mysql> set time_zone='+07:00';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT TIMESTAMP('2021-12-31 23:59:59') AS timestamp;
+---------------------+
| timestamp |
+---------------------+
| 2021-12-31 23:59:59 |
+---------------------+
1 row in set (0.00 sec)
mysql> SELECT UNIX_TIMESTAMP( TIMESTAMP('2021-12-31 23:59:59') ) AS ts;
+------------+
| ts |
+------------+
| 1640969999 |
+------------+
1 row in set (0.00 sec)
CAST(dateTimeStr as datetime|date)
: 受 time_zone 影响
mysql> set time_zone='+07:00';
Query OK, 0 rows affected (0.00 sec)
mysql> select CAST('2021-12-31 23:59:59' AS DATETIME) as dt;
+---------------------+
| dt |
+---------------------+
| 2021-12-31 23:59:59 |
+---------------------+
1 row in set (0.00 sec)
mysql> SELECT UNIX_TIMESTAMP( CAST('2021-12-31 23:59:59' AS DATETIME)) AS ts;
+------------+
| ts |
+------------+
| 1640969999 |
+------------+
1 row in set (0.00 sec)
mysql> set time_zone='+08:00';
Query OK, 0 rows affected (0.00 sec)
mysql> select CAST('2021-12-31 23:59:59' AS DATETIME) as dt;
+---------------------+
| dt |
+---------------------+
| 2021-12-31 23:59:59 |
+---------------------+
1 row in set (0.00 sec)
mysql> SELECT UNIX_TIMESTAMP( CAST('2021-12-31 23:59:59' AS DATETIME)) AS ts;
+------------+
| ts |
+------------+
| 1640966399 |
+------------+
1 row in set (0.00 sec)
CURTIME()
: 受 time_zone
变量的影响
> set time_zone = '+00:00';
> select CURTIME();
CURTIME()|
---------+
12:29:58|
经试验,等效于 system_time_zone=+00 / time_zone=SYSTEM
> set time_zone = '+08:00';
> select CURTIME();
CURTIME()|
---------+
20:29:58|
NOW()
: 受 time_zone 变量影响
mysql> set time_zone='+07:00';
Query OK, 0 rows affected (0.00 sec)
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2024-11-28 10:06:19 |
+---------------------+
1 row in set (0.00 sec)
mysql> set time_zone='+08:00';
Query OK, 0 rows affected (0.00 sec)
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2024-11-28 11:06:40 |
+---------------------+
1 row in set (0.00 sec)
表字段
timestamp 类型
- 定义与特性
TIMESTAMP类型的定义方式为
TIMESTAMP[(fsp)]
,fsp
表示小数位数,范围为0到6,默认值为0。TIMESTAMP类型的特性包括:
可以存储从’1970-01-01 00:00:01’到’2038-01-19 03:14:07’之间的日期和时间。
默认精确到秒级。
占用4个字节的存储空间。
- 存储方式:底层为整数
TIMESTAMP类型的存储方式是通过将日期和时间信息转换成一个整数值,然后存储在4个字节的整数中。
- 使用场景
TIMESTAMP类型适用于需要存储精确到秒级的日期和时间信息的场景,例如存储记录的最后修改时间、日志的时间戳等。
- 限制与问题
由于TIMESTAMP类型的范围较小,只能存储到
2038
年,所以在一些需要存储更远未来时间的场景下可能不适用。
此外,TIMESTAMP类型会受到时区设置的影响,在不同的时区下可能出现时间偏移的问题。
timestamp
数据类型 : 底层是 Long + 时区
本类型的字段存储的数据受时区配置(
time_zone
变量或serverTimeZone
jdbc参数等)影响
timestamp
数据类型会存储当时session
的时区信息,读取时会根据当前 session 的时区进行转换;
- 其他补充
TIMESTAMP 的一些设计却非常鬼畜,比如:
- 如果表中包含 TIMESTAMP 的列,那么其建表语句有可能被系统篡改,取决于 MySql 的版本和参数设置。
- 当 MySQL 参数 time_zone=system 时,高并发可能会引起 CPU 使用率暴涨,系统响应变慢甚至假死
- 如果存入超过范围的时间,在非严格状态下,MySql 不会报错,反而会插入'0000-00-00 00:00:00'
datetime 类型
- 简介
而
datetime
数据类型插入的是什么值,再读取就是什么值,不受时区影响。
也可以理解为已存储的数据是不会变的、尤其是不会受时区设置而改变,只是timestamp
类型数据在读取时会根据时区转换:
- 定义与特性
DATETIME类型的定义方式为
DATETIME[(fsp)]
,fsp
表示小数位数,范围为0到6,默认值为0。DATETIME类型的特性包括:
可以存储从’1000-01-01 00:00:00’到’9999-12-31 23:59:59’之间的日期和时间。
默认精确到秒级。
占用8
个字节的存储空间。
- 存储方式:底层为字符串
DATETIME
类型的存储方式是通过将日期和时间信息分别存储在一个8字节的整数和一个3字节的整数中,然后将它们合并成一个8字节的二进制字符串。
- 使用场景
DATETIME
类型适用于需要存储精确到秒级的日期和时间信息的场景,例如存储订单创建时间、用户注册时间等。
- 限制与问题
由于DATETIME类型的范围较大,存储空间较大,所以在一些特定场景下可能会出现性能问题。
此外,DATETIME类型没有时区信息,可能在跨时区的应用中引发问题————需要针对用户请求做时区转换。
小结
-
datetime 类型数据(底层存储:字符串),不受时区设置(time_zone 变量/ jdbc参数:serverTimeZone)影响
-
timestamp 类型数据(底层存储:整型 + 入库时区)、unix_timestamp/now/计算时间的各类函数,不受时区设置(time_zone 变量/ jdbc参数:serverTimeZone)影响
FAQ
Q: 查看MYSQL数据库的时区偏移量
-- 方式1 : 不推荐
---- 推荐文档: https://dev.mysql.com/doc/refman/8.4/en/mysql-tzinfo-to-sql.html
SELECT (unix_timestamp() - unix_timestamp(convert_tz(now(), 'Etc/UTC', 'America/Vancouver'))) / 3600 as offset;
-- 8.0000
-- 方式2 : 推荐 | from flink 源码 : https://github.com/apache/flink-cdc/blob/release-2.3.0/flink-connector-mysql-cdc/src/main/java/com/ververica/cdc/connectors/mysql/MySqlValidator.java#checkTimeZone
-- 推荐文档 : https://www.cnblogs.com/johnnyzen/p/18500390
SELECT TIME_TO_SEC(TIMEDIFF(NOW(), UTC_TIMESTAMP()))
-- 28800
Q: 修改tim_zone
对MYSQL已入库的历史数据的影响?
假定:修改
time_zone
前为MYSQL老时区,修改time_zone
后为MYSQL新时区。
- 对
datetime
类型的字段:
- 历史数据先前的落库:
因mysql
datetime
类型底层本质是字符串,落库后即存储的字符串。
- 修改新时区后的历史数据存储:
已存储的数据,不会发生改变。
- 修改新时区后的查询:
Query SQL 直查目标字段,而不使用受
time_zone
变量影响的函数时,历史数据的查询无变化(如下列案例中的select update_time
)
- 对
timestamp
类型的字段:
- 历史数据先前的落库:
入库方式1:
INSERT INTO test.test_table (timestamp_column) values ('2024-11-27 20:16:00'); -- 时间字符串类型入库
入库方式2:INSERT INTO test.test_table (timestamp_column) values ( now() ); -- 时间戳类型入库
不论是何种入库方式,本质上在当时都利用了MYSQL老时区来转换为时间戳
- 修改新时区后的历史数据存储:
已存储的数据,不会发生改变。
- 修改新时区后的查询:
Query SQL 直查目标字段,即使使用或不使用受
time_zone
变量影响的函数时,历史数据的查询都有变化:查询结果将随着time_zone
设置的时区而随之改变,实属正常(如下列案例中的select version
)
- 案例
update_time
:datetime(3)
类型
version
:timestamp
类型
mysql> set time_zone='+08:00';
Query OK, 0 rows affected (0.00 sec)
mysql> select id, uuid, username, update_time,UNIX_TIMESTAMP(update_time) as update_time_ts, version,UNIX_TIMESTAMP(version) as version_ts, UNIX_TIMESTAMP('2021-12-31 23:59:59') as ts from `test`.`tb_user`;
+----+--------------------------------------+----------+-------------------------+----------------+---------------------+------------+------------+
| id | uuid | username | update_time | update_time_ts | version | version_ts | ts |
+----+--------------------------------------+----------+-------------------------+----------------+---------------------+------------+------------+
| 36 | 8213572d-f5df-4127-aadd-bf0083c26da1 | jack | 2024-11-01 09:00:00.179 | 1730422800.179 | 2024-11-28 11:50:48 | 1732765848 | 1640966399 |
| 37 | 8213572d-f5df-4127-aadd-bf0083c26da2 | jane | 2024-11-01 09:05:00.179 | 1730423100.179 | 2024-11-01 09:05:00 | 1730423100 | 1640966399 |
+----+--------------------------------------+----------+-------------------------+----------------+---------------------+------------+------------+
2 rows in set (0.00 sec)
mysql> set time_zone='+07:00';
Query OK, 0 rows affected (0.00 sec)
mysql> select id, uuid, username, update_time,UNIX_TIMESTAMP(update_time) as update_time_ts, version,UNIX_TIMESTAMP(version) as version_ts, UNIX_TIMESTAMP('2021-12-31 23:59:59') as ts from `test`.`tb_user`;
+----+--------------------------------------+----------+-------------------------+----------------+---------------------+------------+------------+
| id | uuid | username | update_time | update_time_ts | version | version_ts | ts |
+----+--------------------------------------+----------+-------------------------+----------------+---------------------+------------+------------+
| 36 | 8213572d-f5df-4127-aadd-bf0083c26da1 | jack | 2024-11-01 09:00:00.179 | 1730426400.179 | 2024-11-28 10:50:48 | 1732765848 | 1640969999 |
| 37 | 8213572d-f5df-4127-aadd-bf0083c26da2 | jane | 2024-11-01 09:05:00.179 | 1730426700.179 | 2024-11-01 08:05:00 | 1730423100 | 1640969999 |
+----+--------------------------------------+----------+-------------------------+----------------+---------------------+------------+------------+
2 rows in set (0.00 sec)
- CASE1: mysql jdbc查询结果的分析 (接着上面的案例)
- jdbc url :
"jdbc:mysql://localhost:3306/test"
- 第1条查询结果记录 在java内存中的分析
id : Long //36
uuid : String
username : String
update_time : java.time.LocalDateTime //springboot + FastJSON 序列化后 : "2024-11-01 09:00:00.179"
((LocalDateTime) queryResult.getObject(c) ).toString(); -- 2024-11-01T09:00:00.179
((LocalDateTime) queryResult.getObject(c) ).toInstant(ZoneOffset.of("+08")); -- nanos = 179000000 / seconds = 1730422800
((LocalDateTime) queryResult.getObject(c) ).toInstant(ZoneOffset.of("+00")).toEpochMilli(); -- 1730451600179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("Asia/Shanghai")).toInstant().toEpochMilli() -- 1730422800179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("Asia/Shanghai")).withZoneSameInstant(ZoneId.of("UTC")).toInstant().toEpochMilli() -- 1730422800179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("+08")).withZoneSameInstant(ZoneId.of("UTC")).toInstant().toEpochMilli() -- 1730422800179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("UTC+08")).withZoneSameInstant(ZoneId.of("UTC")).toInstant().toEpochMilli() -- 1730422800179
update_time_ts : java.math.BigDecimal // toString() : "1730422800.179"
version : java.sql.Timestamp //springboot + FastJSON 序列化后 : "2024-11-28 11:50:48"
( (Timestamp) columnValue ).getTime() -- 1732765848000L
( (Timestamp) columnValue ).toString() -- 2024-11-28 03:50:48.0
( (Timestamp) columnValue ).toLocalDateTime().toString() -- 2024-11-28T03:50:48
version_ts : Long // 1732765848L
ts : Long // 1640966399L
- 第2条查询结果记录 在java内存中的分析
id : Long //37
uuid : String
username : String
update_time : java.time.LocalDateTime //springboot + FastJSON 序列化后 : "2024-11-01 09:05:00.179"
((LocalDateTime) queryResult.getObject(c) ).toString(); -- 2024-11-01T09:05:00.179
((LocalDateTime) queryResult.getObject(c) ).toInstant(ZoneOffset.of("+08")); -- nanos = 179000000 / seconds = 1730423100 | 2024-11-01T01:05:00.179Z
((LocalDateTime) queryResult.getObject(c) ).toInstant(ZoneOffset.of("+00")).toEpochMilli(); -- 1730451900179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("Asia/Shanghai")).toInstant().toEpochMilli() -- 1730423100179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("Asia/Shanghai")).withZoneSameInstant(ZoneId.of("UTC")).toInstant().toEpochMilli() -- 1730423100179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("+08")).withZoneSameInstant(ZoneId.of("UTC")).toInstant().toEpochMilli() -- 1730423100179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("UTC+08")).withZoneSameInstant(ZoneId.of("UTC")).toInstant().toEpochMilli() -- 1730423100179
update_time_ts : java.math.BigDecimal // toString() : 1730423100.179
version : java.sql.Timestamp //springboot + FastJSON 序列化后 : "2024-11-01 09:05:00"
( (Timestamp) columnValue ).getTime() -- 1730423100000L
( (Timestamp) columnValue ).toString() -- 2024-11-01 01:05:00.0
( (Timestamp) columnValue ).toLocalDateTime().toString() -- 2024-11-01T01:05
ts : Long // 1640966399L
- CASE2: mysql jdbc查询结果的分析
- jdbc url :
"jdbc:mysql://localhost:3306/test?serverTimezone=UTC"
- 第1条查询结果记录 在java内存中的分析
update_time_ts : java.math.BigDecimal // toString() : "1730422800.179"
update_time : java.time.LocalDateTime //springboot + FastJSON 序列化后 : "2024-11-01 09:00:00.179"
说明:jdbc url 参数[serverTimezone=UTC]后,update_time 的运算结果仍未发生改变,说明 datetime 类型,不受 jdbc 参数 [serverTimezone]的影响
((LocalDateTime) queryResult.getObject(c) ).toString(); -- 2024-11-01T09:00:00.179
((LocalDateTime) queryResult.getObject(c) ).toInstant(ZoneOffset.of("+08")); -- nanos = 179000000 / seconds = 1730422800
((LocalDateTime) queryResult.getObject(c) ).toInstant(ZoneOffset.of("+00")).toEpochMilli(); -- 1730451600179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("Asia/Shanghai")).toInstant().toEpochMilli() -- 1730422800179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("Asia/Shanghai")).withZoneSameInstant(ZoneId.of("UTC")).toInstant().toEpochMilli() -- 1730422800179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("+08")).withZoneSameInstant(ZoneId.of("UTC")).toInstant().toEpochMilli() -- 1730422800179
((LocalDateTime) queryResult.getObject(c) ).atZone(ZoneId.of("UTC+08")).withZoneSameInstant(ZoneId.of("UTC")).toInstant().toEpochMilli() -- 1730422800179
update_time_ts : java.math.BigDecimal // toString() : "1730422800.179"
version : java.sql.Timestamp //springboot + FastJSON 序列化后 : "2024-11-28 19:50:48"
( (Timestamp) columnValue ).getTime() -- 1732794648000L
( (Timestamp) columnValue ).toString() -- 2024-11-28 19:50:48.0
( (Timestamp) columnValue ).toLocalDateTime().toString() -- 2024-11-28T19:50:48
version_ts : Long // 1732765848L
说明:jdbc url 参数[serverTimezone=UTC]后,仍未发生改变
ts : Long // 1640966399L
说明:jdbc url 参数[serverTimezone=UTC]后,仍未发生改变,UNIX_TIMESTAMP('2021-12-31 23:59:59') 函数 仅受 time_zone 影响,不受 jdbc url 参数[serverTimezone]的影响
- 在MyBatis中避免LocalDateTime类型转换错误的方法:
- 方法1: 使用
TypeHandler
来处理指定Java对象中LocalDateTime
类型的转换。可自定义一个TypeHandler
来处理LocalDateTime
类型与数据库字段的转换。具体实现可以参考MyBatis官方文档或者网上的相关教程。- 方法2:在MyBatis的配置文件中配置全局的
TypeHandler
来处理LocalDateTime
类型。可以在配置文件中配置一个全局的TypeHandler,用来处理LocalDateTime类型与数据库字段的转换。具体配置方法可以参考MyBatis官方文档或者网上的相关教程。
Q: mysql jdbc参数serverTimezone
与数据库内会话级变量time_zone
的影响范围与区别?
-
在使用 jdbc url 参数 serverTimezone 配置数据库连接时,包括 serverTimezone 参数确实会影响到 【JDBC 连接的会话级别】的【时区设置】,但它的工作方式可能与直接设置 MySQL 会话 time_zone 变量有所不同。
-
当你在 JDBC 连接字符串中指定 serverTimezone=UTC,你告诉 JDBC 驱动在与数据库服务器通信时应该使用 UTC 时区。这意味着:
JDBC 驱动层面上的时区转换:
JDBC 驱动会在发送时间戳到 MySQL 服务器以及从服务器接收时间戳时,使用指定的 serverTimezone(在这个例子中是 UTC)进行转换。
这样做的目的是确保无论 MySQL 服务器的时区设置如何,应用程序和数据库之间交换的时间戳都能正确地反映预期的时区。
- 对 MySQL 会话 time_zone 设置的影响:在数据库层影响用户,例如 unix_timestamp() / now() 等受 time_zone 影响的函数
虽然 serverTimezone 参数确实影响了 JDBC 驱动如何处理时间戳,但它并不直接等同于在 MySQL 会话级别使用 SET time_zone = 'UTC';。
MySQL 服务器的全局时区设置和会话时区设置是由其自身的配置和 SQL 命令决定的。
然而,在实践中,通过 JDBC 连接字符串设置 serverTimezone 通常足以确保客户端和服务器之间的时间戳转换按预期工作,无需手动设置会话级别的 time_zone。
- 共同影响点: mysql
timestamp
数据类型字段
小结: MYSQL时区变量、数据类型、时区函数与Java JDBC的关系【推荐】
- MYSQL时区类别的变量:
- system_time_zone :只读变量。默认为MYSQL所在操作系统设置的时区,也可在启动前配置MYSQL配置项
default-time-zone
主动配置时区。 - time_zone : 可修改变量(支持会话级修改)。默认值为'SYSTEM',即其值等于 system_time_zone 变量的值。
- system_time_zone :只读变量。默认为MYSQL所在操作系统设置的时区,也可在启动前配置MYSQL配置项
- MYSQL时间类别的数据类型
- datetime 数据类型(底层:字符串):原样存入取出。
- ■ 如果查询此类字段时不使用时区函数,则:完全不受MYSQL时区变量(time_zone)、mysql jdbc参数[serverTimeZone]的影响
- ■ Java JDBC for MYSQL (8.0.28) 驱动中对应的 Java 类型: java.time.LocalDateTime
- timestamp 数据类型(底层:整型数值+入库时的时区):
- ■ 如果查询此类字段时不使用时区函数,则:查询结果受MYSQL时区变量(time_zone)、或 mysql jdbc参数[serverTimeZone]的影响。
- ■ Java JDBC for MYSQL (8.0.28) 驱动中对应的 Java 类型: java.sql.Timestamp
- datetime 数据类型(底层:字符串):原样存入取出。
- MYSQL时区函数
- unix_timestamp(...) / now() / curtime() / curday() / ... : 仅受mysql时区变量(time_zone)的影响,但不受 mysql jdbc参数[serverTimeZone]的影响。
- Java JDBC for MYSQL的参数
- serverTimeZone: 支持会话级修改MYSQL Java驱动的时区,从而影响 mysql timestamp 数据类型的数据。
Y 推荐文献
X 参考文献
可直观地了解GMT和UTC的区别
UTC时间、GMT时间、CST时间(北京时间)、时间戳
Linux 的时间操作
Spark SQL的时间操作
https://dev.mysql.com/doc/refman/8.0/en/time-zone-support.html
- https://kernelnewbies.org/y2038 | The year 2038 problem
因为时间问题搞坏系统的例子可不少,在 2016 年曾经爆出过一个 iPhone 的 bug,如果将 iPhone 的时间调整到 1970-01-01 00:00:00,则会导致手机”变砖“。
原因是 IOS 基于 BSD 这种 Unix 系统构建,在将时间调整到 1970-01-01 00:00:00 后,如果手机需要展示之前的时间,例如之前收到过短信,则会导致整数溢出。
对于 2038 问题,Linux 的解法是提供新的用户接口:https://kernelnewbies.org/y2038 .但是 MySql 至今还没有相应的公告。
本文链接: https://www.cnblogs.com/johnnyzen
关于博文:评论和私信会在第一时间回复,或直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
日常交流:大数据与软件开发-QQ交流群: 774386015 【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!