GNSS时间变换在卫星导航领域尤为重要,主要涉及格里高利日期,儒略日,年积日,天内秒等诸多繁杂的概念,本文将使用C#进行GNSS变换,由于笔者最近正在学习C#语言,故在这里不使用C语言进行编程,碍于笔者较为贫乏的C#语言基础,部分代码可能过于繁重冗杂,愿读者见谅。
转换方法:
格里高利历日期格式为年(Y)+月(M+日(D)+时(h)+分(m)+秒(s);儒略日格式为儒略日(JD)、约化儒略日(MJD)。不同时间系统的格里高利历标示法与儒略日标示法之间的转换公式相同,具体转换公式如下。
接下来是儒略日转换为格里高利日期
之后便为年+年积日+天内秒与儒略日之间的转换
- 年+年积日+天内秒转换为儒略日
- 计算当年1月1日的儒略日JD1.
- 年积日+JD1-1=儒略日JD2.
- JD2+天内秒/86400=儒略日.
- 儒略日转换为年+年积日+天内秒
- 计算出当年1月1日的儒略日.
- 两个儒略日求差加1,得出年积日.
- 根据格里高利历的时分秒计算出天内秒.
年+年积日+天内秒的时间标示法具有如下约束条件:
- 天内秒:小于86400,大于等于0.
- 闰年不大于366,平年不大于365,年积日从1开始.
最后便是儒略日与GPS BDS Galileo Glonasst之间的相互转换
接下来便是代码部分 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 卫星导航GNSS大作业
{
internal class Program
{
static public double ConvertGeligoriandate(double Y, double M, double D, double h, double m, double s) //格里高利日期转儒略日函数
{
double jd;
if (M <= 2)
{
Y = Y - 1;
M = M + 12;
}
jd = Math.Floor(365.25 * Y) + Math.Floor(30.6001 * (M + 1)) + D + 1720981.5 + h / 24.0 + m / 1440 + s / 86400;
return jd;
}
static public void Convertjulianday(double jd)//儒略日转换为格里高利日期
{
double j = Math.Floor(jd + 0.5);
double N = Math.Floor(4 * (j + 68549) / 146097);
double L1 = j + 68569 - Math.Floor((N * 146097 + 3) / 4);
double Y1 = Math.Floor(4000 * (L1 + 1) / 1461001);
double L2 = L1 - Math.Floor((1461 * Y1) / 4) + 31;
double M1 = Math.Floor(80 * L2 / 2447);
double D = L2 - Math.Floor(2447 * M1 / 80);
double L3 = Math.Floor(M1 / 11);
double M = M1 + 2 - 12 * L3;
double Y = Math.Floor(100 * (N - 49) + Y1 + L3);
double T = (jd + 0.5 - Math.Floor(jd)) * 24 % 24;
double h = Math.Floor(T);
double T1 = (T - h) * 60;
double m = Math.Floor(T1);
double s = (T1 - M) * 60;
Console.Write("转化后的格里高利日期为:{0}年,{1}月,{2}日,{3}时,{4}秒", Y, M, D, h, m, s);
}
static public void ConvertDOYandseconds(double Y, double A, double B)//年积日天内秒转化为儒略日
{
double jd1 = Math.Floor(365.25 * (Y - 1)) + Math.Floor(30.6001 * (1 + 12 + 1)) + 1 + 1720981.5 + 0 / 24.0 + 0 / 1440 + 0 / 86400;//计算当年1月1日的儒略日
double jd2 = A + jd1 - 1;
double jd = jd2 + B / 86400;
Console.WriteLine("转化后的儒略日为{0}", jd);
}
static public void Convertjulianday2(double jd, double Y)//儒略日转化为年积日天内秒
{
double jd1 = Math.Floor(365.25 * (Y - 1)) + Math.Floor(30.6001 * (1 + 12 + 1)) + 1 + 1720981.5 + 0 / 24.0 + 0 / 1440 + 0 / 86400;
double A = Math.Floor(jd - jd1 + 1);
double B = Math.Ceiling(86400 * (jd - jd1 - A + 1));
Console.WriteLine("年积日为{0},天内秒为{1}", A, B);
}
static public void ConvertGps(double WN, double TOW)//GPS转化儒略日
{
if ((WN >= 0) && (TOW >= 0) && (TOW < 604800))
{
double jd = 2444244.5 + WN * 7 + TOW / 86400;
if (jd >= 2444244.5)
{
Console.WriteLine("转换后的儒略日为{0}", jd);
}
}
}
static public void Convertjulianday3(double jd)//儒略日转化GPS
{
double WN = Math.Floor((jd - 2444244.5) / 7);
double TOW =Math.Ceiling(((jd - 2444244.5) / 7 - WN) * 604800) ;
if ((WN >= 0) && (TOW >= 0) && (TOW < 604800) && (jd >= 2444244.5))
{
Console.WriteLine("转换后的周数为{0},周内秒为{1}", WN, TOW);
}
}
static public void ConvertBDS(double WN, double TOW)//BDS转儒略日
{
if ((WN >= 0) && (TOW >= 0) && (TOW < 604800))
{
double jd = 2453736.5 + WN * 7 + TOW / 86400;
if (jd >= 2453736.5)
{
Console.WriteLine("转换后的儒略日为{0}", jd);
}
}
}
static public void Convertjulianday4(double jd)//儒略日转BDS
{
double WN = Math.Floor((jd - 2453736.5) / 7);
double TOW = Math.Ceiling(((jd - 2453736.5) / 7 - WN) * 604800);
if ((WN >= 0) && (TOW >= 0) && (TOW < 604800) && (jd >= 2453736.5))
{
Console.WriteLine("转换后的周数为{0},周内秒为{1}", WN, TOW);
}
}
static public void ConvertGalileo(double WN, double TOW)//Galileo转儒略日
{
if ((WN >= 0) && (TOW >= 0) && (TOW < 604800))
{
double jd = 2451412.5 + WN * 7 + TOW / 86400;
if (jd >= 2451412.5)
{
Console.WriteLine("转换后的儒略日为{0}", jd);
}
}
}
static public void Convertjulianday5(double jd)//儒略日转Galileo
{
double WN = Math.Floor((jd - 2451412.5) / 7);
double TOW = Math.Ceiling(((jd - 2451412.5) / 7 - WN) * 604800);
if ((WN >= 0) && (TOW >= 0) && (TOW < 604800) && (jd >= 2451412.5))
{
Console.WriteLine("转换后的周数为{0},周内秒为{1}", WN, TOW);
}
}
static public void ConvertGlonasst(double N4, double Nt, double h, double m, double s)//Glonasst转儒略日
{
double jdn = Math.Floor(365.25 * (1996 + 4 * (N4 - 1) - 1)) + Math.Floor(30.6001 * (1 + 12 + 1)) + 1 + 1720981.5 + 0 / 24.0 + 0 / 1440 + 0 / 86400;
double jd = Nt - 1 + jdn + h / 24 + m / 1440 + s / 86400;
Console.WriteLine("转换后的儒略日为{0}",jd);
}
static public void Convertjulianday6(double jd)//儒略日转Glonasst
{
double j = Math.Floor(jd + 0.5);
double N = Math.Floor(4 * (j + 68549) / 146097);
double L1 = j + 68569 - Math.Floor((N * 146097 + 3) / 4);
double Y1 = Math.Floor(4000 * (L1 + 1) / 1461001);
double L2 = L1 - Math.Floor((1461 * Y1) / 4) + 31;
double M1 = Math.Floor(80 * L2 / 2447);
double D = L2 - Math.Floor(2447 * M1 / 80);
double L3 = Math.Floor(M1 / 11);
double M = M1 + 2 - 12 * L3;
double Y = Math.Floor(100 * (N - 49) + Y1 + L3);
double T = (jd + 0.5 - Math.Floor(jd)) * 24 % 24;
double h = Math.Floor(T);
double T1 = (T - h) * 60;
double m = Math.Floor(T1);
double s = (T1 - M) * 60;
Console.WriteLine("转化后的格里高利日期为:{0}年,{1}月,{2}日,{3}时,{4}秒", Y, M, D, h, m, s);
double N4 = Math.Floor((Y - 1996) / 4) + 1;
double jdn = Math.Floor(365.25 * (1996 + 4 * (N4 - 1) - 1)) + Math.Floor(30.6001 * (1 + 12 + 1)) + 1 + 1720981.5 + 0 / 24.0 + 0 / 1440 + 0 / 86400;
double Nt = jd - jdn + 1;
Console.WriteLine("转化后的1996+4*(N4-1)年的儒略日为{0}", jdn);
}
static void Main(string[] args)
{
Console.WriteLine("请你输入数字1-12中任意一个:");
Console.WriteLine("1.格里高利日期转化为儒略日:");
Console.WriteLine("2.儒略日转化为格里高利日期:");
Console.WriteLine("3.年年积日天内秒转化为儒略日:");
Console.WriteLine("4.儒略日转化为年积日天内秒:");
Console.WriteLine("5.GPS转化为儒略日:");
Console.WriteLine("6.儒略日转化为GPS:");
Console.WriteLine("7.BDS转化为儒略日:");
Console.WriteLine("8.儒略日转化为BDS:");
Console.WriteLine("9.Galileo转化为儒略日:");
Console.WriteLine("10.儒略日转化为Galileo:");
Console.WriteLine("11.GLonasst化为儒略日:");
Console.WriteLine("12.儒略日转化为GLonasst:");
int a = Convert.ToInt32(Console.ReadLine());
switch (a)
{
case 1:
Console.WriteLine("请输入格里高利日期:");
double Y = Convert.ToDouble(Console.ReadLine());
double M = Convert.ToDouble(Console.ReadLine());
double D = Convert.ToDouble(Console.ReadLine());
double h = Convert.ToDouble(Console.ReadLine());
double m = Convert.ToDouble(Console.ReadLine());
double s = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("转化过的儒略日为{0}", ConvertGeligoriandate(Y, M, D, h, m, s));
break;
case 2:
Console.WriteLine("请输入儒略日:");
double jd = Convert.ToDouble(Console.ReadLine());
Convertjulianday(jd);
break;
case 3:
Console.WriteLine("请输入年,年积日,天内秒:");
double Y1 = Convert.ToDouble(Console.ReadLine());
double A = Convert.ToDouble(Console.ReadLine());
double B = Convert.ToDouble(Console.ReadLine());
ConvertDOYandseconds(Y1, A, B);
break;
case 4:
Console.WriteLine("请输入儒略日以及年份:");
double jdA = Convert.ToDouble(Console.ReadLine());
double Y2= Convert.ToDouble(Console.ReadLine());
Convertjulianday2(jdA, Y2);
break;
case 5:
Console.WriteLine("请输入GPS周以及周内秒:");
double WN = Convert.ToDouble(Console.ReadLine());
double TOW= Convert.ToDouble(Console.ReadLine());
ConvertGps(WN, TOW);
break;
case 6:
Console.WriteLine("请输入儒略日:");
double jdB = Convert.ToDouble(Console.ReadLine());
Convertjulianday3(jdB);
break;
case 7:
Console.WriteLine("请输入BDS周以及周内秒:");
double WN1= Convert.ToDouble(Console.ReadLine());
double TOW1= Convert.ToDouble(Console.ReadLine());
ConvertBDS(WN1, TOW1);
break;
case 8:
Console.WriteLine("请输入儒略日:");
double jdC = Convert.ToDouble(Console.ReadLine());
Convertjulianday4(jdC);
break;
case 9:
Console.WriteLine("请输入Galileo周以及周内秒:");
double WN2= Convert.ToDouble(Console.ReadLine());
double TOW2 = Convert.ToDouble(Console.ReadLine());
ConvertGalileo(WN2, TOW2);
break;
case 10:
Console.WriteLine("请输入儒略日:");
double jdD = Convert.ToDouble(Console.ReadLine());
Convertjulianday5(jdD);
break;
case 11:
Console.WriteLine("请输入GLonnasst计时:");
double N4 = Convert.ToDouble(Console.ReadLine());
double Nt= Convert.ToDouble(Console.ReadLine());
double h1 = Convert.ToDouble(Console.ReadLine());
double m1 = Convert.ToDouble(Console.ReadLine());
double s1 = Convert.ToDouble(Console.ReadLine());
ConvertGlonasst(N4, Nt, h1, m1, s1);
break;
case 12:
Console.WriteLine("请输入儒略日:");
double jdE = Convert.ToDouble(Console.ReadLine());
Convertjulianday6(jdE);
break;
}
}
}
}
由于笔者是C#初学者,部分代码并没有实现简化,今后会在之后的学习过程中不断进行优化,望见谅!