本程序为《卫星导航定位基础》大作业之一,内容是实现GNSS常用时间标示法的转换,需要注意的是,程序只提供了固定框架的转换方向,若需实现自由转换可自行修改。
算法如下:
不难注意到,3.1、4.1、5.1中使用的算法类似,3.2、4.2、5.2中使用的算法类似 ,故而可以分别合为一个函数,通过不同选择下的变量不同以实现不同的功能,使代码优化。
代码如下:
#include
#include
//格里高利日期转儒略日
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语句替换掉,增添功能使程序可以做到任意转化,添加限制条件以控制输入来减少运行错误。