混合和匹配数据类型以生成所需的日期格式 mm/dd/yyyy

Posted

技术标签:

【中文标题】混合和匹配数据类型以生成所需的日期格式 mm/dd/yyyy【英文标题】:mixing and matching data types to produce a desired date format of mm/dd/yyyy 【发布时间】:2021-12-14 02:47:22 【问题描述】:

让我从我有一个混乱的 Oracle 表开始,其中有 2 个特定的列,1 个用于已发布的 VARCHAR2(10),一个用于 compdate VARCHAR2(8)。系统会话的 NLS_DATE_FORMAT 是 'YYYY-MM-DD HH24:MI:SS'。我无法更改 NLS_DATE_FORMAT,因为有一组重要的 SELECT 使用此格式将其他时间戳转换为日期。

发行日期为 'MMDDYYYY' COMPDATE 为 'MM/DD/YYYY'

这里是有问题的 Select 部分

    co.issuedate issued,
    to_date(substr(ae.cdts, 1,8)) DATE_JOB_OPENED,
    TO_DATE(substr(ae.xdts, 1,8)) DATE_JOB_CLOSED, 
    co.compdate WORKED,

目标是减法

    issued-WORKED

并以天数为单位获得结果。

感谢指导

【问题讨论】:

不要将日期值存储为字符串。不要在函数的第二个参数中指定格式模型的情况下使用TO_DATE 取两个日期的差并得到 mm/dd/yyyy 格式的结果并没有什么意义。如果你今天做了 - 昨天你期望得到 00/01/0000? @eaolson - 谢谢。我编辑了原始问题 @mto - 如果不对下游应用程序造成相当大的风险,我无法真正改变 12 年前所做的事情,因此日期值必须是一个字符串。我会在下面给出你的解决方案 【参考方案1】:

解决方案的第一部分应该是修复您的表,以便您将日期值存储在 DATE 数据类型中,而 NOTVARCHAR2 中。

解决方案的第二部分应该是返回所有旧代码并修复使用TO_DATETO_CHAR 的任何实例,以确保它们始终传递第二个参数以显式设置格式模型和永远不要依赖 NLS_DATE_FORMAT 会话参数设置的隐式格式模型。


由于您将其存储为 VARCHAR2,因此只需使用 TO_DATE 并减去即可:

SELECT co.issuedate issued,
       TO_DATE(substr(ae.cdts, 1,8), 'YYYYMMDD') DATE_JOB_OPENED,
       TO_DATE(substr(ae.xdts, 1,8), 'YYYYMMDD') DATE_JOB_CLOSED, 
       co.compdate WORKED,
       TO_DATE(co.issuedate, 'MMDDYYYY') - TO_DATE(co.compdate, 'MM/DD/YYYY')
         AS days_difference
FROM   ...;

并以 mm/dd/yyyy 格式获取结果。

如果您真的想要天、月和年的差异,那么它会变得更加复杂:

SELECT issued,
       DATE_JOB_OPENED,
       DATE_JOB_CLOSED,
       worked,
       TO_CHAR(
         EXTRACT(MONTH FROM (issued_date - comp_date) YEAR TO MONTH),
         'FM00'
       )
       ||'/'||
       TO_CHAR(
         issued_date - ADD_MONTHS(comp_date, FLOOR(MONTHS_BETWEEN(issued_date, comp_date))),
         'FM00'
       )
       ||'/'||
       TO_CHAR(
         EXTRACT(YEAR FROM (issued_date - comp_date) YEAR TO MONTH),
         'FM0000'
       ) AS difference
FROM   (
  SELECT co.issuedate issued,
         TO_DATE(substr(ae.cdts, 1,8), 'YYYYMMDD') DATE_JOB_OPENED,
         TO_DATE(substr(ae.xdts, 1,8), 'YYYYMMDD') DATE_JOB_CLOSED, 
         co.compdate WORKED,
         TO_DATE(co.issuedate, 'MMDDYYYY') AS issued_date,
         TO_DATE(co.compdate, 'MM/DD/YYYY') AS comp_date
  FROM   table_name co
         -- ...
);

其中,对于样本数据:

CREATE TABLE table_name (issuedate, compdate) AS
SELECT '10292021', '01/01/2021' FROM DUAL;

co 相关列的输出:

ISSUED WORKED DIFFERENCE
10292021 01/01/2021 10/28/0000

db小提琴here

【讨论】:

以上是关于混合和匹配数据类型以生成所需的日期格式 mm/dd/yyyy的主要内容,如果未能解决你的问题,请参考以下文章

使用 JQuery Validate 以“mm-dd-yyyy”和“mm/dd/yyyy”格式验证日期

将输入日期数据类型更改为 DD/MM/YYYY 而不是 MM/DD/YYYY 需要 [重复]

接受不同类型日期格式的掩码格式化程序

使用 PHP 将 mm/dd/yyyy 格式转换为纪元

我需要在 Access 中拆分以 MM/YYYY 和 MM/DD/YYYY 格式存储日期的文本列,以删除日期格式

PHP MailChimp生日字段的日期格式 - 格式正确吗?