MySQL時間加減的正確開啟方式

2021-08-07 09:59:05 字數 3929 閱讀 5250

一、背景介紹

業務會有這樣的需求:時間字段需要加1或減1秒。

研發sql:update table set time = time + 1 where id=1; 

看似好像挺對的,但是偶爾會出現不是想要的結果。

二、模擬測試

新建乙個表test1,有3條記錄如下,執行+1操作:

create table `test1` (

`id` bigint(20) not null auto_increment,

`type` smallint(6) default '0',

`status` smallint(6) default '0',

`createtime` datetime default null,

`modifytime` timestamp default null,

primary key (`id`)

) engine=innodb auto_increment=1 default charset=utf8;

> select createtime,modifytime from test1;

+-+-------------+-------------+

| id | createtime      | modifytime       |

+-+-------------+-------------+

|  1 | 2017-08-01 18:30:59 | 2017-08-01 18:30:59 |

|  2 | 2017-08-01 18:31:01 | 2017-08-01 18:31:01 |

|  3 | 2017-08-01 18:31:02 | 2017-08-01 18:31:02 |

+-+-------------+-------------+

> update test1 set createtime=createtime+1,modifytime=modifytime+1;

> select * from test1;

+-+-------------+-------------+

| id | createtime      | modifytime       |

+-+-------------+-------------+

|  1 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |

|  2 | 2017-08-01 18:31:02 | 2017-08-01 18:31:02 |

|  3 | 2017-08-01 18:31:03 | 2017-08-01 18:31:03 |

+-+-------------+-------------+

繼續測試:

> update test1 set createtime=createtime+55,modifytime=modifytime+105;

> select createtime,modifytime from test1;

+---------------------+---------------------+

| createtime            | modifytime          |

+---------------------+---------------------+

| 0000-00-00 00:00:00 | 2000-01-05 00:00:00 |

| 2017-08-01 18:31:57 | 2017-08-01 18:32:07 |

| 2017-08-01 18:31:58 | 2017-08-01 18:32:08 |

+---------------------+---------------------+

createtime+55,modifytime+105後,並不是我們想的逢整進製的關係。

測試後我們看到59秒的時候加1秒全部變成了0000-00-00 00:00:00,而其他是正確的,此時我們會覺得是不是跟逢整進製有關係,59秒的時候再加上1秒進製1分鐘,結果卻變成了0000-00-00 00:00:00,這是為什麼?

三、問題分析

> select modifytime from test1 limit 1;                      

+----------------+             

| modifytime            |             

+----------------+             

| 2017-08-01 18:30:59 |             

+----------------+   

> update test1 set modifytime = modifytime + ; 

其實只要我們知道datatime型別以'yyyy-mm-dd hh:mm:ss'的形式來顯示的,就知道原因了。

例如:n=61,會轉換成 '0000-00-00 00-00-61';

n=101,會轉換成 '0000-00-00 00-01-01';

n=65535,會轉換成 '0000-00-00 06-55-35';

因為秒只能是0~59,不會有大於59秒的時候存在,如果大於59屬於異常,會初始化成'0000-00-00 00-00-00'狀態。分鐘也一樣。

所以如果此時秒正好為0:

當1<=n<60時,可以正常相加;

當60<=n<100時,超過59秒屬於異常,初始化成'0000-00-00 00-00-00';

當n=100時,會轉換成 '0000-00-00 00-01-00',也就是1分鐘,如果此時為59分,也會初始化成'0000-00-00 00-00-00';

以此類推,所以並不是所有的都會成功,也不是所有的都會失敗,因為這種方式本來就不符合時間加減規範,其他日期型別同理。 所以要杜絕此類問題,研發就不能偷懶,必須使用時間函式。

四、正確方式

date_add(@dt, interval 1 microsecond); -加1毫秒

date_add(@dt, interval 1 second); -加1秒 

date_add(@dt, interval 1 minute); -加1分鐘  

date_add(@dt, interval 1 hour); -加1小時  

date_add(@dt, interval 1 day); -加1天 

date_add(@dt, interval 1 week); -加1周  

date_add(@dt, interval 1 month); -加1月  

date_add(@dt, interval 1 quarter); -加1季  

date_add(@dt, interval 1 year); -加1年  

為日期減去乙個時間間隔:date_sub(),格式同date_add()

改寫後:

> update test1 set createtime=date_add(createtime, interval 1 second),modifytime=date_add(modifytime, interval 1 second);

> select * from test1;

+-+-------------+-------------+

| id | createtime      | modifytime       |

+-+-------------+-------------+

|  1 | 2017-08-01 18:31:00 | 2017-08-01 18:31:00 |

|  2 | 2017-08-01 18:31:02 | 2017-08-01 18:31:02 |

|  3 | 2017-08-01 18:31:03 | 2017-08-01 18:31:03 |

+-+-------------+-------------+

mysql加減時間 函式 時間加減

mysql加減時間 函式 時間加減 1.mysql 為日期增加乙個時間間隔 date add set dt now select date add dt,interval 1 day 加1天 select date add dt,interval 1 hour 加1小時 select date ad...

mysql加減時間 函式 時間加減

mysql加減時間 函式 時間加減 1.mysql 為日期增加乙個時間間隔 date add set dt now select date add dt,interval 1 day 加1天 select date add dt,interval 1 hour 加1小時 select date ad...

mysql加減時間 函式 時間加減

select timediff 23 40 00 18 30 00 兩時間相減 select substring timediff 23 40 00 18 30 00 1,5 05 10 相減返回小時 分鐘 select datediff 2008 08 08 2008 08 01 7 兩日期相減 ...