oracle date日期类型 精析
一、date
1.date、sysdate格式说明
展示
date类型,可以以任何想要的格式进行展现,譬如:
既可以为:YYYY/MM/DD,也可以为YYYY/MM/DD HH24:MI:SS;
其存储格式,一般情况下,精确到秒,比如:YYYY/MM/DD HH24:MI:SS
展示格式一:
当你只存年月日时,date实际存储的是:年月日0时0分0秒,在plsql中,其默认展示格式为:YYYY/MM/DD(月份和日期前面不会通过补0的方式补够2位,如:2022-2-3),
将其转换成YYYY/MM/DD HH24:MI:SS时,返回的是YYYY/MM/DD 00:00:00。
展示格式二:
当date实际存储的是年月日时分秒时,在plsql中,其默认展示格式为:YYYY/MM/DD HH24:MI:SS(月份和日期前面不会补零);
系统时间sysdate,在plsql中,其展示格式为:YYYY/MM/DD HH24:MI:SS。
说明:与插入时的格式无关
证实
TESTDATE表结构
插入sql的日期格式及结果展示
补充:
当插入年月日时分秒且时分秒为:00:00:00,在plsql中是不显示时分秒的。
要想显示出来,需用to_char()
若是还是对推荐有疑问,请看下面的 4.2 查询指定时间段的数据
2022年2月9日15:08:45
说明:不同数据库工具,对于日期类型的显示格式是不一样的。
PLSQL:默认的,显示格式为YYYY/M/D HH24:MI:SS
可通过首选项进行修改
NAVICATE:默认的显示格式为yyyy-MM-dd HH:mm:ss
可通过:工具--》选项--》记录,修改成自己想要展示的日期效果
ORACLE官方客户端:默认的显示格式如下
可通过SQL来更改本地会话的日期展示结果
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';
2.日期转字符串
TO_CHAR(date,format)
方式一:只带一个参数
select to_char(t.schedule_date) from CONSULT_SCHEDULE t
--28-APR-17
方式二:带2个参数
转换格式不区分大小写;
小时格式化:不带24时,默认为12小时制,24小时格式转换时需要指明;
分钟格式化:可以使用mi或mm,建议使用MI。
说明:
格式化成yyyy年mm月dd日
错误方式:
正确方式:
--年月日
--需要填充3个空格,不然‘日’显示不出来
SELECT TO_CHAR(SYSDATE, 'yyyy"年"MM"月"dd"日" ' ) 系统日期 FROM DUAL
注意:
年月日需加上双引号;
别名不能加单引号、双引号。
格式化:yyyy,mm,dd,hh,mi,ss,在Oracle当中不区分大小写,结果都一样。
3.字符串转日期
方法一:
TO_DATE('dateStr', format),规则如下:
转换格式不区分大小写;
小时格式化:不带24时,默认为12小时制,24小时格式转换时需要指明;
分钟格式化:必须使用mi,不能使用mm,否则会算错;
dateStr的长度<=format的长度,都可以实现类型转换:
方式一:标准格式
年月日
说明:将年月日转换成日期类型,实际转换结果为:1997/01/01 00:00:00;
证明如下:
年月日时分秒
方式二:字符串只到分,会自动添加上:00秒。
方式三:字符串也是只到日
2021年12月24日11:12:10
方式四:将时间转换成日期
小时转日期
时分转日期
时分秒转日期
分钟转日期
秒转日期
我们可以看到,无论是单独将:小时、小时+分钟、小时+分钟+秒数,转换成日期的时候,都会被统一转换成:
系统当前月的第一天+时分秒(时分秒,会被自动填充),具体转换内容看图片更合适。
年份转日期
月份转日期
天数转日期
年月转日期
方法二:
DATE'YYYY-MM-DD',并且只能是这一种格式。
另外,TO_DATE(date),该函数也可以只传一个参数,但是这个参数必须是date类型,
表示的含义是:将任何格式的日期类均转换成YYYY/MM/DD的格式。
4.根据日期查询数据(重点注意)
说明:这里着重介绍的是日期字段带有时分秒的
4.1 查询某一天的数据
测试环境:
VIRTUAL_CARD表中共有5条记录;
字段REGTIME的字段类型为date。
情景模拟:查询2018年7月18日的数据记录
格式要求:日期转变成YYYY-MM-DD HH24:MI:SS格式的字符串
方式一:查询条件使用字符串实现
--查询条件按字符串进行
SELECT TO_CHAR(T.REGTIME, 'YYYY-MM-DD HH24:MI:SS' ) REGTIME
FROM VIRTUAL_CARD T
WHERE TO_CHAR(T.REGTIME, 'yyyy-mm-dd' ) = '2018-07-18'
方式二:查询条件使用日期实现
方法一:TRUNC()
--查询条件按日期进行1
SELECT TO_CHAR(T.REGTIME, 'YYYY-MM-DD HH24:MI:SS' ) REGTIME
FROM VIRTUAL_CARD T
WHERE TRUNC(T.REGTIME) = TO_DATE( '2018-07-18' , 'YYYY-MM-DD' )
方法二:TO_DATE()
--查询条件按日期进行2
SELECT TO_CHAR(T.REGTIME, 'YYYY-MM-DD HH24:MI:SS' ) REGTIME
FROM VIRTUAL_CARD T
WHERE TO_DATE(T.REGTIME) = TO_DATE( '2018-07-18' , 'YYYY-MM-DD' )
方式三:利用TO_DATE()特性
SELECT TO_CHAR(T.REGTIME, 'YYYY-MM-DD HH24:MI:SS' ) REGTIME
FROM VIRTUAL_CARD T
WHERE T.REGTIME >= TO_DATE( '2018-07-18' , 'YYYY-MM-DD' )
AND T.REGTIME < TO_DATE( '2018-07-19' , 'YYYY-MM-DD' )
方法四:TO_CHAR()-->TO_DATE() 不建议使用
SELECT TO_CHAR(T.REGTIME, 'YYYY-MM-DD HH24:MI:SS' ) REGTIME
FROM VIRTUAL_CARD T
WHERE TO_DATE(TO_CHAR(T.REGTIME, 'YYYY-MM-DD' ), 'YYYY-MM-DD' ) =
TO_DATE( '2018-07-18' , 'YYYY-MM-DD' )
查询结果展示
updateTime--2018年8月15日10点21分
4.2 查询指定天数的数据
表数据展示
场景:查询从2018-08-05至2018-08-06的数据
错误实现方式:
--错误实现:between and
SELECT REGTIME
FROM VIRTUAL_CARD
WHERE REGTIME BETWEEN TO_DATE( '2018-08-05' , 'yyyy-mm-dd' ) AND
TO_DATE( '2018-08-07' , 'yyyy-mm-dd' )
ORDER BY REGTIME
查询结果:[2018/08/05 00:00:00,2018/08/07 00:00:00]
由最上面的TO_DATE('dateStr', format)介绍得知:
to_date('2018-08-05','yyyy-mm-dd'),实际代表的日期为:2018年8月5日0时0分0秒。
方式一:转换日期前往后推一天+1并用小于号;
--方式一:[2018/08/05 00:00:00,2018/08/06 23:59:59]
SELECT REGTIME
FROM VIRTUAL_CARD
WHERE REGTIME >= TO_DATE( '2018-08-05' , 'yyyy-mm-dd' ) AND
REGTIME < TO_DATE( '2018-08-07' , 'yyyy-mm-dd' )
ORDER BY REGTIME
说明:不用担心天数+1导致的跨月问题。
方式二:转换日期后+1并用小于号;(推荐使用)
--方式二:[2018/08/05 00:00:00,2018/08/07 00:00:00)
SELECT REGTIME
FROM VIRTUAL_CARD
WHERE REGTIME >= TO_DATE( '2018-08-05' , 'yyyy-mm-dd' ) AND
REGTIME < TO_DATE( '2018-08-06' , 'yyyy-mm-dd' ) + 1 --2018-08-07
ORDER BY REGTIME
方式三:加上时分秒;
--方式三
SELECT REGTIME
FROM VIRTUAL_CARD
WHERE REGTIME >= TO_DATE( '2018-08-05 00:00:00' , 'yyyy-mm-dd hh24:mi:ss' ) AND
REGTIME <= TO_DATE( '2018-08-06 23:59:59' , 'yyyy-mm-dd hh24:mi:ss' )
ORDER BY REGTIME
2021年12月24日14:53:51
方式四:将字段转成字符串。
SELECT REGTIME
FROM VIRTUAL_CARD
WHERE TO_CHAR(REGTIME, 'yyyy-mm-dd') >= '2019-08-05' AND
TO_CHAR(REGTIME, 'yyyy-mm-dd') <= '2019-08-06'
ORDER BY REGTIME;
2021年12月24日15:28:32
4.3查询指定月数数据
查询2019年7月,8月两个月的数据
由最上面的TO_DATE('dateStr', format)介绍得知:
to_date('2019-07','yyyy-mm'),实际代表的日期为:2019年7月1日0时0分0秒。
方式1:转换成日期后往后推一个月;
--[2019/07/01 00:00:00,2019/09/01 00:00:00)
SELECT REGTIME
FROM VIRTUAL_CARD
WHERE REGTIME >= TO_DATE('2019-07', 'yyyy-mm')
AND REGTIME < TO_DATE('2019-08', 'yyyy-mm') + interval '1' month
ORDER BY REGTIME;
说明:不用考虑月数+1导致的跨年问题。
方式2:转换成日期前,往后推一个月。
--[2019/07/01 00:00:00,2019/09/01 00:00:00)
SELECT REGTIME
FROM VIRTUAL_CARD
WHERE REGTIME >= TO_DATE('2019-07', 'yyyy-mm')
AND REGTIME < TO_DATE('2019-09', 'yyyy-mm')
ORDER BY REGTIME;
方式3:to_char()。
SELECT REGTIME
FROM VIRTUAL_CARD
WHERE TO_CHAR(REGTIME, 'yyyy-mm') >= '2019-07' AND
TO_CHAR(REGTIME, 'yyyy-mm') <= '2019-08'
ORDER BY REGTIME;
4.4查询指定年数数据
查询2017,2018两年的数据
由最上面的TO_DATE('dateStr', format)介绍得知:
to_date('2019','yyyy'),实际代表的日期为:2019年+系统当前月+1日0时0分0秒;
由于系统时间是在一直变化的,这样,将年转换成日期后,就会导致:中间的月份不断变化,根本无法进行固定运算;
所以,这里有且只有一种查询办法:
利用to_char()函数将日期字段转成字符串。
--唯一方式
SELECT REGTIME
FROM VIRTUAL_CARD
WHERE TO_CHAR(REGTIME, 'yyyy') >= '2017' AND
TO_CHAR(REGTIME, 'yyyy') <= '2018'
ORDER BY REGTIME;
5.date类型进行加减运算
5.1 关键词:interval
语法:加减符号+[间隔倍数 * ] interval+'间隔数字'+间隔单位。
获取前1秒时间
select sysdate,sysdate - interval '1' second 1秒前 from dual
获取前1分钟时间
select sysdate,sysdate - interval '1' minute 1分钟前 from dual
获取前1小时时间
select sysdate,sysdate - interval '1' hour 1小时前 from dual
获取前1天时间
select sysdate,sysdate - interval '1' day 1天前 from dual
获取前1月时间
方式1:使用interval;
select sysdate,sysdate - interval '1' month 1月前 from dual
方式2:使用add_months()。
获取前1年时间
方式1:使用interval;
select sysdate,sysdate - interval '1' year 1年前 from dual
方式2:使用add_months()。
获取七天前的3种方式
方式一:
方式二:
方式三:
5.2函数add_months()
语法:add_months(日期类型,整数);
第2个参数虽然支持小数,但是,实际运算结果也只计算整数部分;
第2个参数可以为正数,表示时间往后推,也可以为负数,表示时间往前推。
二、timestamp
1.格式
--查询系统时间戳
SELECT SYSTIMESTAMP FROM DUAL
2022年2月9日16:26:24
timestamp的另外两种变形:
TIMESTAMP WITH LOCAL TIME ZONE
TIMESTAMP WITH TIME ZONE
三、相互转换
1.日期转时间戳
--系统时间转时间戳
SELECT CAST (SYSDATE AS TIMESTAMP ) DATE_TO_TIMESTAMP FROM DUAL
2023年6月9日09:38:53
2.关于sysdate的补充说明
2018年写的文章《oracle对系统日期sysdate进行格式化: to date(sysdate, 'yyyy-MM-dd')》。
在新版本的Oracle当中已经无法执行了。
其实,也可以理解,sysdate本身就是日期date类型,无法再使用to_date()方法也是情理之中。
写在最后
哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!
本文来自博客园,作者:Marydon,转载请注明原文链接:https://www.cnblogs.com/Marydon20170307/p/9336970.html