Dates and Timestamps总结
上一篇 / 下一篇 2007-05-30 10:29:41 / 个人分类:笔记
Dates and Timestamps总结
CNOUG博客首页"g.[[7i2i^&Si1.Datetime Datatypes
1LH%w.m(d'W)GJAw0 DATECNOUG博客首页[:K%ee0] oJ5d jE
存储日期、时间,没有时区,精确到秒,是 9i 之前唯一的 datetime datatype。
Zi;A9~_r!K.g"NPE0 TIMESTAMP [(precision)]CNOUG博客首页Y9qN3o)lv5~8NU
除了最多精确到 billionth of a second,其他和 DATE 一样。
'x,?8hf#G[z&o0 TIMESTAMP [(precision)] WITH TIME ZONE
+G `.H!dlaE(R7b0 TIMESTAMP 的基础上,保存时区信息。在内部存储时,Oracle 将时间转换为 UTC 格式进行保存,比如:2002-02-06 20:00:00:00.00 -5:00。CNOUG博客首页#`/\_)Lx7w+e'H'a
TIMESTAMP [(precision)] WITH LOCAL TIME ZONECNOUG博客首页f8q7Hkw`:r
不保存时区信息,但会将时间转换为数据库的时区(如果是保存到数据库表的列中)或者 session 的时区(如果保存为 PL/SQL variables)。数据在不同时区间传输时,会进行转换,但不保存时区信息。
3HeE0k,q3lm/?0 其中 precision 表示秒的小数部分保留的位数,范围为:0~9。
gJ
{$hOc0
(o1@RCU!E0ll0 如何选择 Datetime DatatypeCNOUG博客首页*q$`-S
NB7L6Z
Hx
1.如果你要精确到秒的小数位,那么使用 TIMESTAMPCNOUG博客首页o/T6gN:g
2.如果要保留 datetime 值的时区,那么使用 TIMESTAMP WITH TIME ZONE
p2Zn2hk!_0?X0 3.可以用 TIMESTAMP(0) 代替 DATE,但是两者的日期算法是不同的
OwXfad,Td0 4.为了兼容 TIMESTAMP 出现之前的应用程序,那么使用 DATE
9Ax&[#kqhQ0 5.PL/SQL 代码中的类型应该和数据库表中的类型相一致,比如将 TIMESTAMP WITH TIME ZONE 的类型存放到 DATE 类型的列中,时区就会丢失CNOUG博客首页 @J M2Z-TT(t r(y
6.使用 9i 以前的版本,那么只能使用 DATE
0zkBuM0 7.将 ADD_MONTHS 这种传统操作 DATE 类型的函数应用到新的 TIMESTAMP 类型上,会产生很大的不同CNOUG博客首页d-BWU(Z2bc
aP J\
2.获得现在的时间
oK*kq:L
G`4R0U3@+Ta0 Function Time zone Datatype returnedCNOUG博客首页8j j8Yc1p4|'~OX-J
CURRENT_DATE Session DATE
&Qr'y\*a!_,J+kr0 CURRENT_TIMESTAMP Session TIMESTAMP WITH TIME ZONE
9n$P5xfC4G
B0 LOCALTIMESTAMP Session TIMESTAMPCNOUG博客首页:T'q QO8jC ?
SYSDATE Server DATE
]9r3KteWW%t0 SYSTIMESTAMP Server TIMESTAMP WITH TIME ZONE
注:返回的都是数据库服务器端的当时时间,单前三者会转换为 session 的时区,可以用 alter session set time_zone 改变CNOUG博客首页n,E4?,i2@5\6I7m%H!vR
9i 之前只有 SYSDATECNOUG博客首页oc+hF4o3RO
j R1_wC \g5I q0
3.Interval Datatypes
Obb+C.E.T_:f0 INTERVAL YEAR TO MONTH
kIVlL*jr4d0 Allows you to define an interval of time in terms of years and months.
O'u-|.Bm3C?0 INTERVAL YEAR [(year_precision)] TO MONTHCNOUG博客首页:A0w:lP4N[*Z1]
year_precision:year 的位数,范围:0~4,默认:2CNOUG博客首页
g9Y:n5\LH
INTERVAL DAY TO SECONDCNOUG博客首页/BG
T.e#Y}
uy+[f~fK
Allows you to define an interval of time in terms of days, hours, minutes, and seconds (including fractional seconds).CNOUG博客首页1M@E-K i\H
INTERVAL DAY [(day_precision)] TO SECOND [(frac_sec_prec)]
5uVuC^4U/x0 day_precision:day 的位数,范围:0~9,默认:2
g@1^Uw M:O#@2L"g0 frac_sec_prec:秒小数部分保留的位数,范围:0~9,默认:6CNOUG博客首页Y M1h2{p7j
M#Z
CNOUG博客首页#RS3MU$P+A
Month、hour、minute、second 的精度是不用设置的,Oracle 会保证他们的范围分别在 0~11、0~23、0~59、0~59
z-@*Mg)WGP0
CNOUG博客首页TMK.NJh
I.ni8[5C
4.Datetime Conversions
)R&Cd+BW6q0 Date 范围:CNOUG博客首页poXm1r'r4o;o+g4G
4712-01-01 B.C. —— 9999-12-31 A.D.CNOUG博客首页8o$k&lZYA*U
/QWFM?/q0 From Strings to Datetimes
5Ap/}a6u]9?-w+t0 隐式:
)C_;s$kAg~I|:x0 根据 NLS_DATE_FORMAT 的格式写 String 的值,Oracle 会隐式转换,如果和 NLS_DATE_FORMAT 不匹配,不能转换。
0e],y7fs8kY0 显式(使用内建函数):
m/uJ,O@ [F&f0 TO_DATE( string[, format_mask[, nls_language]])CNOUG博客首页2Z]\FJA7F TV$v
TO_DATE( number[, format_mask[, nls_language]])
#X)U.X{F+H0 用数字表示 Julian date 转换为 Date 类型,此时 format_mask = 'J',number 表示从 January 1, 4712 B.C. 开始的天数,由于 Oracle 中最大日期是 December 31, 9999 A.D.,所以 number 的范围为:1 ~ 5373484CNOUG博客首页W d7cV;n&v
A
TO_TIMESTAMP( string[, format_mask[, nls_language]])
Vj5d
_$I0 TO_TIMESTAMP_TZ( string[, format_mask[, nls_language]])
?1Z'B%T&V0 此函数用于将 string 转换为 TIMESTAMP WITH TIME ZONE、TIMESTAMP WITH LOCAL TIME ZONECNOUG博客首页7lV4k1S"z
|z;Z:T
format_mask:CNOUG博客首页x5O2z Rq
默认为 NLS_DATE_FORMAT、NLS_TIMESTAMP_FORMAT、NLS_TIMESTAMP_TZ_FORMAT(分别对应 TO_DATE、TO_TIMESTAMP、TO_TIMESTAMP_TZ)CNOUG博客首页)`f.{n.H _Z
对于 TIMESTAMP 类型,秒的小数部分可以用 '.FF' 或者 'XFF' 表示,比如:'mm/dd/yyyy hh:mi:ss.ff AM TZD' or 'mm/dd/yyyy hh:mi:ssxff AM TZD',其中 'X' 由 NLS_NUMERIC_CHARACTERS 的第一个字符决定。
v\$U8mk0WN0 nls_language:
0r \G@.P)V'il|'V0 Optionally specifies the language to be used to interpret the names and abbreviations of both months and days in the string.
}(L)@,e*mY0 几个限制:
r
i:Tp??0 1.传给 TO_DATE 中的 string 长度不能超过 220 个字符。
9u6r
Gg8D0 2.format mask 中 Julian date element (J) 和 the day of year element (DDD) 不能同时出现。
_j:v2| H;?g0 3.format mask 中 date/time 的某一个部分不能重复出现,比如:'YYYY-YYY-DD-MM'
dV,a%~"S/u0 4.format mask 中 HH24 不能和 am/pm 同时出现CNOUG博客首页+k8\U
uNz
?"{yt}9f6N$O'}[ ~0 From Datetimes to Strings
1R/n0Z!JQ0 使用 TO_CHAR,默认格式 'DD-MON-RR'(9 位),可以用 NLS_DATE_FORMAT 覆盖。CNOUG博客首页#zc@5[N:?#v
对于 TIMESTAMP 类型,秒的小数部分可以用 FF1 ~ FF9 来表示保留几位(自动四舍五入)。CNOUG博客首页)?:UZx%V4B
不能将用于 TIMESTAMP 的 format_mask 用于 DATE 类型,否则会报 ORA-01821,反过来可以。
;J u6ELm%@A0
3jw*\LU0 Working with Time ZonesCNOUG博客首页~2e7g;\-@;v
明确表示某一个时区,应该联合使用 TZH TZM 或者 TZR TZDCNOUG博客首页}e4z9i3o.[ DP
TZH:与 UTC 之间 HOUR 的偏移CNOUG博客首页"gI5gx6WA2U#n-g
TZM:与 UTC 之间 MINUTE 的偏移CNOUG博客首页.{#_8gms,bx
TZR:The time zone region
Fw)^-d j}F0 TZD:The abbreviated time zone nameCNOUG博客首页F4f4d3U8w.gEd
注:后两者可以查看 V$TIMEZONE_NAMES 获得
HrN [6GC0 对于时区,存入的是什么信息,显示的也是什么信息,比如用 TZH:TZM 存入和 UTC 之间的偏移,就只能显示类似 +08:00 的时区偏移,而无法显示具体哪个 time zone region
r'atF#M7j#o WOV0
u1T4FB&h5N;M0 二位数年份的处理CNOUG博客首页5]%~RdIULjj
使用 RR/RRRR 时,Oracle 自动根据现在的年份辨别输入的二位数年份:CNOUG博客首页\zoivC;L9m;r
1.如果现在是前半世纪(0~49)
`
Y9T&Ex&E4b0 如果输入的是前半世纪(0~49),那么返回本世纪的年份
U#p4cF1E5N0 如果输入的是后半世纪(50~99),那么返回上世纪的年份CNOUG博客首页aE%z^T
2.如果现在是后半世纪(50~99)
AP2?]r0w,?/w"{0 如果输入的是前半世纪(0~49),那么返回下世纪的年份CNOUG博客首页rex|R
如果输入的是后半世纪(50~99),那么返回本世纪的年份CNOUG博客首页T p.sJ6a2F
使用 YY/YYYY 时,不管输入的是什么,都返回本世纪的年份
$l#p%F,tl!_0 注:这种自动转换只适用于 String -> Date 的转换,如果是 Date -> String,那就按照 Date 存储的值来转换,此时再用 RR/RRRR 已经没有意义了,因为 Oracle 内部存储的年份是四位数的。CNOUG博客首页e&|)C-[fz
]U d
5.Date and Timestamp LiteralsCNOUG博客首页[Yt[$p
B?
这是 9i 之后 引入的 ISO SQL standard 格式,格式是固定的,不能更改,也不受环境变量影响,因此可以作为常量来使用
et
K y.]:r
v0 DATE 'YYYY-MM-DD'
+O0CK'z5R5F7QSb0 TIMESTAMP 'YYYY-MM-DD HH:MI:SS[.FFFFFFFFF] [{+|-}HH:MI]' (HH 必须是 24 小时制的,FFFFFFFFF 可选 1~9 位,也可以没有,时区也可以使用 time zone region(EST),但这只是 Oracle 提供的格式,不是 ANSI/ISO standards)
RS7iSc pg#X0 例子:CNOUG博客首页!Y;d,i5E7pdwkt
DATE '2002-02-19'CNOUG博客首页q;sqt!O.So
TIMESTAMP '2002-02-19 14:00:00.000000000 -5:00';
5s,Q)\7{}*h ]0 CNOUG博客首页,|gnpaR:_:r2GK N
CNOUG博客首页t^|4R `}
6.Interval ConversionsCNOUG博客首页/`4Z\-QM
Numbers to IntervalsCNOUG博客首页 E#qL
h qEB
NUMTOYMINTERVAL ( n , 'char_expr' )CNOUG博客首页8_S_p7]
NUMTODSINTERVAL ( n , 'char_expr' )CNOUG博客首页 J9Pzu*y0?h"W,}+F
char_expr:
0p9L)A8HcqM0 Name DescrīptionCNOUG博客首页h j%d9[:fMNO
YEAR Some number of years, ranging from 1 through 999,999,999CNOUG博客首页#p*Wc1N|1\
MONTH Some number of months, ranging from 0 through 11
/F$k(~6A8L|}0 DAY Some number of days, ranging from 0 to 999,999,999CNOUG博客首页(a3KS)LI_W [8l]
HOUR Some number of hours, ranging from 0 through 23
)})vO+k
@3B&LQ0 MINUTE Some number of minutes, ranging from 0 through 59
2FBY:m%C,hS&\|$Q0 SECOND Some number of seconds, ranging from 0 through 59.999999999CNOUG博客首页~3V3g5}`#T%sv
以上不区分大小写
/j+owi+x0
+qv7V1gT.haf
A0 Strings to Intervals
WXg0n}|0 TO_YMINTERVAL('Y-M')CNOUG博客首页sD/u d(h
TO_DSINTERVAL('D HH:MI:SS')
+J1fk3N~C|:q0 格式是固定的,不能缺少任何一个部分CNOUG博客首页y9\1KmwFIW^
CNOUG博客首页N{,aoa:e'x
eS"_d
g%yf6|;N4G07.Interval Literals
