0

我的问题与第 5 个命令有关。

  1. create ex_table(on_date date);

  2. insert into ex_table values(to_date('23-aug-75','dd-mm-rr'));

  3. insert into ex_table values(to_date('23-aug-75','dd-mm-yy'));

应用上述3条命令后(2015年执行):

  1. select to_char(on_date,'dd-mm-yyyy') from ex_table;

结果:

on_date
-------
23-aug-1975
23-aug-2075
  1. select to_char(on_date,'dd-mm-yyyy') from ex_table where on_date='23-aug-75';

结果:

on_date
-------
23-aug-1975

为什么是第 5 个命令的结果23-aug-1975而不是23-aug-2075或两者兼而有之?

我问这个是因为如果不执行命令 #2,那么结果肯定会包含23-aug-2075.

4

2 回答 2

2

当你这样做

where on_date='23-aug-75'

它实际上将其翻译为:

where on_date=to_date('23-aug-75') -- without the fmt parameter.

因为没有明确指定格式,所以字符串被解析并根据当前nls_date_format会话值转换为日期。最有可能的是,您的会话值是DD-MON-RR. 您可以通过查询来检查:

select value
from nls_session_parameters
where parameter = 'NLS_DATE_FORMAT';

如果是这种情况,那么The RR Datetime Format Element75上的文档解释了如果当前日期是,如何确定字符串的年份2015

如果指定的两位数年份是 50 到 99,那么 [...] 如果当前年份的后两位数是 00 到 49,那么返回年份的前 2 位数字比前 2 位数字小 1本年度。

因此,当您应用条件时,应用上述规则:

where on_date='23-aug-75'

...然后它正在寻找 1975 年 8 月 23 日的日期。

在您的问题中,您还说:

我问这个是因为如果不执行命令 #2,那么结果肯定会包含23-aug-2075.

我不得不不同意这种说法。除非您nls_date_format将会话值更改为类似DD-MON-YY.

这就是解释。但就最佳实践而言,为什么不始终明确说明您使用的日期格式并始终使用 4 位数年份格式,或者使用YYYY-MM-DD清晰易用的 ISO 格式,从而完全避免歧义。

于 2015-07-23T19:23:52.890 回答
0

RR 代表世纪,YY 代表年

您可以按照 sstan 的建议检查数据库的日期格式。

我是这样记的。

规则1 :

如果当前年份介于 00-49 之间,并且您提供的值介于 00-49 之间,那么世纪将不会发生变化,即 2015 年是当前年份并且您传递了一个值 30,那么 30 将被解释为 2030

规则 2:

如果当前年份介于 00-49 之间,并且您提供的值介于 50-99 之间,则存在的世纪为负 1,即 2015 年是当前年份,并且您传递了值 75,那么 75 将被解释为 1975。

规则 3:

假设当前年份在 50-99 之间,并且您提供了 00-49 之间的值,那么世纪将为世纪 + 1,即如果当前年份是 2060 并且您提供了值 23,那么它将被解释为 2161

规则 4:

假设当前年份在 50-99 之间,并且您提供的值介于 50-99 之间,那么世纪不会发生变化,即如果当前年份是 2060 并且您提供了值 56,那么它将被解释为 2056

于 2015-07-23T20:47:04.407 回答