zoukankan      html  css  js  c++  java
  • MySQL 日期类型函数及使用

      1 MySQL 数据库中有五种与日期时间有关的数据类型,各种日期数据类型所占空间如下图所示:

      

      2 datetime 与 date

      datetime 占用8字节,是占用空间最多的一种日期格式。它显示日期,同时也显示时间。5.5及以前的版本不支持微妙级别,任何微妙数值都会被截断之后存入数据库。

      date 占用3字节,仅仅显示日期。

      

      3 timestamp

    timestamp 与 datetime 显示的结果是一样的,不同的是timestamp 占用4个字节。它的显示范围是:1970-01-01 00:00:01 至 2038-01-19 01:14:07(UTC),UTC 协调世界时间,世界统一时间。

    timestamp 与 datetime显示的格式一样,但是显示的范围不同,还有以下一些区别

    • 建表时, 列为timestamp的类型可以设置一个默认值,datetime 不行。
    • 更新表时,可以设置timestamp 类型的列自动更新时间为当前时间。

      4 year 与 time

      year 类型占用1字节,在定义时可以显示指定宽度为year(4)或者year(2)。对于year(4),其显示的年份范围为 1901 ~ 2155;对于year(2),其显示的年份范围为:1970~2070。

      在year(2)的设置下,00~69 代表 2000~2069。

      time 类型占用3字节,显示的范围 -838:59:59 ~ 838:59:59。time 类型时间大于23或者为负数时用来表示时间间隔。

      5 时间与日期函数

      5.1 系统时间函数 now(), current_timestamp, sysdate()

      这三个函数都能返回系统时间,看看它们的区别,同时访问这三个函数得到的结果一样,但是让其等待几秒之后,结果就不同了。

      

      上图发现sysdate()返回的时间与now(), current_timestamp不同,慢了2秒,原因如下:

      current_timestamp 是now的同义词,两者实际上是一样的;

      sysdate() 函数返回的是执行到当前函数时的时间,而now()返回的是执行sql语句时的时间;

      5.2 时间加减函数

      ① date_add 与 date_sub

      date_add(date, interval expr unit) 与 date_sub(date, interval expr unit) 分别表示增加与减少。

    select
    date_add('2017-12-18 22:51:00', interval 1 second),
    date_add('2017-12-18 22:51:00', interval 1 minute),
    date_add('2017-12-18 22:51:00', interval 1 hour),
    date_add('2017-12-18 22:51:00', interval 1 day),
    date_add('2017-12-18 22:51:00', interval 1 month),
    date_add('2017-12-18 22:51:00', interval 1 year);

      

      遇到闰月时,date_add怎么处理呢,MySQL如果是闰月返回的日期为2月29,如果不是闰月返回的是2月28。

    select date_add('2016-02-29 22:51:00', interval -1 year),
    date_add('2016-02-29 22:51:00', interval 4 year);

     2015-02-28 22:51:00   2020-02-29 22:51:00

     

     datediff 与 timediff

    datediff(date1,date2):两个日期相减 date1 - date2,返回天数。select datediff('2016-02-29 22:51:00','2016-03-29 22:51:00');

    timediff(time1,time2):两个日期相减 time1 - time2,返回 time 差值(格式为:838:59:59)。select timediff('2016-02-29 22:51:00','2016-01-29 22:51:00');

    注意:timediff(time1,time2) 函数的两个参数类型必须相同。

     

    ③ timestamp 增,减,转换函数

    timestamp(date)  -- date to timestamp

    timestamp(date, time) -- date + time

     

      timestampadd(unit,interval,datetime_expr)   -- 类似date_add,对时间按单位进行增加,减少 

    select timestampadd(second, 60, '2017-12-18 00:00:00');
    select timestampadd(minute, 60, '2017-12-18 00:00:00');
    select timestampadd(hour, 60, '2017-12-18 00:00:00');


      timestampdiff(unit,datetime_expr1,datetime_expr2) --计算两个时间的差,可以计算秒,分,时,天,月,年,周

    select timestampdiff(second, '2017-12-18 00:00:00','2017-12-18 12:00:00');
    select timestampdiff(hour, '2017-11-18 00:00:00','2017-12-18 12:00:00');
    select timestampdiff(day, '2017-10-17 00:00:00','2017-11-18 23:00:00');

     

    ④ date_format 函数

    date_format 函数主要用途是格式化日期

    select date_format(now(),'%Y%m%d'),
    date_format(now(),'%Y-%m-%d'),
    date_format(now(),'%Y/%m/%d'),
    date_format(now(),'%m/%d/%Y');

     

    注意:查询数据时如果对某个日期字段使用这个函数,则优化器不会使用字段的索引,也不能通过索引来查询数据,因此查询效率会很低,如下列查询语句,如果字段birth_date有索引,则该索引因为使用了date_format函数失效:

    select *
    from employees
    where date_format(birth_date,'%Y-%m-%d') = '1961-08-03';

      6 日期的经典编程问题

      根据某个用户的出生日期与当前日期,计算他最近的生日(包括已经过去的和将来的)

    -- 上一年,当年,下一年生日与当前时间差最小的年就是用户最近的生日
    select emp_no,first_name,last_name,birth_date,today,if(last_diff<=cur_diff and last_diff<=next_diff, last,if(cur_diff<last_diff and cur_diff<next_diff, cur, next) ) as latest_birth
    from
    (
    -- 计算当前时间与上一年,当年,下一年生日的时间差
    select emp_no,first_name,last_name,birth_date,datediff(today,last) as last_diff,abs(datediff(today,cur)) as cur_diff,abs(datediff(today,next)) as next_diff,
    last,cur,next,today
    from
    (
    -- 用户最近的生日可能分布在前一年,当年,下一年。根据年度差year_diff计算上一年,当年,下一年用户的生日
    select emp_no,first_name,last_name,birth_date,
    DATE_ADD(birth_date,INTERVAL year_diff year) as cur,
    DATE_ADD(birth_date,INTERVAL year_diff+1 year) as next,
    DATE_ADD(birth_date,INTERVAL year_diff-1 year) as last,
    today
    from
    (
    -- 获取当前事前与出生日期的年度差 year_diff
    select emp_no,first_name,last_name,birth_date,(year(NOW())-year(birth_date)) as year_diff, NOW() as today
    from employees
    ) a
    ) b
    ) c

      

  • 相关阅读:
    Interop.SQLDMO组件无法连接SQL2008
    关于数据连接配置connectionStrings的写法
    SQL锁表语句 (转摘)
    从思想到命运
    CIO:2013年OA选型六步走(摘)
    JS SCRIPT Confirm
    Silverlight 2 RTW中ToolTipService.ToolTip不继承父节点的DataContext的问题
    在Silverlight里实现类似WPF的UniformGrid
    尝试通过HttpWebRequest向TAOBAO批量发布商品及上传图片
    简单探照灯遮照效果的几个Silverlight程序(Silverlight 2.0)
  • 原文地址:https://www.cnblogs.com/Latiny/p/8059827.html
Copyright © 2011-2022 走看看