【问题标题】:Timestamp Difference In Hours for PostgreSQLPostgreSQL 的时间戳小时差异
【发布时间】:2021-11-01 19:29:04
【问题描述】:

PostgreSQL 是否有 TIMESTAMPDIFF() 等价物?

我知道我可以减去两个时间戳来得到一个 postgresql INTERVAL。我只想要一个 INT 表示的两个时间戳之间的差异(以小时为单位)。

我可以在 MySQL 中这样做:

TIMESTAMPDIFF(HOUR, links.created, NOW())

我只需要以整数表示的两个时间戳之间的差异。

解决方案适合我:

SELECT "links_link"."created",
"links_link"."title",
(EXTRACT(EPOCH FROM current_timestamp - "links_link"."created")/3600)::Integer AS "age" 
FROM "links_link"

【问题讨论】:

    标签: sql postgresql timestamp


    【解决方案1】:

    首先出现的东西

    EXTRACT(EPOCH FROM current_timestamp-somedate)/3600
    

    可能不漂亮,但可以畅通无阻。如果定义了区间除以区间可能会更漂亮。

    编辑:如果您希望它大于零,请使用 abs 或 best(...,0)。适合您的意图。

    Edit++:我没有使用age 的原因是age 带有一个参数,引用文档:减去current_date(在午夜)强>。这意味着除非在午夜跑步,否则您不会得到准确的“年龄”。现在已经快凌晨 1 点了:

    select age(current_timestamp);
           age        
    ------------------
     -00:52:40.826309
    (1 row)
    

    【讨论】:

      【解决方案2】:

      在postgresql中获取时间戳大于日期的字段:

      SELECT * from yourtable 
      WHERE your_timestamp_field > to_date('05 Dec 2000', 'DD Mon YYYY');
      

      从 postgresql 中的时间戳中减去分钟:

      SELECT * from yourtable 
      WHERE your_timestamp_field > current_timestamp - interval '5 minutes'
      

      从 postgresql 中的时间戳中减去小时数:

      SELECT * from yourtable 
      WHERE your_timestamp_field > current_timestamp - interval '5 hours'
      

      【讨论】:

        【解决方案3】:

        Michael Krelin 的回答是 close 并不完全安全,因为在极少数情况下它可能是错误的。问题是 PostgreSQL 中的时间间隔没有关于夏令时之类的上下文。间隔在内部将事物存储为月、日和秒。在这种情况下,月份不是问题,因为减去两个时间戳只使用天和秒,但“天”可能是个问题。

        如果您的减法涉及夏令时转换,则特定一天可能分别被视为 23 小时或 25 小时。间隔将考虑到这一点,这对于了解象征意义上过去的天数很有用,但它会给出不正确的实际过去小时数。间隔上的纪元只会将所有天数乘以 24 小时。

        例如,如果一个完整的“短”天过去了,第二天又增加了一个小时,则间隔将记录为一天零一小时。转换为 epoch/3600 是 25 小时。但实际上 23 小时 + 1 小时应该是总共 24 小时。

        所以更安全的方法是:

        (EXTRACT(EPOCH FROM current_timestamp) - EXTRACT(EPOCH FROM somedate))/3600
        

        正如 Michael 在他的后续评论中提到的,您可能还想使用 floor() 或 round() 将结果作为整数值。

        【讨论】:

          【解决方案4】:

          您可以在时间间隔和时间戳上使用“extract”或“date_part”函数,但我认为这不能满足您的要求。例如,它为“2 天,3 小时”的间隔给出 3。但是,您可以通过将 'epoch' 指定为所需的时间元素,将间隔转换为秒数:extract(epoch from '2 days, 3 hours'::interval) 返回 183600(然后除以 3600 以将秒转换为小时)。

          因此,将所有这些放在一起,您基本上会得到迈克尔的答案:extract(epoch from timestamp1 - timestamp2)/3600。由于您似乎并不关心哪个时间戳在哪个之前,您可能希望将其包装在abs

          SELECT abs(extract(epoch from timestamp1 - timestamp2)/3600)
          

          【讨论】:

          • 这确实是最接近的。删除所有小数应该不是问题,尽管我对缺少像 MySQL 这样的内置函数感到非常难过。
          • 不应该有任何小数,因为它将进行整数除法。
          • araqnid,我也这么认为,但我刚刚尝试过,它确实产生了浮动。
          • 如何获得非浮点值? @MichaelKrelin-hacker
          • @Zoran777 将其转换为整数?
          【解决方案5】:

          postgresql 获取时间戳之间的秒差

          SELECT (
              (extract (epoch from (
                  '2012-01-01 18:25:00'::timestamp - '2012-01-01 18:25:02'::timestamp
                                   )
                       )
              )
          )::integer
          

          哪个打印:

          -2
          

          因为时间戳相隔两秒。取数字除以 60 得到分钟,再除以 60 得到小时。

          【讨论】:

            【解决方案6】:

            extract(hour from age(now(),links.created)) 为您提供小时差的四舍五入计数。

            【讨论】:

            • 三年后...我怀疑。此外:尝试select extract(hour from '11 mons 30 days 23:00:00'::interval); 你只会得到“23”,而不是 11 个月、30 天和 23 小时(约 8660 小时)。
            【解决方案7】:

            为避免历元转换,您可以提取天数乘以 24 并添加小时数的提取。

            select current_timestamp, (current_timestamp - interval '500' hour), (extract(day from (current_timestamp - (current_timestamp - interval '500' hour)) * 24) + extract(hour from (current_timestamp - (current_timestamp - interval '500' hour))));

            【讨论】:

              【解决方案8】:

              对于 MySQL timestampdiff 我不知道,但是对于 MSSQL datediff(hour, start, end),PostgreSQL 中最好的等价物是 floor(extract(epoch from end - start)/3600),因为在 MSSQL 中选择 datediff(hour ,'2021-10-31 18:00:00.000', '2021-10-31 18:59:59.999') 返回 0

              【讨论】:

              • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
              【解决方案9】:

              对于许多喜欢利用数据库功能的开发人员来说,这可能听起来很疯狂,

              但是经过详尽的思考、使用 php 比较日期函数为 mysql 和 postgrsql 创建和修复应用程序的问题后,我得出了结论(对我自己而言),最简单的方法,即最简单的 SQL 问题较少的方法不是利用其中任何一个。

              为什么?因为如果您使用像 PHP 这样的中间件语言进行开发,PHP 具有所有这些功能,并且它们更容易在应用程序 ode 中作为比较整数来实现。 PostgreSQL 时间戳不是 == UNIX TIMESTAMP 并且 MySQL 的 UNIX TIMESTAMP 不是 PostgresQL 或 Oracles 时间戳。如果使用数据库时间戳,移植会变得更加困难。

              所以只需使用整数,而不是时间戳, 作为自 1970 年 1 月 1 日午夜以来的秒数。并且不要介意数据库时间戳。 , 并使用 gmdate() 并将所有内容存储为 gmt 时间以避免时区问题。

              如果您需要在您的应用程序中搜索、排序或比较其他数据中的日期、月份或年份或星期几或任何其他数据, 和用于 time_day、time_hour、time_seconds 的 INTEGER 数据类型.. 或任何您想要索引以进行搜索的数据类型将使数据库更流畅、更便携。 在大多数情况下,您可以只使用一个字段:INTEGER time_created NOT NULL

              (您的数据库行中的更多字段是我发现的此解决方案的唯一缺点,并且不会引起那么多头痛或咖啡杯 :)

              php 的日期函数非常适合比较日期, 但在 mysql 或 postgresql 中,比较日期?不.. 使用整数 sql 比较

              我意识到在插入函数上使用 CURRENT_TIMESTAMP 似乎更容易。哈! 不要被愚弄了。

              你不能这样做DELETE FROM SESSION_TABLE WHERE time-initialized < '2 days' 如果 time-initialized 是一个 postgresql 时间戳。 但你可以这样做:

              DELETE FROM SESSION_TABLE WHERE time_initialized < '$yesterday'

              只要您在 php 中将 $yesterday 设置为自 1970 年以来昨天的秒数。

              这比在 postgresql 选择语句中比较时间戳更容易管理会话记录。

              SELECT age()、SELECT extract() 和 asbtime 本身就是令人头疼的问题。这只是我的看法。

              你可以用php日期对象做加法、减法、等操作

              _peter_sysko U4EA 网络公司

              【讨论】:

              • 那么您如何确保只有有效日期才能进入您的“整数日期”?你在哪里检查2012-02-29是否有效。您怎么知道02:14 的时间是否在 3 月 24 日有效? (提示由于 DST 规则,它并非在任何地方都有效)。而且删除很简单:DELETE FROM SESSION_TABLE WHERE time-initialized < current_date - interval '2' day
              猜你喜欢
              • 1970-01-01
              • 2012-06-03
              • 2015-06-27
              • 2011-08-18
              • 1970-01-01
              • 1970-01-01
              • 2018-09-27
              • 2012-11-28
              • 1970-01-01
              相关资源
              最近更新 更多