【问题标题】:Converting dates from different centuries转换不同世纪的日期
【发布时间】:2017-11-14 19:14:29
【问题描述】:

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

【问题讨论】:

  • 默认日期转换将当前年份的前 2 位数字添加到日期格式中。如果您希望将 34 年视为 1934 而不是 2034,则必须在 34 之前附加 19。
  • 你试过to_date('03/20/1934','mm/dd/rrrr') 吗?
  • @kraj,你怎么知道 34 年是 1934 年而不是 2034 年。所以应该有一些标志/机制让编译器知道它的 1934 年不是 2034 年。
  • @Debabrata “默认日期转换将当前年份的前 2 位数字添加到日期格式中” - 这不太正确。如果年份的最后两位数字介于 50 和 99 之间,则使用 RR 表示年份的格式(例如,'DD-MON-RR' 的默认 nls_date_format )将(截至今天)返回 19 世纪,如果它们在 00 到 49 之间,则为 20。
  • 经典 Year 2000 problem - 但我真的很惊讶它仍然在 2017 年发生。你没有发现这个错误 17 年吗?

标签: oracle date oracle11g


【解决方案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

【讨论】:

  • 感谢您的建议。我会将数据源更正为 4 位数年份,这样无论年份如何,我的流程逻辑都保持良好。
  • @kraj,不要只是将数据源更改为在字符串中存储 4 位数年份 - 而是使用 Oracle 的内置 DATE 数据类型。
  • 感谢历史背景资料及解答。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 2015-07-13
    相关资源
    最近更新 更多