转换不同世纪的日期

时间:2017-06-13 06:48:36

标签: oracle date oracle11g

我有一个临时表,其中包含日期为字符串,格式为' mm / dd / yy'。在加载到主表之前,我有Oracle 11g过程将字符串转换为日期格式。我使用to_date('03/20/34','mm/dd/rr')转换为日期格式,错误输出为03/20/2034,而正确的日期是03/20/1934。请帮助我获取正确的输出,其中我的表包含几个世纪的日期。

2 个答案:

答案 0 :(得分:1)

  

“我正在使用to_date('03 / 20/34','mm / dd / rr')转换为日期格式,它提供错误的输出为03/20/2034,而正确的日期是03/20 / 1934年。“

RR是甲骨文在上一个千年中引入的黑客行为,是解决the Y2K bug的斗争的一部分。标准日期掩码YY将世纪默认为当前世纪。但在1999年,01/01/00更可能意味着01/01/2000而不是01/01/1900。所以RR hack是使用在00上旋转的固定窗口来推导日期世纪:值00-49给出世纪20,给出50-99 19。显然,有些时候这种猜测是错误的,但引入的数据损坏程度低于将所有日期默认为世纪19

关键是,窗户是固定的。它本来是一个临时解决方案,因为没有时间将所有遗留系统切换到2000年到来之前使用四位数年份。但愿景始终是所有系统都将在长期内得到修复,即使只是通过退休或更换。当然没有人预计会建造支持两位数年份的新​​系统。

现在 2017 ,并且没有理由让系统仍然使用两位数年份。在过去的日子里,存储空间很昂贵,从日期开始刮两位数就可以节省宝贵的空间。现在只是邋。了。

这显然无法帮助您解决问题。简短的回答是无法更改RR使用的支点。最好的解决方案是对系统的数据输入方面实施更严格的验证,并坚持四位数年。这是否可行取决于你的办公室政治。另一种解决方案是编写自己的转换函数:

 create or replace function my_to_date (p_str varchar2) return date as
 begin
     if to_number(substr(p_str, 7) <= 35 then
         return to_date(substr(p_str, 1, 6)||'19'||substr(p_str, 7), 'dd/mm/yyyy');
     else
         return to_date(substr(p_str, 1, 6)||'20'||substr(p_str, 7), 'dd/mm/yyyy');
 end;

显然,您需要定义用于决定是使用19还是20的实际规则。

答案 1 :(得分:0)

在插入90年代后期的日期值时,我也遇到了类似的问题。脚本中的格式为DD-MON-YY,因此数据库将其读取为20YY,而不是19YY。

我非常优雅的解决方案是打开原始数据文件,并在YY年值之前添加一个“ 19”。