pg 时间函数及与oracle,mysql 区别
Posted 紫无之紫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pg 时间函数及与oracle,mysql 区别相关的知识,希望对你有一定的参考价值。
pg CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(n), LOCALTIMESTAMP, LOCALTIMESTAMP(n) 实现源码分析
CURRENT_TIMESTAMP 包含时区, LOCALTIMESTAMP 不包含时区,但会受时区影响. 获取的都是事务开始的时间。下面对主要逻辑进行分析。
获取时间
通过如下函数获取带时区的时间,转为以2000年1月1日00:00:00为时间起点的秒数
TimestampTz
GetCurrentTimestamp(void)
TimestampTz result;
struct timeval tp;
gettimeofday(&tp, NULL);
result = (TimestampTz) tp.tv_sec -
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
result = (result * USECS_PER_SEC) + tp.tv_usec;
return result;
对于 CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(n)
通过GetCurrentTransactionStartTimestamp函数直接获取
TimestampTz
GetSQLCurrentTimestamp(int32 typmod)
TimestampTz ts;
ts = GetCurrentTransactionStartTimestamp();
if (typmod >= 0)
AdjustTimestampForTypmod(&ts, typmod);
return ts;
对于LOCALTIMESTAMP, LOCALTIMESTAMP(n)
通过GetSQLLocalTimestamp 函数获取时间,去掉tz信息
Timestamp
GetSQLLocalTimestamp(int32 typmod)
Timestamp ts;
ts = timestamptz2timestamp(GetCurrentTransactionStartTimestamp());
if (typmod >= 0)
AdjustTimestampForTypmod(&ts, typmod);
return ts;
timestamptz2timestamp 会根据当前session 时区,转换timestamptz 为timestamp,去掉tz 信息
显示
当修改session的时区时会影响显示,而oracle的sysdate, systimestamp不会, 不受客户端影响, mysql对于timestamp 在内部是存储的unix 时间,显示时根据时区展示,因此也会受到影响。
timestamp 类型
timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL)
第一个NULL 表示no TZ conversion wanted , 因为在GetSQLLocalTimestamp调用timestamptz2timestamp时已经转换tz信息。
timestamptz 类型
timestamp2tm(dt, &tz, tm, &fsec, &tzn, NULL)
根据session_timezone 信息转换时间。
与oracle,mysql 区别
mysql
mysql 有current_timestamp, localtimestamp, now, sysdate等,其中current_timestamp, localtimestamp都是now 的同义词,获取的是语句级的时间;
而sysdate 获取的是执行时间。它们的显示都受到session级timezone影响。
mysql> SELECT NOW(), SLEEP(2), NOW();
+---------------------+----------+---------------------+
| NOW() | SLEEP(2) | NOW() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 |
+---------------------+----------+---------------------+
mysql> SELECT SYSDATE(), SLEEP(2), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE() | SLEEP(2) | SYSDATE() |
+---------------------+----------+---------------------+
| 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 |
+---------------------+----------+---------------------+
mysql> show variables like '%zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | CST |
| time_zone | SYSTEM |
+------------------+--------+
2 rows in set (0.02 sec)
mysql> set time_zone='+00:00';
Query OK, 0 rows affected (0.01 sec)
mysql> select sysdate();
+---------------------+
| sysdate() |
+---------------------+
| 2022-05-07 02:27:06 |
+---------------------+
1 row in set (0.00 sec)
mysql>
oracle
sysdate,systimestamp 获取的是数据库所在系统的时间,时区为系统时区,不受数据库影响(session timezone 无影响),其中 使用sysdate 返回date类型,systimestamp 返回TIMESTAMP WITH TIME ZONE.。
current_timestamp, localtimestamp 获取的是当前session time zone下的时间,它们之间的区别是current_timestamp 带有时区信息(TIMESTAMP WITH TIME ZONE.),而localtimestamp没有。
上述时间函数获取的都为语句开始执行时间。
以上是关于pg 时间函数及与oracle,mysql 区别的主要内容,如果未能解决你的问题,请参考以下文章