日期时间存入数据库会差一天?

Date型的数据插入数据库时间被改变的一些问题记录。

一、插入数据库总是早一天

Date型的数据插入数据库,发现总是早一天。

  • 问题原因:是由于JDBC的时区和当前不一致导致的。
    mysql默认的是美国的时区,而我们中国大陆要比他们迟8小时,应该采用+8:00格式

  • 查看数据库时区
    show variables like "%time_zone";
    在这里插入图片描述

  • 解决方式:在JSBC连接的时候与数据库时区保持一致,java默认的应该是系统时区或者是世界时
    如果数据库时区是 CST 或者 世界时(GMT/UT)+8,那么JDBC连接参数中要加入serverTimezone=GMT%2B8,如下

dbc:mysql://localhost:3306/boo?useUnicode=ture&characterEncoding=UTF-8&serverTimezone=GMT%2B8

二、回显到前端会早一天

问题原因:依旧是时区问题,导致数据库跟java虚拟机读出来的时间不一致
应针对字段进行时区处理,例如 @JsonFormat注解中就有设置时区的属性 – timezone

/** 创建时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private Date createTime;

三、夏令时问题

这个问题就是就算是你时区保持一致了,但是在某些时间还是会出现时间不一致的情况

  • 问题原因:
    根据夏令时规定,在规定的时间段内,时针会自动回拨一小时(详见下方扩展)。
    那么当你用Date格式记录日期的时候,例如出生日期“1991-06-16”(此日期在夏令时内),Date中记做‘‘1991-06-16 00:00:00’’,那么插入数据库时日期就会被最终记录成 “1991-06-15 23:00:00”,再次读出来的话就是“1991-06-15”,提前了一天…

解决:
这个问题由于人们认知与实际规定的差异,所以基本无解。好在夏令时实行时间是1986 - 1992年之间,一般项目中涉及这个时间段的只有生日,而生日一般记做 yyyy-MM-dd , 根据夏令时的特性,将生日字段特殊处理 ---- 默认给时间+1小时,即 1996-10-13 在后台处理为 1996-10-13 01,这样在存入数据库时就算因为夏令时时针回拨1小时,那生日依旧是 1996-10-13 00 ,这样就不会出现生日提前一天的情况了。注意这种情况,生日在取得时候取到dd,存的时候+1h,否则累加hh会出错。

扩展:

夏令时

夏令时,(Daylight Saving Time:DST),也叫夏时制,又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间调快一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏时制的国家具体规定不同。全世界有近110个国家每年要实行夏令时。
1986年4月,中国中央有关部门发出“在全国范围内实行夏时制的通知”,具体做法是:每年从四月中旬第一个星期日的凌晨2时整(北京时间),将时钟拨快一小时,即将表针由2时拨至3时,夏令时开始;到九月中旬第一个星期日的凌晨2时整(北京夏令时),再将时钟拨回一小时,即将表针由2时拨至1时,夏令时结束。从1986年1991年的六个年度,除1986年因是实行夏时制的第一年,从5月4日开始到9月14日结束外,其它年份均按规定的时段施行。在夏令时开始和结束前几天,新闻媒体均刊登有关部门的通告。1992年起,夏令时暂停实行。

  • 关键内容
    • 夏令时实行年份: 1986 - 1992 之间,不包括1992
    • 时间为:每年从四月中旬第一个星期日的凌晨2时到九月中旬第一个星期日的凌晨2时整
    • 调整:时针往前回拨一小时,即 1986-05-04 00:00:00 回拨一小时 为 1986-05-03 23:00:00、
      1986-05-04 01:00:00 回拨一小时 为 1986-05-04 00:00:00
    • 其时间分别是:
      1986年:05-04 02 ~ 09-14 02
      1987年:04 -12 02 ~ 09-13 02
      1988年:04 -10 02 ~ 09-11 02
      1989年:04 -17 02 ~ 09-17 02
      1990年:04 -15 02 ~ 09-16 02
      1991年:04 -14 02 ~ 09-15 02
  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个示例代码,可以爬取上海市前十天的最高和最低气温,并将数据存入SQLite数据库,最后使用matplotlib库绘制折线图: ```python import requests import sqlite3 import matplotlib.pyplot as plt from bs4 import BeautifulSoup # 请求头,模拟浏览器访问 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} # 目标网址 url = 'http://www.tianqihoubao.com/lishi/shanghai/month/202107.html' # 发送HTTP请求 res = requests.get(url, headers=headers) # 解析HTML页面 soup = BeautifulSoup(res.text, 'html.parser') # 获取天气数据表格 table = soup.find('table', {'class': 'b'}) # 连接数据库 conn = sqlite3.connect('weather.db') cursor = conn.cursor() # 创建表格 cursor.execute('CREATE TABLE IF NOT EXISTS weather (date TEXT, high_temperature INT, low_temperature INT)') # 解析表格数据 rows = table.find_all('tr') for row in rows[1:11]: data = row.find_all('td') date = data[0].text.strip() high_temperature = int(data[1].text.strip().replace('℃', '')) low_temperature = int(data[2].text.strip().replace('℃', '')) print(date, high_temperature, low_temperature) # 将数据插入数据库 cursor.execute('INSERT INTO weather (date, high_temperature, low_temperature) VALUES (?, ?, ?)', (date, high_temperature, low_temperature)) # 提交事务并关闭连接 conn.commit() conn.close() # 从数据库中读取数据 conn = sqlite3.connect('weather.db') cursor = conn.cursor() cursor.execute('SELECT * FROM weather') data = cursor.fetchall() conn.close() # 绘制折线图 dates = [row[0] for row in data] high_temperatures = [row[1] for row in data] low_temperatures = [row[2] for row in data] plt.plot(dates, high_temperatures, label='High Temperature') plt.plot(dates, low_temperatures, label='Low Temperature') plt.xticks(rotation=45) plt.xlabel('Date') plt.ylabel('Temperature (℃)') plt.title('Shanghai Weather') plt.legend() plt.show() ``` 这段代码会爬取上海市2021年7月份前十天的最高和最低气温,并将数据存入名为`weather.db`的SQLite数据库中。最后使用matplotlib库绘制折线图,展示这些数据。你可以根据需要修改日期、城市等参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值