【GNSS】GNSS处理中的时间系统

26 篇文章 7 订阅

精密GNSS数据处理中主要涉及三种时间类型:以地球自转为基础建立的世界时系统;基于物质内部的原子运动特性的原子时系统;基于天体动力学理论的动力学时系统。

概念介绍

世界时(UT)

世界时是指通过观测恒星的视运动表达的时间系统,如恒星时(ST)指以春分点为参考连续两次经过地方子午圈的时间间隔。格林尼治平恒星时(GMST)消去了章动影响。 同理,以太阳为参考称为太阳时。以真太阳时的平均角速度在天球赤道上作周年视运动的 平太阳作为参考的为平太阳时。若平太阳时起点为平子夜,称为世界时(UT0)。UT0 进行 极移改正后的世界时记为 UT1,在 UT1 上进行地球自转周期性变化(如潮汐)改正后的世 界时记为UT2。

儒略日(JD)

儒略日Julian Day)是在儒略周期内以连续的日数计算时间的计时法,主要是天文学家在使用。

儒略日数Julian Day NumberJDN)的计算是从格林威治标准时间的中午开始,包含一个整天的时间,起点的时间(0日)回溯至儒略历的公元前4713年1月1日中午12点(在格里历是公元前4714年11月24日),这个日期是三种多年周期的共同起点,且是历史上最接近现代的一个起点。例如,2000年1月1日的UT12:00是儒略日2,451,545。

儒略日期Julian dateJD)是以格林威治标准时中午12:00的儒略日加上那一天的瞬时时间的分数。儒略日期是儒略日添加小数部分所表示的儒略日数。例如,2013年1月1日00:30:00(UT)是儒略日期2,456,293.520833。

儒略周期Julian Period)是开始于公元前4713年,长达7980年的纪年法,被用于历史上各种不同历法的日期转换。公元2018年是儒略周期的6731年,下一个儒略周期将开始于公元3268年。

简化儒略日(MJD)

简化儒略日(Modified Julian Day,MJD),是将儒略日(Julian Day,MJD)进行简化后得到的新计时法。1957年,简化儒略日由史密松天体物理台(Smithsonian Astrophysical Observatory)引入。

儒略日2400000是1858年11月16日,因为JD从中午开始计算,所以简化儒略日的定义中引入偏移量0.5,这意味着MJD 0相当于1858年11月17日的凌晨。并且每一个简化儒略日都在世界时午夜开始和结束。

简化儒略日有两个目的:

  1. 日期从午夜而不是中午开始。

  2. 儒略日的数值由7位数减为5位数,节省计算机储存空间。

动力学时(DT)

动力学时指以天体动力学理论为基础,建立运动方程并进行编算,采用独立变量时间 参数定义的时间系统。以太阳系质心为坐标原点的 DT称为太阳质心动力学时(TDB),以 地球质心为原点的 DT 称为地球动力学时(TDT,1992 年后称为地球时 TT)。DT 是一种 连续均匀的时间系统。TT 的起始时刻为 1977 年 1 月 1 日 0 时。

原子时(TAI)

国际原子时(Temps Atomique International, TAI)指以世界时 1958 年 1 月 1 日 0 时为起点,以铯原子基态两级间跃迁辐射的 9192631770 周所需的时间作为 1 秒秒长定义的一 种连续均匀的时间系统。TT 与 TAI 的转换关系
T T = T A I + 32.184 TT=TAI+32.184 TT=TAI+32.184
协调世界时(UTC)也属于 TAI,但是 UTC 通过跳秒保持与 UT1 在时刻上相近(差异小于 0.9s),从而有了实际的物理意义。跳秒的发生时间通常在一年的 6 月 30 日或 12 月 31 日最后一分钟变为 61s 或 59s。截止 2020 年 1 月,UTC 和 TAI 之间总的跳秒数为 37s, 近期的一次跳秒在 2016 年 12 月 31 日。UTC 与 TAI 的转换公式为
T A I = U T C + l e a p s e c o n d TAI=UTC+leap_second TAI=UTC+leapsecond
leap_second为跳秒,其数值由国际地球自转和参考系统服务(International Earth Rotation and Reference System Service, IERS)机构维持和发布。 各GNSS 的时间系统也是基于原子时,只是定义的 UTC 时间起点存在差异。

在这里插入图片描述
在这里插入图片描述

代码实现

声明

#ifndef _TIME_H
#define _TIME_H

#include <math.h>
#include <stdio.h>

/* 通用时间定义; */
struct COMMONTIME
{
	unsigned short Year;
	unsigned short Month;
	unsigned short Day;
	unsigned short Hour;
	unsigned short Minute;
	double Second;
};

/* 简化儒略日; */
struct MJDTIME
{
	int Days;
	double FracDay;

	MJDTIME()
	{
		Days = 0;
		FracDay = 0.0;
	}
};

/* 儒略日; */
struct JDTIME
{
	int Days;
	double FracDay;

	JDTIME()
	{
		Days = 0;
		FracDay = 0.0;
	}
};

/* GPS时间定义 */
struct GPSTIME
{
	unsigned short Week;
	double SecOfWeek;

	GPSTIME()
	{
		Week = 0;
		SecOfWeek = 0.0;
	}
};

/*通用时与简化儒略日;*/
bool CommonTime2MJDTime(COMMONTIME*Common, MJDTIME*MJD);
bool MJDTime2CommTime(MJDTIME*MJD,COMMONTIME*Common);

/*儒略日与简化儒略日;*/
bool JDTime2MJDTime(JDTIME*JD,MJDTIME*MJD);
bool MJDTime2JDTime(MJDTIME*MJD,JDTIME*JD);

/*儒略日与通用时;*/
bool JDTime2CommonTime(JDTIME*JD,COMMONTIME*Common);
bool CommonTime2JDTime(COMMONTIME*Common,JDTIME*JD);

/*GPST与通用时;*/
bool GPSTime2CommonTime(GPSTIME*GPS,COMMONTIME*Common);
bool CommonTime2GPSTime(COMMONTIME*Common,GPSTIME*GPS);

/*GPST与简化儒略日;*/
bool GPSTime2MJDTime(GPSTIME*GPS,MJDTIME*MJD);
bool MJDTime2GPSTime(MJDTIME*MJD,GPSTIME*GPS);

/*GPST与儒略日;*/
bool GPSTime2JDTime(GPSTIME*GPS,JDTIME*JD);
bool JDTime2GPSTime(JDTIME*JD,GPSTIME*GPS);

/*输出各种时间的函数;*/
bool PrintfCommon(COMMONTIME Common);
bool PrintfJD(JDTIME JD);
bool PrintfMJD(MJDTIME MJD);
bool PrintfGPST(GPSTIME GPS);

#endif

实现

/*--------------时间系统转换模板;---------------------

功能:提供儒略日,简化儒略日,GPST,通用时四个时间系统的任意两个间的相互转换功能;
包括;
//通用时与简化儒略日;
bool CommonTime2MJDTime;
bool MJDTime2CommTime;

//儒略日与简化儒略日;
bool JDTime2MJDTime;
bool MJDTime2JDTime;

//儒略日与通用时;
bool JDTime2CommonTime;
bool CommonTime2JDTime;

//GPST与通用时;
bool GPSTime2CommonTime;
bool CommonTime2GPSTime;

//GPST与简化儒略日;
bool GPSTime2MJDTime;
bool MJDTime2GPSTime;

//GPST与儒略日;
bool GPSTime2JDTime;
bool JDTime2GPSTime;

//输出各种时间的函数;
bool PrintfCommon;
bool PrintfJD;
bool PrintfMJD;
bool PrintfGPST;
-----------------------------------------------------*/


/*----------取小数部分;-------------------------
函数名称:FRAC
函数功能:输入一个浮点型变量,输出该变量的小数部分;
输入变量:;
	input 要取小数部分的浮点型变量;
输出变量:;
	return 浮点型变量的小数部分;

-------------------------------------------------*/
double FRAC(double input)
{
	return (input - (int)(input));
}

/*-----------------通用时与简化儒略日的相互转换;----------------------
函数名称:;
	bool CommonTime2MJDTime(COMMONTIME*Common, MJDTIME*MJD)
	bool MJDTime2CommTime(MJDTIME*MJD, COMMONTIME*Common)
函数功能:;
	实现通用时与简化儒略日之间的相互转换;
输入变量:;
	*Common 通用时结构体地址;*MJD 简化儒略日结构体地址;
输出变量:;
	*Common 通用时结构体地址;*MJD 简化儒略日结构体地址;
公式来源:;
	卫星导航算法与程序设计PPT
-------------------------------------------------------------------*/
bool CommonTime2MJDTime(const COMMONTIME Common, MJDTIME*MJD)
{
	int y, m = 0;
	double JD, UT = 0;
	JDTIME	jd;

	if (Common.Month<=2)
	{
		y = Common.Year - 1;
		m = Common.Month + 12;
	}
	if (Common.Month>2)
	{
		y = Common.Year;
		m = Common.Month;
	}
	UT = Common.Hour + Common.Minute / 60.0 + Common.Second / 3600.0;
	JD = (int)(365.25*y) + (int)(30.6001*(m + 1)) + Common.Day + UT / 24.0 + 1720981.5;
	MJD->Days = (int)(365.25*y) + (int)(30.6001*(m + 1)) + Common.Day + UT / 24.0 + 1720981.5-2400000.5;
	MJD->FracDay = (UT / 24.0 ) - (int)(UT / 24.0 );

	return true;
}
bool MJDTime2CommTime(const MJDTIME MJD, COMMONTIME*Common)
{

	int a, b, c, d, e = 0;
	double UTDay = 0;
	double UT = 0;
	a = (int)(MJD.Days+MJD.FracDay + 2400000.5+0.5);
	b = a + 1537;
	c = (int)((1.0*b - 122.1) / (365.25));
	d = (int)(365.25*c);
	e = (int)((b - d)*1.0 / 30.6001);
	UTDay = b - d - (int)(30.6001*e) + FRAC(MJD.Days + MJD.FracDay + 2400000.5 + 0.5);
	Common->Day = (int)(UTDay);
	Common->Month = e - 1 - 12 * (int)(e*1.0 / 14);
	Common->Year = c - 4715 - (int)((7 + Common->Month)*1.0 / 10.0);
	UT = (FRAC(UTDay) * 24.0);
	/*Common->Hour = (int)(UT);
	Common->Minute = (int)(FRAC(UT)*60.0);
	Common->Second = FRAC(UT)*60.0*60.0-Common->Minute*60.0;*/

	Common->Hour = int(MJD.FracDay * 24);
	Common->Minute = int((MJD.FracDay * 24 - Common->Hour) * 60);
	Common->Second = MJD.FracDay * 24 * 3600 - Common->Hour * 3600 - Common->Minute * 60;
	return true;
}

/*-----------------简化儒略日与儒略日的相互转换;----------------------
函数名称:;
bool JDTime2MJDTime(JDTIME*JD, MJDTIME*MJD)
bool MJDTime2JDTime(MJDTIME*MJD, JDTIME*JD)
函数功能:;
实现简化儒略日与儒略日的相互转换;
输入变量:;
	*JD 通用时结构体地址;*MJD 简化儒略日结构体地址;
输出变量:;
	*JD 通用时结构体地址;*MJD 简化儒略日结构体地址;
公式来源:;
卫星导航算法与程序设计PPT
-------------------------------------------------------------------*/
bool JDTime2MJDTime(const JDTIME JD, MJDTIME*MJD)
{

	MJD->Days = JD.Days - 2400000 - (int)(JD.FracDay - 0.5-1);
	MJD->FracDay = FRAC(JD.FracDay + 1 - 0.5);
	return true;
}
bool MJDTime2JDTime(const MJDTIME MJD, JDTIME*JD)
{
	
	JD->Days = MJD.Days + 2400000 + (int)(MJD.FracDay + 0.5);
	JD->FracDay = FRAC(MJD.FracDay+0.5);
	return true;
}

/*-----------------通用时与儒略日的相互转换;----------------------
函数名称:;
bool CommonTime2JDTime(COMMONTIME*Common, JDTIME*JD)
bool JDTime2CommTime(JDTIME*MJD, COMMONTIME*Common)
函数功能:;
实现通用时与儒略日之间的相互转换;
输入变量:;
	*Common 通用时结构体地址;*JD 儒略日结构体地址;
输出变量:;
	*Common 通用时结构体地址;*JD 儒略日结构体地址;
公式来源:;
卫星导航算法与程序设计PPT
-------------------------------------------------------------------*/
bool JDTime2CommonTime(const JDTIME JD, COMMONTIME*Common)
{
	MJDTIME MJD;
	MJD.Days = JD.Days - 2400000 - (int)(JD.FracDay - 0.5 - 1);
	MJD.FracDay = FRAC(JD.FracDay + 1 - 0.5);

	int a, b, c, d, e = 0;
	double UTDay = 0;
	double UT = 0;
	a = (int)(MJD.Days + MJD.FracDay + 2400000.5 + 0.5);
	b = a + 1537;
	c = (int)((1.0*b - 122.1) / (365.25));
	d = (int)(365.25*c);
	e = (int)((b - d)*1.0 / 30.6001);
	UTDay = b - d - (int)(30.6001*e) + FRAC(MJD.Days + MJD.FracDay + 2400000.5 + 0.5);
	Common->Day = (int)(UTDay);
	Common->Month = e - 1 - 12 * (int)(e*1.0 / 14);
	Common->Year = c - 4715 - (int)((7 + Common->Month)*1.0 / 10.0);
	UT = (FRAC(UTDay) * 24.0);
	Common->Hour = int(MJD.FracDay * 24);
	Common->Minute = int((MJD.FracDay * 24 - Common->Hour) * 60);
	Common->Second = MJD.FracDay * 24 * 3600 - Common->Hour * 3600 - Common->Minute * 60;
	return true;


}
bool CommonTime2JDTime(const COMMONTIME Common, JDTIME*JD)
{
	int y, m = 0;
	double TemptJD, UT = 0;
	if (Common.Month <= 2)
	{
		y = Common.Year - 1;
		m = Common.Month + 12;
	}
	if (Common.Month > 2)
	{
		y = Common.Year;
		m = Common.Month;
	}
	UT = Common.Hour + Common.Minute / 60.0 + Common.Second / 3600.0;
	TemptJD = (int)(365.25*y) + (int)(30.6001*(m + 1)) + Common.Day + UT / 24.0 + 1720981.5;
	JD->Days = (int)(TemptJD);
	JD->FracDay = (TemptJD)-JD->Days;
	return true;
}

/*-----------------通用时与GPST的相互转换;----------------------
函数名称:;
bool GPSTime2CommonTime(GPSTIME*GPS, COMMONTIME*Common)
bool CommonTime2GPSTime(COMMONTIME*Common, GPSTIME*GPS)
函数功能:;
实现通用时与GPST的相互转换;
输入变量:;
	*GPS,*Common;
公式来源:;
卫星导航算法与程序设计PPT
-------------------------------------------------------------------*/
bool GPSTime2CommonTime(const GPSTIME GPS, COMMONTIME*Common)
{
	MJDTIME MJD;
	MJD.Days = 44244 + GPS.Week * 7 + (int)(GPS.SecOfWeek / 86400.0);
	MJD.FracDay = FRAC(GPS.SecOfWeek / 86400.0);

	int a, b, c, d, e = 0;
	double UTDay = 0;
	double UT = 0;
	a = (int)(MJD.Days + MJD.FracDay + 2400000.5 + 0.5);
	b = a + 1537;
	c = (int)((1.0*b - 122.1) / (365.25));
	d = (int)(365.25*c);
	e = (int)((b - d)*1.0 / 30.6001);
	UTDay = b - d - (int)(30.6001*e) + FRAC(MJD.Days + MJD.FracDay + 2400000.5 + 0.5);
	Common->Day = (int)(UTDay);
	Common->Month = e - 1 - 12 * (int)(e*1.0 / 14);
	Common->Year = c - 4715 - (int)((7 + Common->Month)*1.0 / 10.0);
	UT = (FRAC(UTDay) * 24.0);

	Common->Hour = int(MJD.FracDay * 24);
	Common->Minute = int((MJD.FracDay * 24 - Common->Hour) * 60);
	Common->Second = MJD.FracDay * 24 * 3600 - Common->Hour * 3600 - Common->Minute * 60;
	return true;
	
}
bool CommonTime2GPSTime(const COMMONTIME Common, GPSTIME*GPS)
{
	MJDTIME MJD;
	int y, m = 0;
	double UT = 0;
	if (Common.Month <= 2)
	{
		y = Common.Year - 1;
		m = Common.Month + 12;
	}
	if (Common.Month>2)
	{
		y = Common.Year;
		m = Common.Month;
	}
	UT = Common.Hour + Common.Minute / 60.0 + Common.Second / 3600.0;
	MJD.Days = (int)(365.25*y) + (int)(30.6001*(m + 1)) + Common.Day + UT / 24.0 + 1720981.5 - 2400000.5;
	MJD.FracDay = (UT / 24.0) - (int)(UT / 24.0);

	GPS->Week = (int)((MJD.Days - 44244) / 7.0);
	GPS->SecOfWeek = MJD.Days*86400.0 - 44244 * 86400.0 - GPS->Week * 7*86400.0 + MJD.FracDay * 86400;
	return true;
}

/*-----------------简化儒略日与GPST的相互转换;----------------------
函数名称:;
	bool GPSTime2MJDTime(GPSTIME*GPS, MJDTIME*MJD)
	bool MJDTime2GPSTime(MJDTIME*MJD, GPSTIME*GPS)
函数功能:;
	简化儒略日与GPST的相互转换;

公式来源:;
	卫星导航算法与程序设计PPT
-------------------------------------------------------------------*/
bool GPSTime2MJDTime(const GPSTIME GPS, MJDTIME*MJD)
{
	double temptMJD;
	temptMJD = 44244 + GPS.Week * 7 + GPS.SecOfWeek / 86400;
	MJD->Days = (int)(temptMJD);
	MJD->FracDay = FRAC(temptMJD);
	return true;
}
bool MJDTime2GPSTime(const MJDTIME MJD, GPSTIME*GPS)
{
	GPS->Week = (int)((MJD.Days + MJD.FracDay  - 44244) / 7.0);
	GPS->SecOfWeek = (MJD.Days + MJD.FracDay  - 44244 - GPS->Week * 7) * 86400;
	return true;
}

/*-----------------儒略日与GPST的相互转换;----------------------
函数名称:;
bool GPSTime2JDTime(GPSTIME*GPS, JDTIME*JD)
bool JDTime2GPSTime(JDTIME*JD, GPSTIME*GPS)
函数功能:;
儒略日与GPST的相互转换;

公式来源:;
卫星导航算法与程序设计PPT
-------------------------------------------------------------------*/
bool GPSTime2JDTime(const GPSTIME GPS, JDTIME*JD)
{
	double temptJD;
	temptJD = 44244 + GPS.Week * 7 + GPS.SecOfWeek / 86400 + 2400000.5;
	JD->Days = (int)(temptJD);
	JD->FracDay = FRAC(temptJD);
	return true;
}
bool JDTime2GPSTime(const JDTIME JD, GPSTIME*GPS)
{
	GPS->Week = (int)((JD.Days + JD.FracDay - 2400000.5 - 44244) / 7.0);
	GPS->SecOfWeek = (JD.Days + JD.FracDay - 2400000.5 - 44244 - GPS->Week * 7) * 86400;
	return true;
}

/*------------------输出各种时间系统;--------------------
函数功能:输出各种时间系统的值,一个只能输出一个结构体的变量;
函数名称:;
	bool PrintfCommon(COMMONTIME Common) 输出通用时;
	bool PrintfJD(JDTIME JD) 输出儒略日;
	bool PrintfMJD(MJDTIME MJD) 输出简化儒略日;
	bool PrintfGPST(GPSTIME GPS) 输出GPST;
-----------------------------------------------------*/
bool PrintfCommon(COMMONTIME Common)
{

	if (Common.Day>31)
	{
		printf("number of day was wrong!\n");
		return false;
	}
	if (Common.Hour>24||Common.Hour<0)
	{
		printf("number of hour was wrong!\n");
		return false;
	}
	if (Common.Minute>60||Common.Minute<0)
	{
		printf("number of minute was wrong!\n");
		return false;
	}
	if (Common.Second>60||Common.Second<0)
	{
		printf("number of second was wrong!\n");
		return false;
	}
	printf("%d.%d.%d  %d:%d:%lf;\n", Common.Year, Common.Month, Common.Day, Common.Hour, Common.Minute, Common.Second);
	return true;
}

bool PrintfJD(JDTIME JD)
{
	printf("%lf;\n", JD.FracDay + JD.Days);
	return true;
}

bool PrintfMJD(MJDTIME MJD)
{
	printf("%lf;\n", MJD.FracDay + MJD.Days);
	return true;
}

bool PrintfGPST(GPSTIME GPS)
{
	if (GPS.SecOfWeek<0||GPS.SecOfWeek>604800)
	{
		printf("number of time of week was wrong!\n");
		return false;
	}
	printf("%d %d;\n", GPS.Week, GPS.SecOfWeek);
	return true;
}
  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值