热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Oracle中的Date、TimeStamp和Interval(上)

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

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

在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') DT2
 from (select to_date('29-02-2012','dd-MM-yyyy')dt from dual);

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

因此,这句会正确执行:

select dt,add_months(dt,1) dt1
 from (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_hours
  from (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') dt2
          from dual );

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

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



助人等于自助! 3w@live.cn

推荐阅读
  • 本文探讨了使用lightopenid库实现网站登录,并在用户成功登录后,如何获取其姓名、电子邮件及出生日期等详细信息的方法。特别针对Google OpenID进行了说明。 ... [详细]
  • Multisim环境下高频小信号谐振放大器的设计与分析
    本次实验旨在通过Multisim软件平台,深入理解并实践高频小信号谐振放大器的设计与分析。具体目标包括:掌握Multisim的基本操作与功能;深入了解谐振放大器的工作机制;熟练掌握放大器性能参数的测试方法。 ... [详细]
  • 利用无代码平台实现高效业务应用开发
    随着市场环境的变化加速,全球企业都在探索更为敏捷的应用开发模式,以便快速响应新兴的商业机遇。然而,传统的软件开发方式不仅成本高昂,而且耗时较长,这往往导致IT与业务部门之间的合作障碍,进而影响项目的成功。本文将探讨如何通过无代码开发平台解决这些问题。 ... [详细]
  • Adobe Flash Player:功能与历史回顾
    本文详细介绍了Adobe Flash Player的功能及其在互联网发展史上的重要角色,同时探讨了其停止支持的原因及后续影响。 ... [详细]
  • 在Android应用开发过程中,开发者经常遇到诸如CPU使用率过高、内存泄漏等问题。本文将介绍几种常用的命令及其应用场景,帮助开发者有效定位并解决问题。 ... [详细]
  • 本文深入探讨了WPF框架下的数据验证机制,包括内置验证规则的使用、自定义验证规则的实现方法、错误信息的有效展示策略以及验证时机的选择,旨在帮助开发者构建更加健壮和用户友好的应用程序。 ... [详细]
  • 为何Compose与Swarm之后仍有Kubernetes的诞生?
    探讨在已有Compose和Swarm的情况下,Kubernetes是如何以其独特的设计理念和技术优势脱颖而出,成为容器编排领域的领航者。 ... [详细]
  • 随着社交媒体的发展,‘三天可见’成为了许多人保护个人隐私的选择,但同时也无意间筑起了人际交往的一道墙。 ... [详细]
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
  • 本文介绍了如何通过安装 sqlacodegen 和 pymysql 来根据现有的 MySQL 数据库自动生成 ORM 的模型文件(model.py)。此方法适用于需要快速搭建项目模型层的情况。 ... [详细]
  • 本文将探讨面试过程中常见的八大问题,并提供有效的应对策略,帮助求职者更好地准备面试,避免落入陷阱。通过本文的指导,求职者可以在面对类似问题时更加自信地展现自己。 ... [详细]
  • 对于编程爱好者而言,理解PHP的强大功能及其在Web开发中的应用至关重要。本文旨在分享作者在学习PHP过程中的实际经验和技巧,帮助初学者找到学习编程的有效途径。 ... [详细]
  • After Effects 十大实用可复制表达式
    本文介绍了After Effects中十个最常用的可复制表达式,这些表达式能够帮助用户快速实现各种动态效果,提升工作效率。 ... [详细]
  • 生活中的每个人都有可能陷入停滞不前的困境,适时地改变生活方式,如通过骑行等运动,不仅能够改善身体健康,还能在心理上带来新的启示与成长。 ... [详细]
  • 精选煲机软件推荐:提升耳机音质的秘密武器
    本文介绍了几款市面上流行的煲机软件,包括它们的特点、使用方法以及如何通过这些工具有效提升耳机和音箱的音质。 ... [详细]
author-avatar
拍友2502881913
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有