【问题标题】:Convert a string representing a timestamp to an actual timestamp in PostgreSQL?将表示时间戳的字符串转换为 PostgreSQL 中的实际时间戳?
【发布时间】:2012-11-28 12:59:16
【问题描述】:

在 PostgreSQL 中:我将 string 转换为 timestampto_timestamp()

select * from ms_secondaryhealthcarearea
where to_timestamp((COALESCE(update_datetime, '19900101010101'),'YYYYMMDDHH24MISS') 
    > to_timestamp('20121128191843','YYYYMMDDHH24MISS')

但我得到这个错误:

ERROR:  syntax error at end of input
LINE 1: ...H24MISS') >to_timestamp('20121128191843','YYYYMMDDHH24MISS')
                                                                       ^
********** Error **********

ERROR: syntax error at end of input
SQL state: 42601
Character: 176

为什么?如何将string 转换为timestamp

【问题讨论】:

    标签: postgresql datetime database-design timestamp


    【解决方案1】:

    上面还有一种将字符串转换为时间戳类型的PostgreSql的方法,

    SELECT to_timestamp('23-11-1986 06:30:00', 'DD-MM-YYYY hh24:mi:ss')::timestamp without time zone;
    

    【讨论】:

      【解决方案2】:

      一个太多的左括号。试试这个:

      select * 
      from ms_secondaryhealthcarearea 
      where to_timestamp(COALESCE(update_datetime, '19900101010101'),'YYYYMMDDHH24MISS') >to_timestamp('20121128191843','YYYYMMDDHH24MISS')
      

      to_timestamp 有两个左括号:

      where to_timestamp((COA.. -- <-- the second one  is not needed!
      

      【讨论】:

        【解决方案3】:

        @ppeterka 指出了语法错误。

        更紧迫的问题是:为什么将timestamp 数据存储为字符串开头?如果您的情况允许,请考虑将列转换为正确的类型:

        ALTER TABLE ms_secondaryhealthcarearea
        ALTER COLUMN update_datetime TYPE timestamp
        USING to_timestamp(update_datetime,'YYYYMMDDHH24MISS');
        

        或使用timestamptz - 取决于您的要求。

        【讨论】:

        • 我什至没有意识到整个故事背后的这个丑陋问题 - 似乎只是一个简单语法问题的另一个案例。将日期存储为任何类型的字符串都是绝对禁止的......
        【解决方案4】:

        我的要求与我阅读标题的方式相同。如何将纪元时间戳作为文本转换为真实时间戳。就我而言,我从 json 对象中提取了一个。所以我最终得到了一个时间戳作为毫秒的文本

        '1528446110978'(格林威治标准时间:2018 年 6 月 8 日星期五上午 8:21:50.978)

        这是我尝试过的。只是后者(ts_ok_with_ms)是完全正确的。

        SELECT
          data->>'expiration' AS expiration,
          pg_typeof(data->>'expiration'),
          -- to_timestamp(data->>'expiration'), < ERROR: function to_timestamp(text) does not exist
          to_timestamp(
            (data->>'expiration')::int8
          ) AS ts_wrong,
          to_timestamp(
            LEFT(
              data->>'expiration',
              10
            )::int8
          ) AS ts_ok,
          to_timestamp(
            LEFT(
              data->>'expiration',
              10
            )::int8
          ) + (
            CASE
              WHEN LENGTH(data->>'expiration') = 13
              THEN RIGHT(data->>'expiration', 3) ELSE '0'
            END||' ms')::interval AS ts_ok_with_ms
        FROM (
          SELECT '{"expiration": 1528446110978}'::json AS data
        ) dummy
        

        这是返回的(转置的)记录:

        expiration    1528446110978
        pg_typeof     text
        ts_wrong      50404-07-12 12:09:37.999872+00
        ts_ok         2018-06-08 08:21:50+00
        ts_ok_with_ms 2018-06-08 08:21:50.978+00
        

        我确定我忽略了一个更简单的版本,即如何从 json 对象中的时间戳字符串获取带有 ms (ts_ok_with_ms) 的真实时间戳,但我希望这仍然会有所帮助。

        更新:为了您的方便,这里有一个功能。

        CREATE OR REPLACE FUNCTION data.timestamp_from_text(ts text)
        RETURNS timestamptz
        LANGUAGE SQL AS
        $$
          SELECT to_timestamp(LEFT(ts, 10)::int8) +
          (
            CASE
              WHEN LENGTH(ts) = 13
              THEN RIGHT(ts, 3) ELSE '0'
            END||' ms'
          )::interval
        $$;
        

        【讨论】:

          猜你喜欢
          • 2020-11-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多