postgres的时间转换

2023-10-26

天下苦postgres时间转换久已!

最近在操作数据库时,遇到频繁的时间操作,每次弄完了就忘了,今天痛定思痛,下定决心(终于自己也受不了自己的lazy了)对postgres的时间操作进行一下总结。本文竟可能详尽的记录postgres中涉及到date、timestamp以及和字符串之间的转换进行说明。

1.utc对timestamp的转换

在postgres中没有utc这个概念,为什么?这个问题没有深入的调研,没有什么我们不关心,但是与之对应的有一个概念——epoch,其意思为新纪元,新时代,怎么定义的新呢,计算机上面就是指1970-01-01 00:00:00之后的时间,有人会说这不就是utc吗,好吧,我承认买了个关子,但是有助于记忆。

postgres中的时间可以精确到小数点后五位,也就是10微秒的单位,已经很小了,我们先来感受一下在pg中获取epoch:

--把时间戳转成epoch值
postgres=# select extract(epoch from now());
date_part     
---
1533803404.49598
(1 row)

上面是将当前时间戳转化为epoch,转换的过程中主要用到extract函数,

--将具体时间戳转换为utc
select extract(epoch from timestamp without time zone '1970-01-01 01:00:00');
 date_part 
-----------
  3600
(1 row)
--根据具体时间进行计算,一个小时的utc
select extract(epoch from interval '+1 hours');
 date_part 
-----------
  3600
(1 row)
--同上
select extract(epoch from interval '-1 hours');
 date_part 
-----------
  -3600
(1 row)

下面是将epoch值也就是utc值,转换为时间戳,如下:

--把epoch 值转换回时间戳
postgres=# SELECT TIMESTAMP WITH TIME ZONE 'epoch' + 1447898857.74524 * INTERVAL '1 second';           
?column?           
---
2015-11-19 10:07:37.74524+08

其他都很好理解,这里有一点需要注意,就是with time zone,字面意思很好理解,就是带时区,如果不带时区怎么表示?对了就是without time zone,我们将上面语句进行不带时区的运行,如下:

SELECT TIMESTAMP WITHout TIME ZONE 'epoch' +  1447898857 * INTERVAL '1 second';
---
2015-11-19 02:07:37

整整相差了8个小时,不卖关子,其主要区别如下:

没有时区代表的是绝对时间,absolute timestamp,即 UTC (UTC+0) 时间。

带着时区的代表相对时间,relative timestamp,即当地时间,如北京的当地时间是 UTC+8 的时间。

使用的一个最佳实践是时间类型都设为 timestamp with time zone 类型,只有在根据 timestamp 进行 partition 时才使用 timestamp without time zone 类型,因为 partition 必须使用 immutable 数据 (即在任何情况下数据取出来都一样),而 timestamp with time zone 的数据值与 postgres 配置的 timezone 有关。

这两种数据类型的区别是:

  • 以当地时间存储数据到 timestamp with time zone 类型的字段时,postgres 底层会以 UTC 时间存储,展示数据时会根据 postgres 设置的 timezone 显示为当时时间。
  • 以当地时间存储数据到 timestamp without time zone 类型的字段时,postgres 底层以输入的数据进行存储,展示时会原样展示,与 postgres 设置的时区无关。

查看当前时间戳

下面这是查看当前时间戳的几种方式,如下:

 --查看当前的时间戳,还有函数now()

postgres=# select clock_timestamp(),current_timestamp,localtimestamp;

        clock_timestamp        |              now              |         timestamp          

-------------------------------+-------------------------------+----------------------------

 2016-02-02 17:54:15.547194+08 | 2016-02-02 17:54:15.546956+08 | 2016-02-02 17:54:15.546956

clock_timestamp和current_timestamp都有时区信息,而localtimestamp没有时区信息

时间戳加减

--时间加减
postgres=# select date '2016-02-02 10:00:00'+ interval '10 minutes'; 
?column?       
---
 2016-02-02 00:10:00

时间戳格式转化

将时间戳根据具体格式转换为字符串:

 SELECT to_char((TIMESTAMP WITH TIME ZONE'epoch' + 1447898857 * INTERVAL '1 second' ),'yyyy-MM');
 2015-11

时间段内的随机时间

--直接用sql生成随机日期时间

select '2015-5-1'::date + trunc(random()*100)::integer +' 00:22:22'::time + (trunc(random()*3600*24)||' second')::interval; 

random()生成一个0到1的随机数,trunc()对生成随机数进行截取,剩下的参考时间戳加减过程的相关做法。

--创建随机日期时间函数       
   CREATE OR REPLACE FUNCTION rand_date_time(start_date date, end_date date) RETURNS TIMESTAMP AS  
BODY  
 DECLARE  
    interval_days integer;  
    random_seconds integer;  
    random_dates integer;  
    random_date date;  
    random_time time;
BEGIN  
    interval_days := end_date - start_date;  
    random_dates:= trunc(random()*interval_days);
    random_date := start_date + random_dates; 
    random_seconds:= trunc(random()*3600*24); 
    random_time:=' 00:00:00'::time+(random_seconds || ' second')::INTERVAL;
    RETURN random_date +random_time;  
END;   
BODY  
LANGUAGE plpgsql;  
--生成指定时间内的随机时间
SELECT rand_date_time('2000-01-01', '2013-12-31');  

不同时区日期转化

--不同时区之间的转换,pst美国太平洋标准时间

postgres=# select '2016-02-03 09:07:30.816885+08' at time zone 'pst';
timezone          
---
 2016-02-02 17:07:30.816885
(1 row)
--cct中国沿海时间
postgres=# select '2016-02-03 09:07:30.816885+08' at time zone 'cct';
timezone          
---
 2016-02-03 09:07:30.816885
(1 row)
--将西五区转到东八区
postgres=#  SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'cct';
      timezone       
---
 2001-02-17 09:38:40

系统时区查看

 --查看系统支持的时区
 select * from pg_timezone_names ; 

系统时区设置

--时区设置参数
timezone = 'PRC'
--修改时区的方法

1. 全局参数
   postgresql.conf
   timezone='UTC'
2. 数据库级配置
    alter database dbname set timezone='UTC';
    pipeline=# select * from pg_db_role_setting ;

 setdatabase | setrole |              setconfig               

-------------+---------+--------------------------------------

       14930 |       0 | {TimeZone=UTC}

3. 用户级配置
   alter role rolname set timezone='UTC';
   或者
   alter role all set timezone='UTC';

    pipeline=# select * from pg_db_role_setting ;

 setdatabase | setrole |              setconfig               

-------------+---------+--------------------------------------

       14930 |       0 | {TimeZone=UTC}
           0 |       0 | {TimeZone=UTC}

执行休眠时间设置

--休眠1.5秒后执行,单位秒
SELECT clock_timestamp(),pg_sleep(1.5),clock_timestamp();

--休眠5分钟,单位interval
SELECT clock_timestamp(),pg_sleep_for('5 minutes'),clock_timestamp();

--到指定时间执行,注意这些休眠时间不是完全精确的
SELECT clock_timestamp(),pg_sleep_until('today 10:00'),clock_timestamp();

字符串到时间戳和日期

主要涉及到的函数为todate和toTimestamp,示例如下:

select to_date('2018-03-12 18:47:35','yyyy-MM-dd hh24:mi:ss') 
--转化为日期
2018-03-12
  --对日期进行比较,输出boolean
  select current_timestamp <= to_date('2018-03-12 18:47:35','yyyy-MM-dd hh24:mi:ss')
f
select current_timestamp <= to_timestamp('2018-03-12 18:47:35','yyyy-MM-dd hh24:mi:ss') flag;
select to_timestamp('2018-03-12 18:47:35','yyyy-MM-dd hh24:mi:ss')
---
f
2018-03-12 18:47:35+08

从上面比较可以看出,date和timestamp的主要区别,需要特别说明的一点是,在指定日期的格式的时候,特别注意时分秒的格式指定问题(使用惯了java的格式,用这个会有点不习惯)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

postgres的时间转换 的相关文章

随机推荐

  • Linux下 Nginx设置开机自启

    1 将启动命令添加到 etc rc d rc local 文件中 2 添加完保存后 给rc local文件赋予可执行权限 chmod x etc rc d rc local
  • CentOS7.6服务器部署VNC

    CentOS7 6服务器部署VNC 安装vnc服务器 开启vnc 开启远程端口 查看服务器ip 关闭防火墙和selinux 远程访问 安装vnc服务器 root localhost yum install tigervnc server 开
  • Python实战之数据表提取和下载自动化

    在网络爬虫领域 动态渲染类型页面的数据提取和下载自动化是一个常见的挑战 本文将介绍如何利用Pyppeteer库完成这一任务 帮助您轻松地提取动态渲染页面中的数据表并实现下载自动化 一 环境准备 首先 确保您已经安装了Python环境 接下来
  • blender2.8 利用zbrush减面工具进行减面 再进行拓扑

    有时候想要进行重拓扑的模型一级细分的面数就非常高 为了提高导入到其它软件的加载速度 最好对模型的面数进行减面 这里使用zbrush的自带减面工具 在减面前记得Duplicate一份模型 首先选中想要减面的百分比 这里我先选择百分之四十 再点
  • Ubuntu 虚拟机无法联网(NAT模式下)- 解决方法

    想要在 Ubuntu16 04 虚拟机上安装 git 克隆仓库 只需在 Ubuntu 终端输入以下命令即可 sudo apt get install git 但是我在输入之后并未安装成功 反而显示以下结果 全部都是 暂时不能解析域名 cn
  • bugku-eval

    这是一道php题 标题是eval 先查一下eval的用法 Eval var dump echo的区别 var dump 会将传入的变量打印到页面 变量类型 变量长度和变量值 eval 会执行传入到其中的php代码 echo输出的是最终的结果
  • 自动化框架之python+selenium+pytest

    1 概述 selenium 基于JavaScript代码库的自动化测试框架 通过脚本语言 模拟用户行为操作 最接近用户真实场景 实现对web自动测试 Selenium 是目前的最火爆企业最主流的webUI自动化框架 pytest pytes
  • Docker学习之Dockerfile

    Dockerfile是为了快速构建镜像 Dockerfile由一行行命令语句组成 并且支持以 开头的注释行 一般而言 Dockerfile分为4个部分 基础镜像信息 维护者信息 镜像操作指令 容器启动时执行指令 直接构建出一个环境容器apa
  • vue el-table里输入框、下拉框校验弹出框提示

    table里面有输入框或下拉框 要执行你的方法进行造作之前需要校验 可以在form里面嵌套表格 参考https blog csdn net qq 45039940 article details 122260642 可以弹出提示框进行提示
  • 利用pyinstaller打包streamlit移植到其他电脑上使用

    先上效果图 由于本人在学习深度学习的过程中 有很多关于python的代码 为此想要思考用部分的python代码作为底层 开发一些简单使用的用户界面 因此考虑采用pyqt gradio streamlit来作为前端页面 pyqt我也会写 但是
  • 因果图设计用例的步骤_用例设计之因果图

    1 因果图的介绍 因果图法是一种利用图解法分析输入的各种组合情况 从而设计测试用例的方法 它适合于检查程序输入条件的各种组合情况 1 1 主要的因果关系 因果图中主要有两种节点 原因节点与结果节点 这两种节点分别有两种状态 0状态 1状态
  • 数据库基础知识

    数据库 1数据库联接操作 左连接 右链接 全链接的操作以及区别 问了数据库的三大范式 一编码 1登录 mysql uroot p 2查询数据库 mysql gt show database 3 选中数据库 use 数据库 4 创建数据库 m
  • 关于java.io.FileNotFoundException: class path resource [spring/springmvc.xml]异常的问题解决

    web xml配置文件如下图所示 但是老是报出以下的异常 org springframework beans factory BeanDefinitionStoreException IOException parsing XML docu
  • 【前端面试题】【Vue】v-if 和v-show有什么区别?

    Q v if 和v show有什么区别 A v if实际上操作的dom元素的销毁或者重建 会切换绑定的事件监听器和部分子组件 v show操作的是切换css的渲染 实际操作的是display属性 none block 如果需要频繁切换组件的
  • buuctf - web - [HCTF 2018]WarmUp

    老样子 F12 检查 发现 source php 被注释掉了 在 url 直接进行访问 可以看到是源代码 发现 high file 泄漏 访问 hint php 可以看到 flag 在那里 回头分析源代码 我们发现最底部的if语句为执行条件
  • Moonbeam社区提议新增收集人维护网络稳定,你怎么看?

    维护网络的稳定性和安全性一直是Moonbeam社区的关注重点 最近 Moonbeam社区成员Jim CertHum发布提案 呼吁新增4个活跃收集人至已有的Moonbeam网络收集人集 提升链上治理和网络出块效率 本次提案的重点 将网络中的活
  • Python安全攻防之第一章渗透测试概述

    渗透测试的具体方法 一 如何绕过CDN获取网站的真实IP地址 通过内部邮箱获取 一般情况下 邮箱服务器位于内网 我们可以通过注册邮箱或者订阅邮件 目的就是让对方给我自己发送邮件 这样 查看邮件的原始邮件头 就会发现邮件服务器的真实IP地址
  • docker - 在 alpine 上安装 MongoDB 的问题

    RUN echo http dl cdn alpinelinux org alpine v3 6 community gt gt etc apk repositories RUN apk update RUN apk add mongodb
  • 2019浙江ACM省赛

    目录 E Sequence in the Pocket J Welcome Party K Strings in the Pocket E Sequence in the Pocket 题意 给定一组数 每次操作 可以把一个数抽出 放在数组
  • postgres的时间转换

    天下苦postgres时间转换久已 最近在操作数据库时 遇到频繁的时间操作 每次弄完了就忘了 今天痛定思痛 下定决心 终于自己也受不了自己的lazy了 对postgres的时间操作进行一下总结 本文竟可能详尽的记录postgres中涉及到d