日期问题合集(时令、时区)

日期问题合集(时令、时区)

概念

首先介绍一下有关日期的相关概念

时区

时区是地球上的区域使用同一个时间定义。以前,人们通过观察太阳的位置(时角)决定时间,这就使得不同经度的地方的时间有所不同(地方时)。1863年,首次使用时区的概念。时区通过设立一个区域的标准时间部分地解决了这个问题。世界各个国家位于地球不同位置上,因此不同国家的日出、日落时间必定有所偏差。这些偏差就是所谓的时差。
在这里插入图片描述来源:https://blog.csdn.net/fanst_/article/details/50627744

GMT:(Greenwich Mean Time)代表格林尼治标准时间
UTC:协调世界时,又称世界标准时间或世界协调时间
CST:被视为美国、澳大利亚、古巴或中国的标准时间
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
CDT:夏令时时间
除此之外还有每个国家自己设定的比如Asia/Shanghai

分析

来看看这些有什么不一样:
UTC:时间戳就是通过UTC的1970-01-01至今算出来的,UTC与GMT+0所表示的时间是一样的都是0时区。
GMT:这个就是咱们比较熟悉的了,平常总是在用,但之前了解都是一星半点。咱们所在北京就是GMT+8的时区,在这个经度上的国家都可以使用GMT+8时区
CST:他同时代表了四个地方的时区,而不同使用场景他表示的就不一样,像在java中CST代表的是中国的,而js好像代表的就是美国的,mysql中CST代表的也是美国的时区。
时间戳:时间戳就是UTC的1970年1月1日到某个时间点走过的毫秒数。他是没有时区的概念的,只是在不同的时区的地方对于同一个时间戳展示的时间也不同,因为时间戳解析出来的是相当于GMT+0的1970-01-01…的时间,但自己的时区不在GMT+0的话,那么时间就不同了。

时令

时令问题也是最近才了解到的。时令是每个国家自己设定的。拿中国举例,在中国的1986年-1991年这6年中实行了时令。就是说为了省电,在夏天的时候,这几年的四月中旬那周的周日会在凌晨2点将时钟向后拨1小时,也就是说在正常2点的这个时刻,如果说支持夏令时看到的就是3点,不支持夏令时看到的就是2点。时区如果是Asia/Shanghai或是中国的CST,那么就是支持夏令时的,看到的时间就是3点,而如果用GMT+8来看的话那就是2点。
来做个时间

public class DateTest {
    public static void main(String[] args) throws ParseException {
        test1();
        System.out.println("================================\n\n");
        test2();
    }

    /**
     * 使用系统默认时间parse转换时间
     */
    public static void test1() throws ParseException {
        System.out.println("系统默认时区------->"+ TimeZone.getDefault().getID());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date1 = simpleDateFormat.parse("1988-07-28");
        Date date2 = simpleDateFormat.parse("1998-07-28");
        System.out.println("使用系统默认时区转换得到时间(在夏令时中)------>"+date1);
        System.out.println("使用系统默认时区转换得到时间(不在夏令时中)------>"+date2);
        TimeZone timeZone = TimeZone.getTimeZone("GMT+8");
        TimeZone.setDefault(timeZone);
        System.out.println("时区设置成为------->"+timeZone.getID());
        System.out.println("时间转成GMT+8时间(在夏令时中)"+date1);
        System.out.println("时间转成GMT+8时间(不在夏令时中)"+date2);
    }

    public static void test2() throws ParseException {
        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
        System.out.println("系统默认时区------->"+ TimeZone.getDefault().getID());
        long startTime = 586022400000L;
        Date date1 = new Date(586022400000L);
        Date date2 = new Date(901555200000L);
        System.out.println("时间戳转成默认时区的时间(在夏令时中)----->"+date1);
        System.out.println("时间戳转成默认时区的时间(不在夏令时中)----->"+date2);
        TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
        System.out.println("时区设置成为------->GMT+8");
        System.out.println("时间转成GMT+8时间(在夏令时中)"+date1);
        System.out.println("时间转成GMT+8时间(不在夏令时中)"+date2);
    }

}

结果:

系统默认时区------->Asia/Shanghai
使用系统默认时区转换得到时间(在夏令时中)------>Thu Jul 28 00:00:00 CDT 1988
使用系统默认时区转换得到时间(不在夏令时中)------>Tue Jul 28 00:00:00 CST 1998
时区设置成为------->GMT+08:00
时间转成GMT+8时间(在夏令时中)Wed Jul 27 23:00:00 GMT+08:00 1988
时间转成GMT+8时间(不在夏令时中)Tue Jul 28 00:00:00 GMT+08:00 1998
================================


系统默认时区------->Asia/Shanghai
时间戳转成默认时区的时间(在夏令时中)----->Thu Jul 28 01:00:00 CDT 1988
时间戳转成默认时区的时间(不在夏令时中)----->Tue Jul 28 00:00:00 CST 1998
时区设置成为------->GMT+8
时间转成GMT+8时间(在夏令时中)Thu Jul 28 00:00:00 GMT+08:00 1988
时间转成GMT+8时间(不在夏令时中)Tue Jul 28 00:00:00 GMT+08:00 1998

Process finished with exit code 0

常用的SimpleDateFormat类中有个方法可以设置时区 sdf.setTimeZone(TimeZone.getTimeZone(timeZoneId));
对于parse方法来说:设置的是parse出来的日期是哪个时区的时间
对于format方法来说:设置指定待解析的时间是哪个时区的时间

MYSQL中时区

查看数据库时区:show variables like ‘%time_zone%’;
在这里插入图片描述
默认采用的是CST。
注意:还记得前面说CST可以代表多个时区吗,在这MySql他代表了美国的时区(UTC-06:00或UTC-05:00)。
为什么呢美国规定每年从“3月11日”至“11月7日”实行夏令时,美国中部时区改为UTC-05:00;而“11月7日”至“3月11日”实行冬令时,美国中部时区改为UTC-06:00,博主的线上问题发现的时间是2019年1月9日,而此时美国中部的时区是UTC0600,而我们的时区是UTC0800,所以6+8=14个小时,因此错误时间的相隔14个小时。
我们可以设置全局默认时区:set global time_zone = ‘+08:00’,也可以设置数据库的连接参数设置为GMT+8。

此外
TIMESTAMP和DATETIME的不同点:

对于TIMESTAMP,它把客户端插入的时间从当前时区转化为UTC(世界标准时间)进行存储。查询时,将其又转化为客户端当前时区进行返回。

而对于DATETIME,不做任何改变,基本上是原样输入和输出。
做个实验:在两个表中一个是datetime类型的,一个是timestamp类型的,存储同一个时间,然后查看看到的时间是一样的
在这里插入图片描述
修改时区后再次查看,可以看到存储为datetime的还是原来的值,而timestamp的值就变了
在这里插入图片描述
两者存储时间的范围也是不一样的:
timestamp所能存储的时间范围为:‘1970-01-01 00:00:01.000000’ 到 ‘2038-01-19 03:14:07.999999’。

datetime所能存储的时间范围为:‘1000-01-01 00:00:00.000000’ 到 ‘9999-12-31 23:59:59.999999’。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值