【问题标题】:Time subtraction format result时间减法格式结果
【发布时间】:2018-01-17 19:45:44
【问题描述】:

我在格式化我的时间计算结果以及搜索论坛解决方案时遇到了问题。我不希望查看导致结果的“UTC 小时数”(+09)。

select
(localtimestamp - to_timestamp(us.STARTDATETIME,'hh24:mi:ss')) as HoursPassed
from random us

其中us.STARTDATETIMEvarchar2,类似于08:00

我的结果:

+09 07:30:17.160826

想要的结果:

07:30:17

【问题讨论】:

  • +09 是从每月第一天算起的天数,而不是从 UTC 算起的小时数。您使用时间戳和会话时区而不是系统时区是否有原因? startdatetime 是否代表特定时区?
  • @Alex Poole 不,不需要使用会话时区。 startdatetime 不代表特定时区

标签: oracle time format


【解决方案1】:

当你subtract one timestamp from another时,结果是一个内部区间数据类型,但你可以把它当成'interval day to second'

select
(localtimestamp - to_timestamp(us.STARTDATETIME,'hh24:mi:ss')) as HoursPassed
from random us;

HOURSPASSED        
-------------------
+08 15:26:54.293892

“+08”(在我的会话时区中)是天数,而不是 UTC 偏移量;这是因为当您将字符串转换为日期或时间戳并仅提供时间部分时,日期部分defaults to the first day of the current month

默认日期值确定如下:

  • 年份是当前年份,由 SYSDATE 返回。
  • 月份是当前月份,由 SYSDATE 返回。
  • 当天是 01(每月的第一天)。
  • 时、分、秒均为0。

这些默认值用于请求日期值的查询中,其中日期本身未指定...

所以我真的在比较:

select localtimestamp, to_timestamp(us.STARTDATETIME,'hh24:mi:ss')
from random us;

LOCALTIMESTAMP             TO_TIMESTAMP(US.STARTDATET
-------------------------- --------------------------
2017-08-09 23:26:54.293892 2017-08-01 08:00:00.000000

你不能直接格式化一个区间,但是你可以extract时间的元素,分别格式化,然后串联起来。

select to_char(extract(hour from (localtimestamp
    - to_timestamp(us.STARTDATETIME, 'hh24:mi:ss'))), 'FM00')
  ||':'|| to_char(extract(minute from (localtimestamp
    - to_timestamp(us.STARTDATETIME, 'hh24:mi:ss'))), 'FM00')
  ||':'|| to_char(extract(second from (localtimestamp
    - to_timestamp(us.STARTDATETIME, 'hh24:mi:ss'))), 'FM00')
  as hourspassed
from random us;

HOURSPASSED
-----------
15:26:54

重复计算相同的间隔看起来有点浪费且难以管理,因此您可以在内联视图或 CTE 中执行此操作:

with cte (diff) as (
  select localtimestamp - to_timestamp(us.STARTDATETIME, 'hh24:mi:ss')
  from random us
)
select to_char(extract(hour from diff), 'FM00')
  ||':'|| to_char(extract(minute from diff), 'FM00')
  ||':'|| to_char(extract(second from diff), 'FM00')
  as hourspassed
from cte;

HOURSPASSED
-----------
15:26:54

您也可以使用日期而不是时间戳;减法然后将差值作为数字给出,包括整数天和小数天:

select current_date - to_date(us.STARTDATETIME, 'hh24:mi') as hourspassed
from random us;

HOURSPASSED
-----------
 8.64368056

最简单的格式化方法是将其添加到已知的午夜时间,然后使用to_char()

select to_char(date '1970-01-01'
  + (current_date - to_date(us.STARTDATETIME, 'hh24:mi')),
  'HH24:MI:SS') as hourspassed
from random us;

HOURSPAS
--------
15:26:54

我坚持使用 current_date 作为最接近 localtimestamp 的匹配项;您实际上可能想要systimestamp 和/或sysdate。 (更多关于区别here。)

【讨论】:

    猜你喜欢
    • 2016-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-07
    相关资源
    最近更新 更多