#region 公历、儒略日互转
/// <summary>
/// 给定公历的日期,返回对应的儒略日
/// </summary>
/// <paramname="date">给定的公历日期</param>
/// <returns>儒略日</returns>
public static double DateToJd(DateTime date)
{
return DateToJd(date.Year,date.Month,date.Day);
}
/// <summary>
/// 给定公历的年月日,返回对应的儒略日
/// </summary>
/// <param name="year">年</param>
/// <param name="month">月</param>
/// <param name="day">日</param>
/// <returns>儒略日</returns>
public static double DateToJd(int year,int month,int day)
{
double jd;
double w;
jd = year + (month + day / 100.0) / 100.0;
if (jd > 1582.1014)
{
w = -Math.Floor(year / 100.0) + Math.Floor(year / 400.0) + 2;
}
else if (jd < 1582.1005)
{
w = 0;
}
else
{
return 0;
}
if (month < 2.5)
{
month = month + 12;
year = year - 1;
}
jd = Math.Floor(365.25 * year) + Math.Floor(30.6 * (month + 1)) + day + w + 1720994.5;
return jd;
}
/// <summary>
/// 儒略日转公历
/// </summary>
/// <param name="jd">指定的儒略日</param>
/// <returns>文本格式的公历日期(年/月/日)</returns>
public static string JdToDate(double jd)
{
if (jd < 2299160.5)
{
return JdToDateS(jd);
}
else
{
return JdToDateL(jd);
}
}
private static string JdToDateS(double jd)
{
// 按指定的儒略日计算 公元1582年10月4日 及之前日期的文本格式公历日期,以“/”为分隔符
double xs = jd - Math.Floor(jd); // 儒略日的小数部分
if (xs < 0.5) // 如果小数部份小于0.5,则是前一天的日期
{
jd = jd - 0.5; // 取输入日期的整数部份减半天,方便计算
}
else
{
jd = jd + 0.5; // 取输入日期的整数部份减半天,方便计算
}
int month = 3;
int day = 1;
int year = (int)Math.Floor((jd - 0 - 1721116.5) / 365.25);
double S = jd - 1721116.5 - Math.Floor(365.25 * year);
if (S == 0)
{
year = year - 1;
S = jd - 1721116.5 - Math.Floor(365.25 * year);
}
month = (int)(Math.Floor((S + 122) / 30.6) - 1);
day = (int)(S + 122 - Math.Floor(30.6 * (month + 1)));
if (day == 0)
{
month = month - 1;
day = (int)(S + 122 - Math.Floor(30.6 * (month + 1)));
}
return year.ToString() + "/" + month.ToString() + "/" + day.ToString();
}
private static string JdToDateL(double jd)
{
// 按指定的儒略日计算 公元1582年10月15日 及之后日期的文本格式公历日期,以“/”为分隔符
double xs = jd - Math.Floor(jd); // 儒略日的小数部分
if (xs < 0.5) // 如果小数部份小于0.5,则是前一天的日期
{
jd = jd - 0.5; // 取输入日期的整数部份减半天,方便计算
}
else
{
jd = jd + 0.5; // 取输入日期的整数部份减半天,方便计算
}
// ------------------------------------------------------------------
int year = (int)Math.Floor((jd - 0 - 1721116.5) / 365.25);
// double w = -Math.Floor(year / 100.0) + Math.Floor(year / 400.0) + 2;
// double S = jd - w - 1721116.5 - Math.Floor(365.25 * year);
double w = -10;
for (int y = 1582; y != year; y++)
{
year = (int)Math.Floor((jd - 1721116.5 - w) / 365.25);
w = -Math.Floor(year / 100F) + Math.Floor(year / 400F) + 2;
}
double S = jd - w - 1721116.5 - Math.Floor(365.25 * year);
// ------------------------------------------------------------------
if (S == 0)
{
year = year - 1;
w = -Math.Floor(year / 100.0) + Math.Floor(year / 400.0) + 2;
S = jd - w - 1721116.5 - Math.Floor(365.25 * year);
}
int month = 3;
int day = 1;
month = (int)(Math.Floor((S + 122) / 30.6) - 1);
day = (int)(S + 122 - Math.Floor(30.6 * (month + 1)));
if (day == 0)
{
month = month - 1;
day = (int)(S + 122 - Math.Floor(30.6 * (month + 1)));
}
return year.ToString() + "/" + month.ToString() + "/" + day.ToString();
}
#endregion