客户扔过来一个bug,说是一个系统中对42岁以上的人的统计不正确,而41岁以下的人没有问题。眼睛瞟了一下托盘区里的日期,2012年3月26日,嗯,今年42岁的话,那么应该就是出生在1970年左右,马上就把问题锁定在了unixtime上,嗯,重点怀疑!

小贴士:UNIX时间,或称POSIX时间是UNIX或类UNIX系统使用的时间表示方式:从协调世界时1970年1月1日0时0分0秒起至现在的总秒数,不包括闰秒。——来自《维基百科》

看了一下数据库,生日是以int形式保存的,有正有负。这没啥问题嘛。

再看代码,SQL语句中有一个类似下面的条件语句:

WHERE FROM_UNIXTIME(birthday, '%Y') = XXX

其中的birthday是存放生日日期的unixtime值的字段,int类型的。XXX由PHP的date('Y', timestamp)来算出年份。在我的印象中,PHP的date函数处理负数的时间戳是没有问题的(注:PHP4在windows下不能处理负数时间戳,PHP5则没有这个问题。客户的服务器是Linux的,PHP4也没有问题)。好吧,那么我就开始怀疑FROM_UNIXTIME函数了,以前还真没怎么注意这玩意。随手写两个测试:

> SELECT FROM_UNIXTIME(1);
> 1970-01-01 08:00:01

看来FROM_UNIXTIME还与时区有关系。继续来:

> SELECT FROM_UNIXTIME(-1);
> NULL

哦耶,FROM_UNIXTIME果然不支持负数。测试版本为Mysql 5.1.x

这是一个条件语句,又不能拿出来由PHP处理。当然办法还是很多,比如把生日所在年换一个以unixtime表示的年龄段等等。但是我们只讨论如何用mysql计算负数的unixtime。

我们知道了unixtime表示的是从1970年1月1日0时0分0秒开始到现在的秒数,而为负的情况就是1970年第一天之前的秒数,那么可不可以通过时间计算来算出来呢?查手册,找到一个date_add函数,可以计算时间的加减。那我们就以1970年的第一天(unixtime=0的时候)作为基准来手动计算吧。由于Mysql的日期计算基本上都和时区有关系,我也懒得去搞了,就写一个大一点的秒数来看看结果:

> SELECT DATE_ADD(FROM_UNIXTIME(0), INTERVAL 1234567 SECOND);
> 1970-01-15 14:56:07

这是没有问题的,unixtime为负数的情况下:

> SELECT DATE_ADD(FROM_UNIXTIME(0), INTERVAL -1234567 SECOND);
> 1969-12-18 01:03:53

哦耶!成功了!那么剩下的问题就简单了,将本文开始的查询条件修改为:

WHERE DATE_FORMAT(DATE_ADD(FROM_UNIXTIME(0), INTERVAL birthday SECOND),'%Y') = XXX

就没问题了,BUG去除成功。

本例中用了到INTERVAL关键字,由于它不止可以用于date_add函数,那下面再总结一下DATE_ADD函数的单位(从官方手册里抄来的,为了方便理解,有一点小修改):

使用格式:INTERVAL expr type

举例:

DATE_ADD(date,INTERVAL
expr type)

DATE_SUB(date,INTERVAL expr type)

date +/-INTERVAL expr type等。

关键词INTERVA及 
type分类符均不区分大小写。

type值 预期的expr格式
MICROSECOND 整数
SECOND 整数
MINUTE 整数
HOUR 整数
DAY 整数
WEEK 整数
MONTH 整数
QUARTER 整数(季节)
YEAR 整数
SECOND_MICROSECOND '秒.毫秒'
MINUTE_MICROSECOND '分钟数.毫秒'
MINUTE_SECOND '分:秒'
HOUR_MICROSECOND '小时数.毫秒'
HOUR_SECOND '时:分:秒'
HOUR_MINUTE '时:分'
DAY_MICROSECOND '日期号数.毫秒'
DAY_SECOND '日 时:分:秒'
DAY_MINUTE '日 时:分'
DAY_HOUR '日 小时'
YEAR_MONTH '年-月'
 
 
 
转: https://blog.unlink.link/sql/mysql_before_1970_minus_unixtime.html
 
 
mysql的from_unixtime只能处理1970~2038年的时间戳,超过必须要上面的思路,并且int长度也只能表示到2038年,bigint可以表示的范围大些
 
 
 
 
 

Mysql中处理1970年前的日期(unixtime为负数的情况)负数时间戳格式化的更多相关文章

  1. 关于JDBC技术中,调用MySQL中不建议在没有服务器身份验证的情况下建立SSL连接错误解决

    今天学习到了JBDC前沿:对JDBC编写步骤的封装,出现了一大串红色报错(当然,也不能叫报错,毕竟不是所有的红色都是错误eeror,) 错误如下: Establishing SSL connectio ...

  2. MYSQL中关于日期处理的函数

    < DOCTYPE HTML PUBLIC -WCDTD HTML TransitionalEN> MySQL数据库中SQL语句中 关于日期.时间\时间戳的函数   一 MySQL 获得当 ...

  3. mysql 中时间和日期函数应用

    一.MySQL 获得当前日期时间 函数 1.1 获得当前日期+时间(date + time)函数:now() mysql> select now(); +-------------------- ...

  4. mysql 中 时间和日期函数

    From: http://www.cnblogs.com/redfox241/archive/2009/07/23/1529092.html 一.MySQL 获得当前日期时间 函数 1.1 获得当前日 ...

  5. mysql中时间日期函数

    转自:mysql 中 时间和日期函数 一.MySQL 获得当前日期时间 函数 1.1 获得当前日期+时间(date + time)函数:now() mysql> select now(); +- ...

  6. Java中日期类型和mysql中日期类型进行整合

      1. java与mysql中日期.时间类型总结: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 mysql(版本:5.1.50)的时间日期类型如下:   da ...

  7. mysql中查看某个日期是星期几?如何知道某个日期是星期几?某个日期是周几?

    需求描述: mysql中,如果要查看某个日期是星期几,可以用date_format函数实现,在此记录下. 操作过程: 1.通过date_format函数查看某个日期是星期几 mysql> sel ...

  8. TIMESTAMP类型字段在SQL Server和MySQL中的含义和使用

    公众号上转的满天飞的一篇文章,MySQL优化相关的,无意中瞄到一句“尽量使用TIMESTAMP而非DATETIME”,之前对TIMESTAMP也不太熟悉,很少使用,于是查了一下两者的区别. 其实,不管 ...

  9. MySQL中日期和时间类型

    1 日期类型 MySql中关于日期的类型有Date/Datetime/Timestamp三种类型. 日期赋值时,允许"不严格"语法:任何标点符都可以用做日期部分或时间部分之间的间割 ...

随机推荐

  1. 福州三中集训day1

    第一天感觉很是不友好,好在我是学过搜索之后才听的课,不然估计得死在教室…. 某zld犇犇讲的很是强?今天主要是讲枚举和DFS,几道经典题目讲完,还没到下课时间, 然后讲起了float. 有空整理一下吧 ...

  2. 谜题8:Dos Equis

    这个谜题将测试你对条件操作符的掌握程度,这个操作符有一个更广为人知的名字:问号冒号操作符.下面的程序将会打印出什么呢? public class DosEquis{ public static voi ...

  3. URAL 2072 Kirill the Gardener 3 (单调DP)

    [题目链接] http://acm.timus.ru/problem.aspx?space=1&num=2072 [题目大意] 一个园丁要给一排花浇水,每个花都有一个标号,必须要先浇标号小的, ...

  4. 【后缀数组】poj3581 Sequence

    考虑第一次切割,必然切割的是翻转后字典序最小的前缀,伪证: 若切割位置更靠前:则会导致第一个数翻转后更靠前,字典序必然更大. 若切割位置更靠后,则显然也会导致字典序更大. ↑,sa即可 对于第二次切割 ...

  5. 1.7(学习笔记)过滤器(Fliter)

    一.过滤器(Fliter)简介 过滤器是位于客户端与服务器之间的滤网,在访问资源时会经过一系列的过滤器, 满足条件则放行,不满足条件的将其拦截. 过滤器可以看做是一个特殊的Servlet,设置了过滤器 ...

  6. UITextField的returnkey点击事件

    关于隐藏软键盘,网上的办法良莠不齐,大多是通过实现UITextFieldDelegate来隐藏软键盘,该方法代码较多,且在文本框很多的时不好处理.我经过搜索与摸索,找到了最佳的处理办法.(引用的)一. ...

  7. String的解析

    String作为Java中最常用的引用类型,相对来说基本上都比较熟悉,无论在平时的编码过程中还是在笔试面试中,String都很受到青睐,然而,在使用String过程中,又有较多需要注意的细节之处. 1 ...

  8. php之文件类型解析漏洞防御与攻击

    php在处理文件上传时,经常可以用到下面几种方式来判断文件的类型 1.通过文件名后缀,不安全,非常容易欺骗2.通过mime判断,部分类型的文件通过修改文件后缀名,也可以欺骗服务器3.通过头字节判断文件 ...

  9. ubuntu16.04 登录密码破解方法

    1:开机按Shift键,出现如下界面.(手速要快,Shift键要按时间久一点) 选择第二项 2:按回车键进入如下界面,然后选中有recovery mode的选项(第三项) 3:按e进入如下界面,并找到 ...

  10. [C++]豆知识(1条)

    术语: ctor:constructor,构造函数 dtor:destructor,析构函数 构造函数/析构函数 如果基类要利用多态,则dtor需要声明为virtual,这样在销毁对象时才可以正确调用 ...