【C语言】GNSS常用时间标示法转换

前言

本程序为《卫星导航定位基础》大作业之一,内容是实现GNSS常用时间标示法的转换,需要注意的是,程序只提供了固定框架的转换方向,若需实现自由转换可自行修改。

 需求

算法如下:

 

不难注意到,3.1、4.1、5.1中使用的算法类似,3.2、4.2、5.2中使用的算法类似 ,故而可以分别合为一个函数,通过不同选择下的变量不同以实现不同的功能,使代码优化。

代码如下:

#include<stdio.h>
#include<math.h>
//格里高利日期转儒略日
double con1_1(double Y, double M, double D, double h, double m, double s) 
{
	double JD;
	if(M <= 2)
	{
		Y = Y - 1;
		M = M + 12;
	}
	JD = floor(365.25 * Y) + floor(30.6001 * (M + 1)) + D + 1720981.5 + h / 24.0 + m / 1440 + s / 86400;
	return JD;  //返回儒略日
}
//儒略日转格里高利日期
int* con1_2(double JD)  
{
	static int a[6];   //用一个数组装载年月日时分秒,以返回多个值
	double J, N, L1, L2, L3, M1, Y1, T1, T;
	J = floor(JD + 0.5);
	N = floor(4 * (J + 68569) / 146097);
	L1 = J + 68569 - floor((N * 146097 + 3) / 4);
	Y1 = floor(4000 * (L1 + 1) / 1461001);
	L2 = L1 - floor(1461 * Y1 / 4) + 31;
	M1 = floor(80 * L2 / 2447);
	a[2] = L2 - floor(2447 * M1 / 80);
	L3 = floor(M1 / 11.0);
	a[1] = M1 + 2 - 12 * L3;
	a[0] = floor(100 * (N - 49) + Y1 + L3);
	T = fmod((JD + 0.5 - floor(JD)) * 24, 24);
	a[3] = floor(T);
	T1 = (T - a[3]) * 60;
	a[4] = floor(T1);
	a[5] = (T1 - a[4]) * 60;
	return a;  //返回数组
}
//年+年积日+天内秒转换为儒略日
int con2_1()
{
	double y, add_d, add_s;
	double JD, JD1, JD2;
	printf("请输入年+年积日+天内秒,中间用空格间隔\n");
	scanf("%lf%lf%lf", &y, &add_d, &add_s);
	JD1 = con1_1(y, 1, 1, 0, 0, 0);   //计算当年1月1日的儒略日JD1
	JD2 = JD1 + add_d - 1;			  //年积日+JD1-1=儒略日JD2.
	JD = JD2 + add_s / 86400;		  //JD2+天内秒/86400=儒略日.
	printf("对应儒略日为%lf\n", JD);
	return 0;
}
//儒略日转换为年+年积日+天内秒
int con2_2()
{
	double JD, jd;
	int y, add_d, add_s;
	int* c;
	printf("请输入儒略日数\n");
	scanf("%lf", &JD);
	y = JD / 365.25 -4712;					    //计算当年年份
	jd = con1_1(y, 1, 1, 0, 0, 0);			    //计算出当年1月1日的儒略日.
	add_d = JD -jd + 1;							//两个儒略日求差加1,得出年积日
	c = con1_2(JD);								//求格里高利日期
	add_s = 3600 * c[3] + 60 * c[4] + c[5];		//计算天内秒
	printf("对应为%d年+%d天+%d秒\n", y, add_d, add_s);
	return 0;
}
//GPS\BD\Galileo周转换为儒略日
int con345_1(double mode)
{;
	double w, s, JD;
	scanf("%lf%lf", &w, &s);
	JD = mode + 7 * w + s / 86400;        //根据所求周类型不同,设置不同原点
	printf("对应儒略日为:%lf\n", JD);
	return 0;
}
//儒略日转换为GPS\BD\Galileo周
int* con345_2(double mode)
{
	static int c[2];
	double JD;
	printf("请输入儒略日数\n");
	scanf("%lf", &JD);
	c[0] = floor((JD - mode) / 7);         //根据所求周类型不同,设置不同原点
	c[1] = ((JD - mode) / 7 - c[0]) * 604800;
	return c;
}
//GLONASST转换为儒略日
int con6_1()
{
	int N4, NT;
	double JD, JDN, h, m, s;
	printf("请输入GLONASST计时,中间用空格间隔\n");
	scanf("%d %d %lf %lf %lf", &N4, &NT, &h, &m, &s);
	JDN = con1_1(1996 + 4 * (N4 - 1 ), 1, 1 ,0, 0, 0);     //计算出1996+4×(N4-1)年1月1日对应的儒略日JDN
	JD = NT - 1 + JDN + h / 24 + m / 1440 + s / 86400;
	printf("对应儒略日为:%lf\n", JD);
	return 0;
}
//儒略日转换为GLONASST计时
int con6_2()
{
	double JD, JDN;
	int* e;
	int N4, NT;
	printf("请输入儒略日数\n");
	scanf("%lf", &JD);
	e = con1_2(JD);                                    //儒略日先转换成格里高利日期
	N4 = floor(float((e[0] - 1996)) / 4) + 1;
	JDN = con1_1(1996 + 4 * (N4 - 1), 1, 1 ,0, 0, 0); //计算出1996+4×(N4-1)年1月1日对应的儒略日JDN
	NT = JD - JDN + 1;
	printf("对应GLONASST计时为:%d:%d:%d:%d:%d\n", N4, NT, e[3], e[4], e[5]);
	return 0;
}
int main()
{
	int input, k;
	begin1:
	printf("请选择GNSS常用时间转换类型:\n1.儒略日与格里高利日期之间转换\n2.儒略日与年+年积日+天内秒之间转换\n3.儒略日与GPS周+周内秒之间转换\n4.儒略日与BD周+周内秒之间转换\n5.儒略日与Galileo周+周内秒之间转换\n6.儒略日与GLONASST之间转换\n7.退出\n");
	begin2:
	scanf("%d",&input);
	switch (input)//根据需求不同提供不同的转换
	{
	case 1:
		printf("请选择转换方向:\n1.格里高利历日期转换为儒略日\n2.儒略日转换为格里高利日期\n3.退出\n");
		choose1:
		scanf("%d",&input);
		switch (input)//选择转换方向
		{
		case 1:
			double Y, M, D, h, m, s;
			printf("请输入格里高利历日期:年、月、日、时、分、秒,中间用空格间隔\n");	
			scanf("%lf%lf%lf%lf%lf%lf",&Y, &M, &D, &h, &m, &s);
			printf("对应儒略日为:%lf\n", con1_1(Y, M, D, h, m, s)); 
			break;
		case 2:
			double JD;
			int* b;
			printf("请输入儒略日数:\n");
			scanf("%lf", &JD);
			b = con1_2(JD);
			printf("对应格里高利历为:%d年%d月%d日%d时%d分%d秒\n", b[0], b[1], b[2], b[3], b[4], b[5]);
			break;
		case 3:break;
		default:
			printf("请正确输入\n");
			goto choose1;
		}
		break;
	case 2:
		printf("请选择转换方向:\n1.年+年积日+天内秒转换为儒略日\n2.儒略日转换为年+年积日+天内秒\n3.退出\n");
		choose2:
		scanf("%d",&input);
		switch (input)//选择转换方向
		{
		case 1:
			con2_1();
			break;
		case 2:
			con2_2();
			break;
		case 3:break;
		default:
			printf("请正确输入\n");
			goto choose2;
		}
		break;
	case 3:
		printf("请选择转换方向:\n1.GPS周+周内秒转为儒略日\n2.儒略日转换为GPS周+周内秒\n3.退出\n");
		choose3:
		scanf("%d",&input);
		switch (input)//选择转换方向
		{
		case 1:
			printf("请输入GPS周+周内秒,中间用空格间隔\n");
			con345_1(2444244.5);
			break;
		case 2:
			int* d1;
			d1 = con345_2(2444244.5);
			printf("对应GPS周+周内秒为:%d周+%d秒\n", d1[0], d1[1]);
			break;
		case 3:break;
		default:
			printf("请正确输入\n");
			goto choose3;
		}
		break;
	case 4:
		printf("请选择转换方向:\n1.BD周+周内秒转为儒略日\n2.儒略日转换为BD周+周内秒\n3.退出\n");
		choose4:
		scanf("%d",&input);
		switch (input)//选择转换方向
		{
		case 1:
			printf("请输入BD周+周内秒,中间用空格间隔\n");
			con345_1(2453736.5);
			break;
		case 2:
			int* d2;
			d2 = con345_2(2453736.5);
			printf("对应BD周+周内秒为:%d周+%d秒\n", d2[0], d2[1]);
			break;
		case 3:break;
		default:
			printf("请正确输入\n");
			goto choose4;
		}
		break;
	case 5:
		printf("请选择转换方向:\n1.Galileo周+周内秒转为儒略日\n2.儒略日转换为Galileo周+周内秒\n3.退出\n");
		choose5:
		scanf("%d",&input);
		switch (input)//选择转换方向
		{
		case 1:
			printf("请输入Galileo周+周内秒,中间用空格间隔\n");
			con345_1(2451412.5);
			break;
		case 2:
			int* d3;
			d3 = con345_2(2451412.5);
			printf("对应Galileo周+周内秒为:%d周+%d秒\n", d3[0], d3[1]);
			break;
		case 3:break;
		default:
			printf("请正确输入\n");
			goto choose5;
		}
		break;
	case 6:
		printf("请选择转换方向:\n1.GLONASST计时转换为儒略日\n2.儒略日转换为GLONASST计时\n3.退出\n");
		choose6:
		scanf("%d",&input);
		switch (input)//选择转换方向
		{
		case 1:
			con6_1();
			break;
		case 2:
			con6_2();
			break;
		case 3:break;
		default:
			printf("请正确输入\n");
			goto choose6;
		}
		break;
	case 7:
		break;
	default:
		printf("请正确输入\n");
		goto begin2;
	}
	printf("是否继续转换\n1.是\n2.否\n");//确认是否退出程序
	begin3:
	scanf("%d", &k);
	switch (k)
	{
	case 1:goto begin1;
	case 2:break;
	default:
		printf("请正确输入\n");
		goto begin3;
	}
	return 0;
}

 实际上代码还有很多可以增加和优化的地方,例如把笔者贪图简便的goto语句替换掉,增添功能使程序可以做到任意转化,添加限制条件以控制输入来减少运行错误。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值