将 2 个月添加到当前时间戳
Posted
技术标签:
【中文标题】将 2 个月添加到当前时间戳【英文标题】:Add 2 months to current timestamp 【发布时间】:2012-12-26 13:11:21 【问题描述】:如何在 Oracle 中将月份添加到时间戳值?在我的查询中,它被转换为日期值:
SELECT add_months(current_timestamp,2)
FROM dual;
实际输出为:
ADD_MONTH
11-MAR-13
预期的输出是:
2013-01-01 00:00:00.000000000+00:00
【问题讨论】:
下次遇到此类问题时,您要在 Google 上搜索的术语是“日期数学”。 【参考方案1】:这将为您提供日期和时间作为TIMESTAMP
数据类型:
select TO_TIMESTAMP(TO_CHAR(ADD_MONTHS(SYSDATE, 2), 'YYYYMMDD HH24:MI'),
'YYYYMMDD HH24:MI') from dual;
如果您需要比上述更多或更少的精度(例如四舍五入),请调整日期格式(两者必须是相同的格式)。例如,这会将 2 个月的精度返回到秒级:
select TO_TIMESTAMP(TO_CHAR(ADD_MONTHS(SYSTIMESTAMP, 2),
'YYYYMMDD HH24:MI:SS'), 'YYYYMMDD HH24:MI:SS') from dual;
这是我能(作为一个字符)获得的最接近您需要的格式:
select TO_CHAR(
TO_TIMESTAMP(TO_CHAR(ADD_MONTHS(SYSTIMESTAMP, 2),
'YYYYMMDD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS'),
'YYYY-MM-DD HH24:MI:SS.FF TZR') from dual;
【讨论】:
您的第一条语句是狡猾的,因为它依赖于隐式转换,并且取决于 NLS 设置,实际上可能会失败(或给出不正确的日期)。 是的,因为 TO_TIMESTAMP 只接受字符,而不接受日期,所以我将删除第一个,只保留具有明确日期格式的转换.. 感谢您增加了 2 个月的时间,但我需要这种格式的输出。 2013-01-11 00:00:00.000000000+00:00 这是我能做到的最接近的 - 虽然它作为一个字符返回:【参考方案2】:对于甲骨文:
select TO_TIMESTAMP(Sysdate,'DD-Mon-YYYY HH24-MI-SS') + 60
from dual;
select sysdate + interval '2' month from dual;
select TO_TIMESTAMP (Sysdate + interval '2' month, 'DD-Mon-YYYY HH24-MI-SS')
from dual
;
结果1:
| TO_TIMESTAMP(SYSDATE,'DD-MON-YYYYHH24-MI-SS')+60 |
----------------------------------------------------
| March, 12 0013 00:00:00+0000 |
结果2:
| SYSDATE+INTERVAL'2'MONTH |
--------------------------------
| March, 11 2013 21:41:10+0000 |
结果3:
| TO_TIMESTAMP(SYSDATE+INTERVAL'2'MONTH,'DD-MON-YYYYHH24-MI-SS') |
------------------------------------------------------------------
| March, 11 0013 00:00:00+0000 |
sqlffidle demo。
【讨论】:
@user1968156 请也看看这个并发表评论:) 我看到了,但我想要这样的年份。 2013-01-11 00:00:00.000000000+00:00 @user1968156 抱歉,但很简单 :D 只需将格式 :D 更改为 `YYYYMMDD HH24-MI-SS' 我试过了,但它给出的输出如下: select TO_TIMESTAMP(SYSDATE+INTERVAL'2'MONTH,'YYYY-MON-DD HH24:MI:SS') from dual; 2011 年 3 月 13 日上午 12 点【参考方案3】:SELECT current_timestamp + INTERVAL '2' MONTH from dual;
要以您想要的格式显示,请使用TO_CHAR
:
SELECT TO_CHAR(current_timestamp + INTERVAL '2' MONTH,
'YYYY-MM-DD HH24:MI:SS.FF9TZH:TZM') from dual;
2013-03-11 23:58:14.789501000+01:00
【讨论】:
您应该知道,根据调用日期,此方法可能会引发 ORA-01839 错误。例如,运行:“SELECT TO_TIMESTAMP('30-JAN-2012','DD-MON-YYYY') + numtoyminterval(1,'month') from dual;”抛出错误,因为它会返回不存在的 2 月 30 日。 对不起——我应该更具体一点——一般使用间隔时会抛出错误。所以:“SELECT TO_TIMESTAMP('30-JAN-2012','DD-MON-YYYY') + 间隔 '1' 从双月开始;”会导致同样的错误。 我在编辑之前对其进行了测试,但是使用 INTERVAL '2' MONTH,当然,这不会引发错误,因为它是在 3 月份。傻我!仍然非常感谢您的帮助!SELECT TIMESTAMP '2067-12-30 01:23:45.6789' + INTERVAL '2' MONTH FROM DUAL
引发异常 ORA-01839: date not valid for month specified
因为没有 2 月 30 日【参考方案4】:
我认为这将为您提供所需的内容:
SELECT TO_CHAR(TO_TIMESTAMP(ADD_MONTHS(CURRENT_TIMESTAMP,2))
+ (CURRENT_TIMESTAMP - TRUNC(CURRENT_TIMESTAMP)),
'YYYY-MM-DD HH:MI:SSxFFTZR') FROM DUAL;
使用间隔方法的问题在于,根据运行查询的日期,您可能会遇到意外错误。例如
SELECT TO_TIMESTAMP('31-JAN-2012') + NUMTOYMINTERVAL(1,'MONTH') FROM DUAL;
该查询返回:
ORA-01839: date not valid for month specified
这是因为它试图返回 2 月 31 日,这不是一个有效的日期。
ADD_MONTHS 是一种“更安全”的日期数学方法,因为间隔查询会引发错误,在上面的示例中,ADD_MONTHS 将返回该月的最后一个日期(2 月 28 日或 29 日,具体取决于年份)。
【讨论】:
这个答案有几个问题 - 首先ADD_MONTHS
将隐式将TIMESTAMP
转换为DATE
删除小数秒,但它保留其余的时间组件,然后您添加当前时间和截断到一天开始的时间之间的间隔,因此您添加了两次时间戳的时间组件(但小数秒只有一次)。
其次,TO_TIMESTAMP( timestampstring, format_model )
使用NLS_TIMESTAMP_FORMAT
会话参数作为默认格式模型,但将DATE
隐式转换为字符串(因为TO_TIMESTAMP
的第一个参数是字符串)使用 NLS_DATE_FORMAT
会话参数 - 依赖隐式转换意味着这些设置必须相同,TIMESTAMP
s 和 DATE
s 通常不具有相同的格式,因此大多数用户不会出现这种情况.
你想要:SELECT CAST( ADD_MONTHS( TRUNC( CURRENT_TIMESTAMP ), 2 ) AS TIMESTAMP ) + ( CURRENT_TIMESTAMP - TRUNC( CURRENT_TIMESTAMP ) ) AS two_months_from_now FROM DUAL;
【参考方案5】:
对于甲骨文:
SELECT
TIMESTAMP'2014-01-30 08:16:32', -- TS we want to increase by 1 month
--TIMESTAMP'2014-01-30 08:16:32' + NUMTOYMINTERVAL(1, 'MONTH'), -- raises ORA-01839: date not valid for month specified
--TIMESTAMP'2014-01-30 08:16:32' + INTERVAL '1' MONTH, -- raises ORA-01839: date not valid for month specified
ADD_MONTHS(TIMESTAMP'2014-01-30 08:16:32', 1), -- works but is a date :(
CAST(ADD_MONTHS(TIMESTAMP'2014-01-30 08:16:32', 1) AS TIMESTAMP) -- works
FROM DUAL
【讨论】:
使用ADD_MONTHS
将TIMESTAMP
转换为DATE
,并在您将其转换回TIMESTAMP
时将小数秒截断为0
。以上是关于将 2 个月添加到当前时间戳的主要内容,如果未能解决你的问题,请参考以下文章