Skip to content

将儒略日期转化为公历(格里高利历)日期

Robert Yao edited this page Jul 1, 2019 · 1 revision
/**
 * 将儒略日期转化为公历(格里高利历)日期
 * ========================================================================
 * @param {Number} JD - 表示儒略日期的数值
 * @returns {{year: number, month: number, date: number}}
 */
const convertJD2CE = (JD) => {
  let A
  let B
  let C
  let D
  let E
  let F
  let Z
  let a
  let year
  let month
  let date

  // 由于儒略日的历元为正午12时,公历历元为半夜12时,为统一计算,将儒略历历元前推至0.5日。即为:JD = JD + 0.5
  JD += 0.5

  // 儒略日整数部分为日数,小数部分为时刻,只对整数部分进行运算
  // Z即为所求日到-4712年0时的日数
  Z = Math.floor(JD)
  F = JD - Z

  // 儒略历
  // 由于儒略历和格里历的岁长不同,需分别处理。即自1582年10月15日0时前适用儒略历(岁长365.25),
  // 此后适用格里历(岁长365.2425)。
  if (Z < 2299161) {
    A = Z
  } else {
    // 格里历
    // 为统一计算,可将格里历转换为儒略历,即假设自-4712年1月1日0时起一直使用的是儒略历。
    // 则针对格里历相对儒略历少置闰(400年3闰)的部分给予补上。由于格里历的历元符合新增置闰规则的年份,
    // 可将历元推至符合400年置闰周期的近距,即1600年1月1日,根据儒略日计算公式,得该日的儒略日为2305447.5。
    a = Math.floor((Z - 2305447.5) / 36524.25)
    // 再补上1582年10月4日到10月15日跳过的10天,即为自-4712年1月1日0时到所求日以儒略历计算的总积日
    A = Z + 10 + a - Math.floor(a / 4)
  }

  // 为避免对负数取整的情况,将历元前推至-4716年3月1日0时,需补上相差的日数,合1524日
  B = A + 1524
  // 对所得的积日(儒略历),除以岁长,即为积年(表达式C)
  C = parseInt((B - 122.1) / 365.25)
  // 其中整数部分为年的积日(表达式D)
  D = parseInt(365.25 * C)
  E = parseInt((B - D) / 30.6)
  // 将B-D除以每月平均日数30.6为积月(表达式E),其中整数部分为月数,小数部分为日数(date)
  date = Math.floor(B - D - parseInt(30.6 * E) + F)

  // 最后调整岁首的情况可得month和year
  if (E < 14) {
    month = E - 1
  } else {
    if (E < 16) {
      month = E - 13
    }
  }

  if (month > 2) {
    year = C - 4716
  } else {
    if ([
      1,
      2
    ].includes(month)) {
      year = C - 4715
    }
  }

  return {
    year,
    month,
    date,
    value: year + '-' + month + '-' + date,
    text: year + '' + month + '' + date + ''
  }
}
You can’t perform that action at this time.