在Oracle中,Date和TimeStamp类型存储精度可变的固定日期时间。Intreval可以很容易地存储一个时间量,如“8个小时”或“30天”,将两个时间戳相减,就会得到一个时间间隔(Interval),例如,将8小时加到一个TimeStamp上,即得到一个新的TimeStamp。

Oracle 5中已经支持Date类型,TimeStamp和Interval在Oracle 9i Release 1中才被引入。因此,Date最为常见,但你应该在新应用中使用TimeStamp类型,因为:

1、TimeStamp支持小数秒,而Date不支持;

2、TimeStamp支持时区,Date不支持。

(一)Date类型

Date类型是一个7字节的定宽日期/时间数据类型,它包含7个属性:世纪、世纪中哪一年、月份、月中的哪一天、小时、分钟、秒。Oracle使用一种内部格式来表示,它并不是保存20,12,10,31,12,01,00来表示2012年10月31日12:01:00,这个可以通过内置函数DUMP来查看:

Create table t (x date);
insert into t(x) values (to_date('2012-11-24 12:01:00','YYYY-MM-dd HH24:mi:ss'));
select x,dump(x,10) d from t;

查询结果:


世纪和年份字节,即(120,112)采用一种“加100”的表示法来存储。必须将其减去100才能得到正确的世纪和年份。这是为了支持BC和AD日期。
如果从世纪字节减100得到负数,表示BC日期,例如:

insert into t (x) values( to_date( '01-08-4712bc','dd-MM-yyyybc hh24:mi:ss' ) );

此时,会报一个错,“ORA-01856: 要求BC/B.C. 或AD/A.D.”。

修改为如下语句:

Insert into t (x) values(to_date('01-08-4712BC','dd-MM-YYYYBC','nls_date_language=American'));insert into t (x) values( to_date( '01-08-4710BC 12:01:13','dd-MM-yyyyBC hh24:mi:ss','nls_date_language=American') );

查看结果:

别担心,读出的世纪和年份是“虚”的,其实记录是正确的,以下语句即可。

select x, to_char(x,'dd-mm-yyyybc','nls_date_language=American') AS TrueDate,dump(x,10) d from t;

世纪字节是53,而53-100=-47,这才是我们插入的真实世纪。由于这是一个负数,我们知道它是一个BC日期。这种存储格式还允许日期以一种二进制方式自然地排序。由于4712BC小于4710BC,我们可以测试一下排序:

select x, to_char(x,'dd-mm-yyyybc','nls_date_language=American') AS TrueDate,dump(x,10) d from t
order by TRUEDATE ASC;

接下来月份和日字节,自然存储,不作任何修改。小时、分、秒采用“加1”表示法存储,也就是各部分都减1,才能得到真实的时间。因此,午夜0点对应的日期字段表示为1,1,1

这种7字节格式能自然排序,可以采用一种进二进制方式按从小到大或从大到小的顺序非常高效地进行排序。另外,这种结构允许很容易地进行截断,而无需把日期变成其他格式。即将尾部三个字节设置为1,1,1即可清除时间分量。

创建一个新表:

create table t ( what varchar2(10), x date );
insert into t (what, x) values
( 'downmoon',to_date( '25-11-2012 22:01:00','dd-MM-yyyy hh24:mi:ss' ) );
insert into t (what, x)
select 'minute', trunc(x,'mi') from t
union all
select 'day', trunc(x,'dd') from t
union all
select 'month', trunc(x,'mm') from t
union all
select 'year', trunc(x,'y') from t
/
select what, x, dump(x,10) d from t;

结果:

要把这个日期截断,只取年份,数据库只要后5个字节置1,这是一个非常快速的操作。

而要向一个date增加时间或减去时间,请先遵循以下原则:

(1)使用NUMTODSINTERVAL增加时分秒;

(2)使用Date直接加数字增加天;

(3)使用ADD_MONTHS内置函数增加月和年;不建议使用NUMTOYMINTERVAL函数。因为前者会帮我们完成日期的舍入。

看示例:

alter session set nls_date_format='dd-MM-yyyy hh24:mi:ss';
select dt,add_months(dt,1) dt1,dt+NUMTOYMINTERVAL(1,'month') DT2from (select to_date('29-02-2012','dd-MM-yyyy')dt from dual);

注意:ADD_MONTHS是添加自然月,而NUMTOYMINTERVAL是加到下个月的同一天,不管这一天是否有效,如果3月31日使用NUMTOYMINTERVAL加一个月,系统会报错。

因此,这句会正确执行:

select dt,add_months(dt,1) dt1from (select to_date('31-03-2012','dd-MM-yyyy')dt from dual);

而这句会报错:指定月份的日期无效。

同理,向2012年2月29日增加1 年也会报错,因为不存在2013年2月29日。

另外一个应用就是如何得到两个日期之差,方法如下:

 select numtoyminterval(trunc(months_between(dt2,dt1)),'month')years_months,numtodsinterval(dt2-add_months( dt1, trunc(months_between(dt2,dt1)) ),'day' )days_hoursfrom (select to_date('2012-11-29 01:02:03','yyyy-MM-dd hh24:mi:ss') dt1,to_date('2014-03-15 11:22:33','yyyy-MM-dd hh24:mi:ss') dt2from dual );

这个结果清楚地表明了两个日期相差1年、3个月、15天、10小时、20分、30秒。

下面一节我们将了解了下TimeStamp

Oracle中的Date、TimeStamp和Interval(上)相关推荐

  1. Oracle中的date与timestamp

    在ORACLE中存储DATE和时间信息的话,实际上你有两种字段数据类型的选择(9i). DATE数据类型 可以存储月,年,日,世纪,时,分和秒.度量粒度是秒 以使用TO_CHAR函数把DATE数据进行 ...

  2. oracle date类型,向Oracle中插入date数据类型

    1.利用Oracle中的方法to_date(); String   DateStr   =   "1985-07-11   10:30:00.0 "; pstmt   =   co ...

  3. oracle数据库日期格式的运算,Oracle时间类型date,timestamp时间差计算

    Oracle的时间类型有两种date和timestamp.   date精确到秒,timestamp精确到毫秒. 1.计算date类型的时间差 可以先把年,月,日,小时,分,秒用to_char函数拆分 ...

  4. oracle 中DATETIME与TIMESTAMP区别

    1.DATETIME的日期范围是1001--9999年,TIMESTAMP的时间范围是1970--2038年. 2.DATETIME存储时间与时区无关,TIMESTAMP存储时间与时区有关,显示的值也 ...

  5. Oracle中VARCHAR2转换TIMESTAMP

    VARCHAR2类型转换TIMESTAMP类型 举例: TO_TIMESTAMP('2021-09-17 16:58:38.905','yyyy-mm-dd hh24:mi:ss.ff') 好了,今天 ...

  6. Oracle中日期Date类型格式的转化

    转成long型: select  (FIRSTARRIVALTIME - to_date('1970-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')) *24*60 ...

  7. JDBC和Ibatis中的Date,Time,Timestamp处理

    JDBC和Ibatis中的Date,Time,Timestamp处理 November 25th, 2010西坪 Leave a commentGo to comments 在此前,遇到过使用Ibat ...

  8. Oracle中的TIMESTAMP类型解读(TIMESTAMP存储格式)

     Oracle中的TIMESTAMP类型解读  SQL> create table test_time (col_time timestamp); 表已创建. SQL> insert in ...

  9. ORACLE中date类型字段的处理

    ORACLE中date类型字段的处理 (1)在英文版本的ORACLE中默认日期格式为'DD-MON-YY',例如'01-JAN-98' 在汉化的中文版本中ORACLE默认日期格式为'日-月-年',例如 ...

最新文章

  1. 腾讯云短信出现there are both domestic mobile phone numbers and international mobile phone numbers in the...
  2. Eclipse最新版 Neon已发布
  3. 深度学习中图像预处理均值
  4. 【中级】【后台】 微信小程序 - 腾讯云 - wafer2 - PHP - DEMO - 003 - 源码分析 - 03 - 腾讯后台初始化 和 CodeIgniter
  5. struts2编辑框中自动填充已经有的列表对应的值
  6. Xbox One 游戏欣赏: 麦克斯-兄弟魔咒
  7. 精读《手写 SQL 编译器 - 回溯》 1
  8. 好家伙,花了一个月时间写了个网易云,以后再也不用充VIP了!
  9. python土味情话_GitHub - MMstarry/itchat: 微信机器人 土味情话
  10. ckplayer播放器自动播放下一集以及点击下一集
  11. java socket ascii_TCP套接字上的ASCII - java
  12. Git安装教程(超详细教程)
  13. 网易(163)yum源是国内最好的yum源
  14. miui 8.5 android,两年前的小米5突遭MIUI9 8.5.3更新!妥妥上安卓8.0
  15. 实时渲染技术和像素流有哪些不同?
  16. 互联网大厂高并发抢购系统架构设计
  17. 水桶服务器eula文件,craftbukkit
  18. 【建议】个人竞争力≠个人竞争力模型
  19. Badboy录制模式
  20. c# 获取串口扫描枪数据

热门文章

  1. 速修复!这个严重的Zlib内存损坏漏洞已存在17年!
  2. SolarWinds 软件出现3个新的严重漏洞
  3. HTML如何设置音频播放器控件的大小
  4. SpringBoot+Dubbo实战demo
  5. [mark] first shellcode
  6. 初学Python之利用map编写姓名格式化输出函数
  7. Linux中运行c程序,与系统打交道
  8. 撰写oracle-sql-hint的注意事项
  9. Hibernate dbcp连接池使用方法
  10. python编码规范总结、python编码转换