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 区别的主要内容,如果未能解决你的问题,请参考以下文章

Oracle与MySQL的几点区别

MySQL几种count比较

MySQL几种count比较

vue的计算属性理解及与watch的区别

mysql数据库的SQL语句和oracle的有啥区别?详细点

MySQL、PG、Oracle、SqlServer、达梦数据库扫描表字段元数据SQL