在 Oracle 中添加一天但丢失小时和分钟,并且格式也在发生变化

Adding a day in Oracle but losing hour and minute, and format is also changing

我有一个 table tab1,其中列 col1 的数据类型为 VARCHAR2(50 BYTE) 并且此列的值类似于 '9/27/21 18:05'

我想为此添加 1 天,我希望得到像“9/28/21 18:05”这样的结果

如果我这样做

TO_TIMESTAMP(col1,'MM/DD/YYYY HH24:MI') + INTERVAL '1' DAY

然后我得到“28-SEP-21 06.24.00.000000000 PM”,如果我这样做

TO_DATE(col1,'MM/DD/YYYY HH24:MI') + INTERVAL '1' DAY'

然后我得到“28-SEP-21”。

请注意,以上两种情况的格式都在变化。

怎样才能得到我想要的结果?

您正在将字符串转换为日期或时间戳,并按天进行调整。然后您的客户决定如何格式化显示,通常使用您的会话设置,如 NLS_DATE_FORMAT.

如果您想以特定格式显示(或存储*)值,则应使用 to_char() 指定,例如:

TO_CHAR(TO_DATE(col1,'MM/DD/YYYY HH24:MI') + INTERVAL '1' DAY,'MM/DD/YYYY HH24:MI')
09/28/0021 18:05

或者,如果您想抑制一些前导零以匹配您的原始字符串,您可以使用 the FM modifier:

切换它们
TO_CHAR(TO_DATE(col1,'MM/DD/YYYY HH24:MI') + INTERVAL '1' DAY,'FMMM/DD/YYYY HH24:FMMI')
9/28/21 18:05

正如您在其中第一个的输出中看到的那样,正如@Aitor 提到的那样,年份显示为 0021 而不是 21。那是因为您使用了四位数的 YYYY 掩码作为两位数的年份值.在第二个中, FM 抑制了它,所以它不太明显。由于您似乎并不关心世纪,因此无论您使用 YY 还是 RR 通常都无关紧要 - 如果您碰巧遇到飞跃 year/day 可能是个例外;但最好让掩码与字符串匹配,所以 RR:

TO_CHAR(TO_DATE(col1,'MM/DD/RR HH24:MI') + INTERVAL '1' DAY,'FMMM/DD/RR HH24:FMMI')
9/28/21 18:05

db<>fiddle

* 但是您不应该将日期存储为字符串。它们应存储 作为日期 ,并格式化为仅供显示的字符串。你也不应该再使用两位数的年份了。

你说你的专栏有这个:9/27/21,但你把掩码像 YYYY。对此要小心,因为使用 YYYY,年份将为公元前 21 年...

也许您想在约会面具中加入 RRRR。 RRRR 表示 00 到 49 范围内的 2 位数年份假定为当前世纪:

select to_char(to_date('9/27/2021 18:05','MM/DD/RRRR HH24:MI')+ INTERVAL '1' DAY,'MM/DD/YYYY HH24:MI') result 
from dual;

结果:2021 年 9 月 28 日 18:05

我不知道你的输出格式是什么,但无论如何,如果你想要你的日期格式像 VARCHAR,试试这个。你的专栏是这样的

select to_char(to_date(col1,'MM/DD/RRRR HH24:MI') + 1,'MM/DD/YYYY HH24:MI') result 
from your_table;

您也可以使用简单的 +1

而不是 INTERVATL '1' DAY

DATETIMESTAMP 值都是二进制数据类型,NOT 具有给定的格式;因此,当您将字符串转换为 DATETIMESTAMP 时,您使用的格式是 NOT stored.

如果要将其转换为 DATETIMESTAMP,然后再转换回相同格式的字符串,则在添加间隔后,您要使用 TO_CHAR转换回具有所需格式的字符串。

例如:

SELECT TO_CHAR(
         TO_DATE(col1, 'MM/DD/RR HH24:MI') + INTERVAL '1' DAY,
         'MM/DD/RR HH24:MI'
       )
FROM   tab1

注意:如果您在格式模型中使用 YYYY,则 21 将被解析为公元 21 年而不是公元 2021 年。相反,您需要使用 YYRR(取决于您希望如何处理上个世纪末的值)。

Please note in both the above cases format is changing.

您的列的格式没有改变,您已将字符串转换为 DATETIMESTAMP,它们是二进制数据类型并且没有任何格式。

您正在使用的用户界面(即 SQL/Plus 或 SQL 开发人员)试图提供帮助,而不是向您展示二进制数据的用户将使用其内部规则来格式化二进制数据作为你可以阅读的东西。 SQL/Plus 和 SQL 开发人员将为 DATE 值使用 NLS_DATE_FORMAT 会话参数,为 TIMESTAMP 值使用 NLS_TIMESTAMP_FORMAT 会话参数。可以为每个用户在每个会话中将这些参数设置为不同的值,因此您不应依赖它们来保持一致。

如果您想要一致的格式,请将 date/timestamp 包裹在 TO_CHAR 中以应用一致的格式。