文档章节

时区转换函数

yonj1e
 yonj1e
发布于 2017/03/31 11:08
字数 536
阅读 51
收藏 0

时区转换函数 

功能

把时区1的时间转换成时区2的时间

参数

  • arg1 -- 输入时间
  • arg2 -- 时区1(也是arg1当前时间所在的时区)
  • arg3 -- 时区2(要转换的时区的时间)  

要求

  1. 参数arg1类型可为timestamp
  2. 24个时区(由1-24表示)

 

在 pg_proc.h 中添加函数定义

src/include/catalog/pg_proc.h

	DATA(insert OID = 6668 (  timezone_convert  PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 1114 "1114 23 23" _null_ _null_ _null_ _null_ _null_ timezone_convert _null_ _null_ _null_ ));
	DESCR("timestamp convert.");

 在  src/backend/utils/adt/myfuncs.c 中实现函数

Datum 
	timezone_convert(PG_FUNCTION_ARGS)
	{
		Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
		int32 zone1 = PG_GETARG_INT32(1);
		int32 zone2 = PG_GETARG_INT32(2);

        Timestamp result = 0;

		if (!((1 <= zone1 && zone1 <= 24) && (1 <= zone2 && zone2 <= 24)))
		{
			ereport(ERROR,
				(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
				errmsg("timestamp out of range.the parameter is 1..24")));
		}
		
		if (TIMESTAMP_NOT_FINITE(timestamp))
		{
			PG_RETURN_TIMESTAMP(timestamp);
		}

		/** 实现时区转换 **/

		PG_RETURN_TIMESTAMP(result);
	}

获取参数判断合法性

思路

Timestamp timestamp = PG_GETARG_TIMESTAMP(0);

timestamp -> day; timestamp -> hour;

hour  = hour + zone2 - zone1;

hour >= 24

    hour -= 24;

    day += 1;

hour < 0

    hour += 24;

    day -= 1;

return timestamp;

src/include/pgtime.h 定义了相关结构体

struct pg_tm
{
	int			tm_sec;        
	int			tm_min;
	int			tm_hour;
	int			tm_mday;        /* 1..31 */
	int			tm_mon;			/* origin 0, not 1 */
	int			tm_year;		/* relative to 1900 */
	int			tm_wday;        /* 0..6 (0是周一)*/
	int			tm_yday;        /* 1..366 Julian date */
	int			tm_isdst;
	long int	tm_gmtoff;
	const char *tm_zone;
};

/src/include/utils/timestamp.h

定义了timestamp 和 pg_tm 的转换方法

extern int tm2timestamp(struct pg_tm * tm, fsec_t fsec, int *tzp, Timestamp *dt);
extern int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm * tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone);

timestamp2tm() 第一个参数是输入timestamp,第三个是输出pg_tm,第四个是输出的小数秒,其他几个参数与时区相关,第2,5个参数也是出参,最后一个设置NULL就可以,表示当前会话时区。

流程

代码

Datum 
timezone_convert(PG_FUNCTION_ARGS)
{
	Timestamp timestamp = PG_GETARG_TIMESTAMP(0);
	int32 zone1 = PG_GETARG_INT32(1);
	int32 zone2 = PG_GETARG_INT32(2);
	struct pg_tm tt, *tm = &tt;
	int day;

	fsec_t     fsec;
	Timestamp result = 0;

	if (!((1 <= zone1 && zone1 <= 24) && (1 <= zone2 && zone2 <= 24)))
	{
		ereport(ERROR,
			(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
			errmsg("timestamp out of range.the parameter is 1..24")));
	}
	
	if (TIMESTAMP_NOT_FINITE(timestamp))
	{
		PG_RETURN_TIMESTAMP(timestamp);
	}
	if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0)
	{
		ereport(ERROR,
			(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
			errmsg("timestamp out of range")));
	}
	
	day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday);
	tm->tm_hour = tm->tm_hour + zone2 - zone1;

	if(tm->tm_hour >= 24)
	{
		tm->tm_hour -= 24;
		day += 1;
	}
	else if(tm->tm_hour < 0)
	{
		tm->tm_hour += 24;
		day -= 1;
	}

	j2date(day, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);

	if (tm2timestamp(tm, fsec, NULL, &result) != 0)
	{
		ereport(ERROR,
			(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
			errmsg("timestamp out of range")));
	}

	PG_RETURN_TIMESTAMP(result);
}

 

© 著作权归作者所有

yonj1e
粉丝 18
博文 20
码字总数 31358
作品 0
济南
后端工程师
私信 提问
lua 中关于时间戳和可读时间格式的一点记录

lua 标准库中提供了关于时间的函数os.time()和os.date(),这两个函数使用起来还是有需要注意的地方的;这两个函数的结果都是加入了时区;比如我现在系统是GMT+8; os.time({year=1970, month=...

熊友良
2014/12/21
7.4K
2
实例介绍PHP日期函数date格式转换

网站开发时我们经常需要对日期、时间进行处理,在PHP里提供了很多日期、时间函数方便PHP开发者对日期、时间进行计算、格式转换。所以掌握PHP日期函数非常必要,也为处理PHP日期函数与Mysql数...

Minho
2012/02/08
250
0
Julian时间问题

因为移植程序原因,调试一个计算当前时间距1970年1月1号0时0分0秒的秒数函数; 被移植的程序搞得很复杂,首先将当前时间转换为Julian Day(凯撒日),1970年1月1号0时0分0秒也转换为Julian Day.然...

jlmpp
2010/11/27
331
0
PHP 日期与时间

获取时间 1.使用 date 函数格式化一个本地时间。 //输出当前时间 echo date('Y-m-d H:i:s'); 2.使用 getdate 函数获取时间戳的日期时间信息。 //打印出详细的信息 var_dump(getdate(time())...

菜鸟不菜么
2017/11/04
0
0
FreeMarker日期内建函数

date, time, datetime (当用于日期/时间/日期-时间值时) 这些内建函数用来指定日期变量中的哪些部分被使用: :仅日期部分,没有一天当中的时间部分。 :仅一天当中的时间部分,没有日期部分...

楠木楠
2016/11/27
82
0

没有更多内容

加载失败,请刷新页面

加载更多

最好的重试是指数后退和抖动

1. 概述 在本教程中,我们将探讨如何使用两种不同的策略改进客户端重试:指数后退和抖动。 2. 重试 在分布式系统中,多个组件之间的网络通信随时可能发生故障。 客户端应用程序通过实现重试来...

liululee
9分钟前
3
0
聊一聊大厂内部的安全管理机制

工作了两个月了体会到了很多之前做外包小项目没有的东西,不得不说大厂的还是有自己一套的完善的体制,不会像B站那样泄露自己整个后台的源码这种事情发生。 电脑办公 比如说在使用电脑办公这...

gzc426
37分钟前
4
0
如何利用deeplearning4j中datavec对图像进行处理

NativeImageLoader Labelloader = new NativeImageLoader(112, 112, 3,new FlipImageTransform(-1)); 一、导读 众所周知图像是有红绿蓝三种颜色堆叠而成,利用deeplearning对图像处理,必须把...

冷血狂魔
38分钟前
7
0
1. Context - React跨组件访问数据的利器

《react-router-dom源码揭秘》系列 2. React-Router的基本使用 3. react-router-dom源码揭秘 - BrowserRouter Context提供了一种跨组件访问数据的方法。它无需在组件树间逐层传递属性,也可以...

前端老手
48分钟前
5
0
Docker入门实战--开篇,为什么要使用Docker

前面Thrift文章中,我曾经介绍过我为什么要用Thrift。Docker的使用却是不一样的。纯属没事找事,因为我现在一个人的团队,项目只要一个project目录足够了! 那我何苦要用Docker呢 各位且听听...

后天的奇点
48分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部