Postgres Datetime替换正则表达式

时间:2015-03-04 11:17:46

标签: regex postgresql datetime

我已经尽可能地独自完成了。

我需要在postgres中的日期时间戳内替换时间。

此:

2015-11-20 08:00:00

需要这样:

2015-11-20 09:00:00

但是对于一年中的每一天(只有时间变化)

这是我到目前为止所拥有的。 (我甚至关闭?)

UPDATE
   events 
SET
   starttime = regexp_replace(starttime,
   E’[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-0]{1}[8-8]{1}:[0-0]{1,2}:[0-0]{1,2}’,
   E’[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-0]{1}[9-9]{1}:[0-0]{1,2}:[0-0]{1,2}’,‘g’)            
WHERE
   account_id = 9           
   AND starttime ~ E’[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-0]{1}[8-8]{1}:[0-0]{1,2}:[0-0]{1,2}’;

3 个答案:

答案 0 :(得分:4)

该文档对此主题非常有用。

在搜索框中输入add 1 hour timestamp

http://www.postgresql.org/docs/9.4/interactive/index.html

作为第一个匹配产生以下页面:

http://www.postgresql.org/docs/9.4/static/functions-datetime.html

所以你可以做点什么

timestamp '2001-09-28 01:00' + interval '1 hour'

此外,如果您的源是列(即mydatecolumn),则可能会变为:

mydatecolumn::timestamp + interval '1 hour'

答案 1 :(得分:4)

我希望您的starttime列属于timestamptimestamp with time zone但如果我怀疑它不是可能需要投射。

UPDATE events SET
    starttime = starttime::timestamp + '1 hour'::interval
WHERE account_id = 9 AND extract(hour from starttime::timestamp) = 8;

与Remi的回答一样,您应参阅手册以获取有关日期时间功能的更多信息。

答案 2 :(得分:4)

我不确定你要做的是什么,但是如果只是那件事,你要做的就是给{{添加一小时' 1}}时间戳,不要使用正则表达式进行日期/时间操作。只是不要。

加1小时

正则表达式用于处理文本数据,但时间戳是starttime - 它具有更复杂的内部结构,并且允许精确操作,而它是“#{}}。文本表示只是打印出来的"原始数据的版本。再次 - TIMESTAMP是postgresql数据类型,因此直接操作它,而不是通过它的"打印出来的"使用正则表达式的文本表单。

更具体地说,你应该这样做:

TIMESTAMP

但如果我没有得到它并且您只想更改UPDATE events SET starttime = starttime + interval '1 hour' WHERE account_id = 9 次(就像您的格式错误的更新声明所示),您可以使用08:00

EXTRACT(field FROM source)

(类似于几分钟或几秒钟等)

无效的正则表达式

即使使用regexp来操纵UPDATE events SET starttime = starttime + interval '1 hour' WHERE account_id = 9 AND EXTRACT(hour FROM starttime) = 8 也不是很明智,你的regexp表达式在几个方面都是错误的:

  1. 您在TIMEDATE来电中有2个正则表达式,其格式为regexp_replace。但你使用regexp字符串甚至替换,这样做:

    regexp_replace(string, regexp, replacement)

    所以你可以看到你刚用select regexp_replace('2015-11-20 08:00:00', E'[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-0]{1}[8-8]{1}:[0-0]{1,2}:[0-0]{1,2}', E'[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-0]{1}[9-9]{1}:[0-0]{1,2}:[0-0]{1,2}', 'g'); regexp_replace ----------------------------------------------------------------------- [0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-0]{1}[9-9]{1}:[0-0]{1,2}:[0-0]{1,2} 字符串替换了所有内容。 Bettew replacement字符串会引用与replacement匹配的组,这会带来第二个问题:

  2. 您的regexp表达式在括号中没有组。如果我更正并在regexp字符串中添加对这些组的引用,您将获得:

    replacement

    看起来几乎不错。但是,由于您要替换 select regexp_replace('2015-11-20 08:00:00', E'([0-9]{4})-([0-9]{1,2})-([0-9]{1,2}) ([0-0]{1})([8-8]{1}):([0-0]{1,2}):([0-0]{1,2})', E'\\1-\\2-\\3 \\4\\5:\\6:\\7', 'g'); regexp_replace --------------------- 2015-11-20 08:00:00 ,请将其更改为:

    08:00
  3. 这不是一个问题,但是使用select regexp_replace('2015-11-20 08:00:00', E'([0-9]{4})-([0-9]{1,2})-([0-9]{1,2}) ([0-0]{1})([8-8]{1}):([0-0]{1,2}):([0-0]{1,2})', E'\\1-\\2-\\3 09:00:00', 'g'); regexp_replace --------------------- 2015-11-20 09:00:00 来匹配零(或其他单个字符)是不必要的,普通[0-0]{1}就足够了,所以我只添加了{{1完全符合字符串。 (您可以将其更改为0以匹配小时,或08:00:00以匹配任何时间)

    [01][0-9]:00:00