广告
返回顶部
首页 > 资讯 > 数据库 >关于Oracle Timezone的一点总结
  • 843
分享到

关于Oracle Timezone的一点总结

2024-04-02 19:04:59 843人浏览 泡泡鱼
摘要

原文:Http://blog.itpub.net/9765498/viewspace-539881 背景描述: 如果需要支持一个国际化的应用,那么数据库端的国际化特性的支持也就显

原文:Http://blog.itpub.net/9765498/viewspace-539881


背景描述: 如果需要支持一个国际化的应用,那么数据库端的国际化特性的支持也就显得尤其重要。oracle中有很多特性支持国际化,如字符集、时区等等。如果相关参数设置不当,或者由于对相关特性不够了解,以至于在设计阶段没有考虑完全,那么肯定会对应用造成一定的损失。偶前不久也遇到了time zone相关的问题,所以在此结合遇到的问题,对时区问题作一个小小的总结

1. 如何查看和修改数据库和session时区

Oracle中相关的时区大体可以分为两类:数据库时区和session时区。可以通过以下方式获得:

查看数据库时区信息:

sql> select dbtimezone from dual;

DBTIME
------
+08:00

查看session时区信息:

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
---------------------------------------------------------------------------
+08:00

Database的timezone 可以在创建数据库的时候指定,如:

CREATE DATABASE db01
...
SET TIME_ZONE='+08:00';

或者在数据库创建之后通过alter database语句修改,但是只有重启数据库后有效:

ALTER DATABASE SET TIME_ZONE='+08:00';

session的timezone 可以简单通过alter session语句修改:

ALTER SESSION SET TIME_ZONE='+08:00';

Note: Database Time Zone只和 TIMESTAMP WITH LOCAL TIME ZONE 数据类型相关! 其实数据库timezone只是一个计算的标尺,TIMESTAMP WITH LOCAL TIME ZONE数据类型从客户端传入数据库后,转为数据库时区存入数据库。在需要进行相关计算的时候,Oracle先把时间转换为标准时间(UTC),完成计算后再把结果转换为数据库时区的时间保存到数据库。关于TIMESTAMP WITH LOCAL TIME ZONE数据类型的详细信息,请参考随后相关部分:)

2. 时区相关的数据类型

和时区相关的数据类型主要有:DATE,TIMESTAMP,TIMESTAMP WITH TIME ZONE和TIMESTAMP WITH LOCAL TIME ZONE。粗略介绍如下:

DATE :存储日期和时间信息,精确到秒。

SQL> alter session set nls_date_fORMat='YYYY-MM-DD HH24:MI:SS';

Session altered.

SQL> select to_date('2009-01-12 13:24:33','YYYY-MM-DD HH24:MI:SS') from dual;

TO_DATE('2009-01-12
-------------------
2009-01-12 13:24:33

TIMESTAMP :DATE类型的扩展,保留小数级别的秒,默认为小数点后6位。不保存时区和地区信息。

SQL> select localtimestamp from dual;

LOCALTIMESTAMP
---------------------------------------------------------------------------
12-JAN-09 07.21.37.984000 PM

TIMESTAMP WITH TIME ZONE :存储带时区信息的TIMESTAMP(以和UTC时间差或者地区信息的形式保存)。形式大致为:

TIMESTAMP '2009-01-12 8:00:00 +8:00'

TIMESTAMP WITH LOCAL TIME ZONE :另一种不同类型的TIMESTAMP,和TIMESTAMP WITH TIME ZONE类型的区别在于:数据库不保存时区相关信息,而是把客户端输入的时间转换为基于database timezone的时间后存入数据库(这也就是database tmiezone设置的意义所在,作为TIMESTAMP WITH LOCAL TIME ZONE类型的计算标尺)。当用户请求此类型信息时,Oracle把数据转换为用户session的时区时间返回给用户。所以Oracle建议把database timezone设置为标准时间UTC,这样可以节省每次转换所需要的开销,提高性能。

下面是针对以上几种类型所做的实验:

操作DATE类型数据

SQL> INSERT INTO table_dt VALUES(1,DATE '2009-01-01');

1 row created.

SQL> INSERT INTO table_dt VALUES(2,TIMESTAMP '2009-01-01 00:00:00 Asia/Hong_Kong');

1 row created.

SQL>  INSERT INTO table_dt VALUES(3,TO_DATE('01-JAN-2009','DD-MON-YYYY'));

1 row created.

SQL> commit;

Commit complete.

SQL> select * from table_dt;

      C_ID C_DT
---------- -------------------
         1 2009-01-01 00:00:00
         2 2009-01-01 00:00:00
         3 2009-01-01 00:00:00

操作TIMESTAMP数据类型

SQL> ALTER SESSION SET NLS_TIMESTAMP_FORMAT='DD-MON-YY HH:MI:SSXFF';

Session altered.

SQL> CREATE TABLE table_ts(c_id NUMBER, c_ts TIMESTAMP);

Table created.

SQL> INSERT INTO table_ts VALUES(1, '01-JAN-2009 2:00:00');

1 row created.

SQL> INSERT INTO table_ts VALUES(2, TIMESTAMP '2009-01-01 2:00:00');

1 row created.

SQL> INSERT INTO table_ts VALUES(3, TIMESTAMP '2009-01-01 2:00:00 -08:00');

1 row created.

SQL> commit;

Commit complete.

SQL> set linesize 120
SQL> select * from table_ts;

      C_ID C_TS
---------- ---------------------------------------------------------------------------
         1 01-JAN-09 02:00:00.000000
         2 01-JAN-09 02:00:00.000000
         3 01-JAN-09 02:00:00.000000

Note: 第三条数据的时区信息丢失!

操作TIMESTAMP WITH TIME ZONE数据类型

SQL> ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT='DD-MON-RR HH:MI:SSXFF AM TZR';

Session altered.

SQL> ALTER SESSION SET TIME_ZONE='-7:00';

Session altered.

SQL> CREATE TABLE table_tstz (c_id NUMBER, c_tstz TIMESTAMP WITH TIME ZONE);

Table created.

SQL> INSERT INTO table_tstz VALUES(1, '01-JAN-2009 2:00:00 AM -07:00');

1 row created.

SQL> INSERT INTO table_tstz VALUES(2, TIMESTAMP '2009-01-01 2:00:00');

1 row created.

SQL> INSERT INTO table_tstz VALUES(3, TIMESTAMP '2009-01-01 2:00:00 -8:00');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from table_tstz;

      C_ID C_TSTZ
---------- ---------------------------------------------------------------------------
         1 01-JAN-09 02:00:00.000000 AM -07:00
         2 01-JAN-09 02:00:00.000000 AM -07:00
         3 01-JAN-09 02:00:00.000000 AM -08:00
Note: 第三条数据保存了时区信息! 可以和上一个例子TIMESTAMP类型做一个对比。

操作TIMESTAMP WITH LOCAL TIME ZONE数据类型

SQL> ALTER SESSION SET TIME_ZONE='-07:00';

Session altered.

SQL> CREATE TABLE table_tsltz (c_id NUMBER, c_tsltz TIMESTAMP WITH LOCAL TIME ZONE);

Table created.

SQL> INSERT INTO table_tsltz VALUES(1, '01-JAN-2009 2:00:00');

1 row created.

SQL>  INSERT INTO table_tsltz VALUES(2, TIMESTAMP '2009-01-01 2:00:00');

1 row created.

SQL> INSERT INTO table_tsltz VALUES(3, TIMESTAMP '2009-01-01 2:00:00 -08:00');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from table_tsltz;

      C_ID C_TSLTZ
---------- ---------------------------------------------------------------------------
         1 01-JAN-09 02:00:00.000000
         2 01-JAN-09 02:00:00.000000
         3 01-JAN-09 03:00:00.000000

Note: 插入的第三条数据指定为UTC-8时区的时间,然后存入数据库后按照database timezone的时间保存,最后在客户端请求的时候,转换为客户端时区的时间(UTC-7)返回!可以参考以下简单实验:

SQL> ALTER SESSION SET TIME_ZONE='-05:00';

Session altered.

SQL> select * from table_tsltz;

      C_ID C_TSLTZ
---------- ---------------------------------------------------------------------------
         1 01-JAN-09 04:00:00.000000
         2 01-JAN-09 04:00:00.000000
         3 01-JAN-09 05:00:00.000000

可以看出,当客户端时区改为UTC-5的时候,TIMESTAMP WITH LOCAL TIME ZONE数据类型的返回信息是会相应改变的。

在了解了相关数据类型后,那么我们该如何在它们之间做出选择呢?

当你不需要保存时区/地区信息的时候,选择使用TIMESTAMP数据类型,因为它一般需要7-11bytes的存储空间,可以节省空间。

当你需要保存时区/地区信息的时候,请选择使用TIMESTAMP WITH TIME ZONE数据类型。比如一个跨国银行业务应用系统,需要精确纪录每一笔交易的时间和地点(时区),在这种情况下就需要纪录时区相关信息。因为需要纪录时区相关信息,所以需要多一些的存储空间,一般需要13bytes。

当你并不关心操作发生的具体地点,而只是关心操作是在你当前时区的几点发生的时候,选择使用TIMESTAMP WITH LOCAL TIME ZONE。比如一个全球统一的change control system。用户可能只关心某某操作是在我的时间几点发生的(比如中国用户看到的是北京时间8:00am,而伦敦的用户看到的是0:00am)。记住,此类行不保存时区/地区信息,因此如果需要保存相关信息的要慎重!

3. 时区相关的几个函数

DBTIMEZONE -- Returns the value of the database time zone. The value is a time zone offset or a time zone region name.

SESSIONTIMEZONE -- Returns the value of the current session's time zone.

CURRENT_DATE -- Returns the current date in the session time zone in a value in the GreGorian calendar, of the DATE datatype.
 
CURRENT_TIMESTAMP -- Returns the current date and time in the session time zone as a TIMESTAMP WITH TIME ZONE value.

SYSDATE -- Returns the date and time of the operating system on which the database resides, taking into account the time zone of the database server's operating system that was in effect when the database was started.
 
SYSTIMESTAMP -- Returns the system date, including fractional seconds and time zone of the system on which the database resides.
 
Note: SYSDATE和SYSTIMESTAMP的返回信息是数据库所在操作系统的信息,和当前session的时区无关!

例:

数据库时区为+08:00,当前session时区为-05:00时:

SQL> select dbtimezone from dual;

DBTIME
------
+08:00

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
---------------------------------------------------------------------------
-05:00

SQL> select current_date from dual;

CURRENT_DATE
-------------------
2009-01-12 06:18:24

SQL> select current_timestamp from dual;

CURRENT_TIMESTAMP
---------------------------------------------------------------------------
12-JAN-09 06:18:36.625000 AM -05:00

SQL>
SQL> select sysdate from dual;

SYSDATE
-------------------
2009-01-12 19:18:42

SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
12-JAN-09 07:18:52.921000 PM +08:00

SQL>

把当前session时区改为+09:00以后:

SQL> alter session set time_zone='+09:00';

Session altered.

SQL>
SQL> select dbtimezone from dual;

DBTIME
------
+08:00

SQL> select sessiontimezone from dual;

SESSIONTIMEZONE
---------------------------------------------------------------------------
+09:00

SQL> select current_date from dual;

CURRENT_DATE
-------------------
2009-01-12 20:19:54

SQL>
SQL> select current_timestamp from dual;

CURRENT_TIMESTAMP
---------------------------------------------------------------------------
12-JAN-09 08:20:07.218000 PM +09:00

SQL>
SQL> select sysdate from dual;

SYSDATE
-------------------
2009-01-12 19:20:24

SQL> select systimestamp from dual;

SYSTIMESTAMP
---------------------------------------------------------------------------
12-JAN-09 07:20:30.921000 PM +08:00

SQL>

从以上例子可以看出,SYSDATE和SYSTIMESTAMP的返回结果是不随SESSION时区的改变而改变的,其实从函数的命名就能看出(一组是system的,一组是current的~):D

总结: 由于这次case涉及到的东西就那么多,因此总结起来也没有面面俱到,所有东西都包括。这里只是简单的总结了怎么查看和修改数据库/session时区,相关的data types和functions。还有诸如Interval Datatypes(存储的是时间间隔), Daylight Saving Time(夏令时,我到现在还不是很清楚~)以及其他functions,parameters等等都没有涉及。

关于time zone的系统介绍,请参考 Oracle Database Globalization Support Guide, Chapter 4 。还有其他的 官方文档 metalink 都可以作为参考。

PS:小小case一则~

应用层用户发现sysdate信息不对,本应为+09:00的时间,却显示为-05:00时区的时间,要求修改数据库timezone。其实sysdate返回信息和数据库timezone设置无关,遂去查看操作系统信息。发现果然是操作系统层设置就存在问题。但当时的问题是操作系统又不能随便重启,问题变得很棘手!

后来经过同事建议,设置了操作系的session信息:setenv TZ Japan。然后重启了listener和database。之后所有经过listener连接到数据库的用户select sysdate from dual;的结果都是正确的信息,而没有通过listener连接的用户得到的则还是错误的信息,因为操作系统本身的时区并没有更新。据说在session级别设置好时区信息后,只要重启listener就足够了,个人没有试过,有兴趣的可以尝试下~

问题的根本解决方法还是要修改操作系统的时区设置,但有个临时的解决方案也是不错的了:)

还有一些关于字符集、地区等国际化特性的总结,以后整理下慢慢都发出来吧...:)


您可能感兴趣的文档:

--结束END--

本文标题: 关于Oracle Timezone的一点总结

本文链接: https://www.lsjlt.com/news/46356.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 关于Oracle Timezone的一点总结
    原文:http://blog.itpub.net/9765498/viewspace-539881 背景描述: 如果需要支持一个国际化的应用,那么数据库端的国际化特性的支持也就显...
    99+
    2022-10-18
  • 关于oracle 11g acs的一点总结:
    今天谈谈下面这几个参数对数据库性能和稳定性的影响: cursor_sharing:游标共享 _optim_peek_user_binds:绑定变量窥视 _optimizer_adapt...
    99+
    2022-10-18
  • 关于oracle的一点备忘
    数据库无法回避的就是处理数据情景:发票信息,很多公司员工在进行交易的时候,填写的发票信息都是一样的,所以公司员工往往想调用统一的发票信息,公司会计登录系统可以填写通用发票信息,为了生成订单简单,发票需要和员...
    99+
    2022-10-18
  • R语言关于“包”的知识点总结
    R语言的包是R函数,编译代码和样本数据的集合。 它们存储在R语言环境中名为“library”的目录下。 默认情况下,R语言在安装期间安装一组软件包。 随后添加更多包,当它们用于某些特...
    99+
    2022-11-12
  • 关于STL中list容器的一些总结
    1.关于list容器 list是一种序列式容器。list容器完成的功能实际上和数据结构中的双向链表是极其相似的,list中的数据元素是通过链表指针串连成逻辑意义上的线性表,也就是li...
    99+
    2022-11-15
    STL list
  • 关于STL中vector容器的一些总结
    1.vector的简单介绍 vector作为STL提供的标准容器之一,是经常要使用的,有很重要的地位,并且使用起来也是灰常方便。vector又被称为向量,vector可以形象的描述为...
    99+
    2022-11-15
    STL vector
  • R语言关于变量的知识点总结
    变量为我们提供了我们的程序可以操作的命名存储。 R语言中的变量可以存储原子向量,原子向量组或许多Robject的组合。 有效的变量名称由字母,数字和点或下划线字符组成。 变量名以字母...
    99+
    2022-11-12
  • 关于Mybatis动态sql中test的坑点总结
    目录总结Mybatis动态sql中test的坑判断相等的注意点判断字符是否相等动态sql标签的小陷阱下面先举个正常的例子总结Mybatis动态sql中test的坑 在mybatis中...
    99+
    2022-11-12
  • 关于STL中的map容器的一些总结
    一、关于map的介绍 map是STL的一个容器,和set一样,map也是一种关联式容器。它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键...
    99+
    2022-11-15
    STL map
  • SoapClient的一点总结
    SoapClient是一个用于访问SOAP(Simple Object Access Protocol) Web服务的客户端类。它提...
    99+
    2023-09-28
    SoapClient
  • 关于jboss配置的总结
    安装/配置apache 2.2.4 和 mod_jk1.1配置负载均衡2、安装/配置jboss2.1 安装jdk1.5.112.2 解压jboss2.3 修改server.xml ,适应负载均衡。2.4 修改server.xml ,配置支持...
    99+
    2023-06-03
  • mysql中关于覆盖索引的知识点总结
    如果一个索引包含(或覆盖)所有需要查询的字段的值,称为‘覆盖索引'。 覆盖索引是一种非常强大的工具,能大大提高查询性能,只需要读取索引而不需要读取数据,有以下优点: 索引项通常比记录要小,所以MySQL访问更少的数据...
    99+
    2022-05-17
    mysql 覆盖索引
  • 关于C++中的友元函数的一些总结
    1.友元函数的简单介绍 1.1为什么要使用友元函数 在实现类之间数据共享时,减少系统开销,提高效率。如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是...
    99+
    2022-11-15
    友元函数 C++
  • R语言关于决策树知识点总结
    决策树是以树的形式表示选择及其结果的图。图中的节点表示事件或选择,并且图的边缘表示决策规则或条件。它主要用于使用R的机器学习和数据挖掘应用程序。 决策树的使用的例子是 预测电子邮件是...
    99+
    2022-11-12
  • 关于MySQL自增ID的一些小问题总结
    下面这几个小问题都是基于 InnoDB 存储引擎的。 1. ID最大的记录删除后,新插入的记录ID是什么 例如当前表中有ID为1,2,3三条记录,把3删除,新插入记录的ID从哪儿开始? 答案: 从4开始。...
    99+
    2022-10-18
  • 关于Python面向对象编程的知识点总结
    前言 如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程。 接下来我们就来了...
    99+
    2022-06-04
    知识点 面向对象 Python
  • mysql关于db.opt文件的总结
    总结 1、create database时会自动生成一个文件db.opt,存放的数据库的默认字符集,show create database时显示数据库默认字符集即db.opt中字符集 2、这...
    99+
    2022-10-18
  • 关于SpringBoot使用@Async的总结
    目录SpringBoot使用@Async总结如下方式会使@Async失效SpringBoot实现异步(Async)接口1. 启动类引入@EnableAsync注解2. 建立异步任务类...
    99+
    2022-11-12
  • 关于PaaS的纯干货总结
    关于PaaS的纯干货总结什么是PaaS PaaS是面向应用的核心平台。 从功能定义和核心价值分为三个层次:   1)自动化获取资源进行部署;   2)提供标准化的编程框架和服务来帮助应用开发和运行实现...
    99+
    2023-06-03
  • R语言关于二项分布知识点总结
    二项分布模型处理在一系列实验中仅发现两个可能结果的事件的成功概率。 例如,掷硬币总是给出头或尾。 在二项分布期间估计在10次重复抛掷硬币中精确找到3个头的概率。 R语言有四个内置函数...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作