Bhikkhu-Kosalla 5 سال پیش
والد
کامیت
e0ac64c7fd
4فایلهای تغییر یافته به همراه404 افزوده شده و 8 حذف شده
  1. 5 0
      app/calendar/index1.html
  2. 12 0
      app/calendar/julian.js
  3. 32 8
      app/calendar/lib/README.md
  4. 355 0
      app/calendar/lune.js

+ 5 - 0
app/calendar/index1.html

@@ -13,6 +13,8 @@
     <script src="../public/js/jquery.js"></script>
     <script src="../public/js/comm.js"></script>
     <script src="jquery-3.3.1.min.js"></script>
+    <script src="lib/julian.js"></script>
+    <script src="lib/lune.js"></script>
     <script src="suncalc.js"></script>
     <script src="../studio/js/fixedsticky.js"></script>
     <script src="../guide/guide.js"></script>
@@ -437,6 +439,9 @@
 
     </div>
     <script>
+        var current_phase = lune.phase()
+        console.log(current_phase)//输出到控制台
+
         $("#title_text").html(localString[g_language].BE);
         var g_coordinate_this = new Object();
         var g_now_date = new Date();

+ 12 - 0
app/calendar/julian.js

@@ -0,0 +1,12 @@
+'use strict'
+
+function fromDate (date) {
+  return date.getTime() / 86400000 + 2440587.5
+}
+
+function toDate (julian) {
+  return new Date((julian - 2440587.5) * 86400000)
+}
+
+exports.fromDate = fromDate
+exports.toDate = toDate

+ 32 - 8
app/calendar/lib/README.md

@@ -14,12 +14,12 @@ npm install lune
 
 ## Usage
 
-### To calculate *current* phase information:
+### To calculate *current* phase information:计算*当前*相的信息
 
 ```javascript
-var lune = require('lune')
+var lune = require('lune')//
 var current_phase = lune.phase()
-console.log(current_phase)
+console.log(current_phase)//输出到控制台
 ```
 
 #### Output:
@@ -33,9 +33,17 @@ console.log(current_phase)
   sun_distance: 148929846.0148686,
   sun_angular_diameter: 0.5354732715700135 }
 ```
+- phase: 月相,
+- illuminated: 亮度,
+- age: 月龄,
+- distance: 地月距离,
+- angular_diameter: 月角直径
+- sun_distance: 地日距离,
+- sun_angular_diameter: 日角直径
 
-### To calculate phase information for a *specific* date:
 
+### To calculate phase information for a *specific* date:
+计算一个*指定*日期的相的信息
 ```javascript
 var lune = require('lune')
 var some_date = new Date('2014-02-17T00:00-0500')
@@ -54,9 +62,16 @@ console.log(some_date_phase)
   sun_distance: 147822484.14817196,
   sun_angular_diameter: 0.5394845874736046 }
 ```
+- phase: 月相,
+- illuminated: 亮度,
+- age: 月龄,
+- distance: 地月距离,
+- angular_diameter: 月角直径
+- sun_distance: 地日距离,
+- sun_angular_diameter: 日角直径
 
 ### To search for recent phases around the *current* date:
-
+在*当前*日期附近搜索最近的相
 ```javascript
 var lune = require('lune')
 var recent_phases = lune.phase_hunt()
@@ -72,9 +87,13 @@ console.log(recent_phases)
   q3_date: Thu Mar 31 2016 11:18:41 GMT-0400 (EDT),
   nextnew_date: Thu Apr 07 2016 07:25:20 GMT-0400 (EDT) }
 ```
-
+- new_date: 新月日期
+- q1_date: 上弦月日期
+- full_date: 满月日期
+- q3_date: 下弦月日期
+- nextnew_date: 下次新月日期
 ### To search for recent phases around a *specific* date:
-
+在*指定*日期附近搜索最近的相
 ```javascript
 var lune = require('lune')
 var some_date = new Date('2014-02-17T00:00-0500')
@@ -91,9 +110,14 @@ console.log(some_date_phase)
   q3_date: Sat Feb 22 2014 12:16:56 GMT-0500 (EST),
   nextnew_date: Sat Mar 01 2014 03:02:41 GMT-0500 (EST) }
 ```
+- new_date: 新月日期
+- q1_date: 上弦月日期
+- full_date: 满月日期
+- q3_date: 下弦月日期
+- nextnew_date: 下次新月日期
 
 ### To search for phases between two dates:
-
+在两个日期之间搜索相
 ```javascript
 // print all full moons in the first quarter of 2014
 var lune = require('lune')

+ 355 - 0
app/calendar/lune.js

@@ -0,0 +1,355 @@
+/**
+ * This library calculates the current phase of the moon
+ * as well as finds the dates of the recent moon phases.
+ *
+ * Some functionality is ported from python version found here:
+ * https://bazaar.launchpad.net/~keturn/py-moon-phase/trunk/annotate/head:/moon.py
+ *
+ * Some functionality is taken from Astronomical Algorithms, 2nd ed.
+ *
+ * Some functionality is taken from the US Naval Observatory, described here:
+ * https://aa.usno.navy.mil/faq/docs/SunApprox.php
+ *
+ * Author: Ryan Seys (https://github.com/ryanseys)
+ * Author: Jay LaPorte (https://github.com/ironwallaby)
+ */
+
+'use strict'
+
+const julian = require('./julian')
+
+// Phases of the moon & precision
+const NEW = 0
+const FIRST = 1
+const FULL = 2
+const LAST = 3
+const PHASE_MASK = 3
+
+// Astronomical Constants
+// Semi-major axis of Earth's orbit, in kilometers
+const SUN_SMAXIS = 1.49585e8
+
+// SUN_SMAXIS premultiplied by the angular size of the Sun from the Earth
+const SUN_ANGULAR_SIZE_SMAXIS = SUN_SMAXIS * 0.533128
+
+// Semi-major axis of the Moon's orbit, in kilometers
+const MOON_SMAXIS = 384401.0
+
+// MOON_SMAXIS premultiplied by the angular size of the Moon from the Earth
+const MOON_ANGULAR_SIZE_SMAXIS = MOON_SMAXIS * 0.5181
+
+// Synodic month (new Moon to new Moon), in days
+const SYNODIC_MONTH = 29.53058868
+
+/**
+ * Convert degrees to radians
+ * @param  {Number} d Angle in degrees
+ * @return {Number}   Angle in radians
+ */
+function torad (d) {
+  return (Math.PI / 180.0) * d
+}
+
+/**
+ * Convert radians to degrees
+ * @param  {Number} r Angle in radians
+ * @return {Number}   Angle in degrees
+ */
+function dsin (d) {
+  return Math.sin(torad(d))
+}
+
+function dcos (d) {
+  return Math.cos(torad(d))
+}
+
+/**
+ * Convert astronomical units to kilometers
+ * @param  {Number} au Distance in astronomical units
+ * @return {Number}    Distance in kilometers
+ */
+function tokm (au) {
+  return 149597870.700 * au
+}
+
+/**
+ * Finds the phase information for specific date.
+ * @param  {Date}   date Date to get phase information of.
+ * @return {Object}      Phase data
+ */
+function phase (date) {
+  if (!date) {
+    date = new Date()
+  }
+  if (!(date instanceof Date)) {
+    throw new TypeError('Invalid parameter')
+  }
+  if (Number.isNaN(date.getTime())) {
+    throw new RangeError('Invalid Date')
+  }
+
+  // t is the time in "Julian centuries" of 36525 days starting from 2000-01-01
+  // (Note the 0.3 is because the UNIX epoch is on 1970-01-01 and that's 3/10th
+  // of a century before 2000-01-01, which I find cute :3 )
+  const t = date.getTime() * (1 / 3155760000000) - 0.3
+
+  // lunar mean elongation (Astronomical Algorithms, 2nd ed., p. 338)
+  const d = 297.8501921 + t * (445267.1114034 + t * (-0.0018819 + t * ((1 / 545868) + t * (-1 / 113065000))))
+
+  // solar mean anomaly (p. 338)
+  const m = 357.5291092 + t * (35999.0502909 + t * (-0.0001536 + t * (1 / 24490000)))
+
+  // lunar mean anomaly (p. 338)
+  const n = 134.9633964 + t * (477198.8675055 + t * (0.0087414 + t * ((1 / 69699) + t * (-1 / 14712000))))
+
+  // derive sines and cosines necessary for the below calculations
+  const sind = dsin(d)
+  const sinm = dsin(m)
+  const sinn = dsin(n)
+  const cosd = dcos(d)
+  const cosm = dcos(m)
+  const cosn = dcos(n)
+
+  // use trigonometric identities to derive the remainder of the sines and
+  // cosines we need. this reduces us from needing 14 sin/cos calls to only 7,
+  // and makes the lunar distance and solar distance essentially free.
+  // http://mathworld.wolfram.com/Double-AngleFormulas.html
+  // http://mathworld.wolfram.com/TrigonometricAdditionFormulas.html
+  const sin2d = 2 * sind * cosd // sin(2d)
+  const sin2n = 2 * sinn * cosn // sin(2n)
+  const cos2d = 2 * cosd * cosd - 1 // cos(2d)
+  const cos2m = 2 * cosm * cosm - 1 // cos(2m)
+  const cos2n = 2 * cosn * cosn - 1 // cos(2n)
+  const sin2dn = sin2d * cosn - cos2d * sinn // sin(2d - n)
+  const cos2dn = cos2d * cosn + sin2d * sinn // cos(2d - n)
+
+  // lunar phase angle (p. 346)
+  const i = 180 - d - 6.289 * sinn + 2.100 * sinm - 1.274 * sin2dn - 0.658 * sin2d - 0.214 * sin2n - 0.110 * sind
+
+  // fractional illumination (p. 345)
+  const illumination = dcos(i) * 0.5 + 0.5
+
+  // fractional lunar phase
+  let phase = 0.5 - i * (1 / 360)
+  phase -= Math.floor(phase)
+
+  // lunar distance (p. 339-342)
+  // XXX: the book is not clear on how many terms to use for a given level of
+  // accuracy! I used all the easy ones that we already have for free above,
+  // but I imagine this is more than necessary...
+  const moonDistance = 385000.56 - 20905.355 * cosn - 3699.111 * cos2dn - 2955.968 * cos2d - 569.925 * cos2n + 108.743 * cosd
+
+  // solar distance
+  // https://aa.usno.navy.mil/faq/docs/SunApprox.php
+  const sunDistance = tokm(1.00014 - 0.01671 * cosm - 0.00014 * cos2m)
+
+  return {
+    phase: phase,
+    illuminated: illumination,
+    age: phase * SYNODIC_MONTH,
+    distance: moonDistance,
+    angular_diameter: MOON_ANGULAR_SIZE_SMAXIS / moonDistance,
+    sun_distance: sunDistance,
+    sun_angular_diameter: SUN_ANGULAR_SIZE_SMAXIS / sunDistance
+  }
+}
+
+/**
+ * Calculates time of the mean new Moon for a given base date.
+ * This argument K to this function is the precomputed synodic month
+ * index, given by:
+ *   K = (year - 1900) * 12.3685
+ * where year is expressed as a year and fractional year.
+ * @param  {Date} sdate   Start date
+ * @param  {[type]} k     [description]
+ * @return {[type]}       [description]
+ */
+function meanphase (sdate, k) {
+  // Time in Julian centuries from 1900 January 12 noon UTC
+  const delta = (sdate - -2208945600000.0) / 86400000.0
+  const t = delta / 36525
+  return 2415020.75933 +
+    SYNODIC_MONTH * k +
+    (0.0001178 - 0.000000155 * t) * t * t +
+    0.00033 * dsin(166.56 + (132.87 - 0.009173 * t) * t)
+}
+
+/**
+ * Given a K value used to determine the mean phase of the new moon, and a
+ * phase selector (0, 1, 2, 3), obtain the true, corrected phase time.
+ * @param  {[type]} k      [description]
+ * @param  {[type]} tphase [description]
+ * @return {[type]}        [description]
+ */
+function truephase (k, tphase) {
+  // restrict tphase to (0, 1, 2, 3)
+  tphase = tphase & PHASE_MASK
+
+  // add phase to new moon time
+  k = k + 0.25 * tphase
+
+  // Time in Julian centuries from 1900 January 0.5
+  const t = (1.0 / 1236.85) * k
+
+  // Mean time of phase
+  let pt = 2415020.75933 +
+    SYNODIC_MONTH * k +
+    (0.0001178 - 0.000000155 * t) * t * t +
+    0.00033 * dsin(166.56 + (132.87 - 0.009173 * t) * t)
+
+  // Sun's mean anomaly
+  const m = 359.2242 + 29.10535608 * k - (0.0000333 - 0.00000347 * t) * t * t
+
+  // Moon's mean anomaly
+  const mprime = 306.0253 + 385.81691806 * k + (0.0107306 + 0.00001236 * t) * t * t
+
+  // Moon's argument of latitude
+  const f = 21.2964 + 390.67050646 * k - (0.0016528 - 0.00000239 * t) * t * t
+
+  // use different correction equations depending on the phase being sought
+  switch (tphase) {
+    // new and full moon use one correction
+    case NEW:
+    case FULL:
+      pt += (0.1734 - 0.000393 * t) * dsin(m) +
+        0.0021 * dsin(2 * m) -
+        0.4068 * dsin(mprime) +
+        0.0161 * dsin(2 * mprime) -
+        0.0004 * dsin(3 * mprime) +
+        0.0104 * dsin(2 * f) -
+        0.0051 * dsin(m + mprime) -
+        0.0074 * dsin(m - mprime) +
+        0.0004 * dsin(2 * f + m) -
+        0.0004 * dsin(2 * f - m) -
+        0.0006 * dsin(2 * f + mprime) +
+        0.0010 * dsin(2 * f - mprime) +
+        0.0005 * dsin(m + 2 * mprime)
+      break
+
+    // first and last quarter moon use a different correction
+    case FIRST:
+    case LAST:
+      pt += (0.1721 - 0.0004 * t) * dsin(m) +
+        0.0021 * dsin(2 * m) -
+        0.6280 * dsin(mprime) +
+        0.0089 * dsin(2 * mprime) -
+        0.0004 * dsin(3 * mprime) +
+        0.0079 * dsin(2 * f) -
+        0.0119 * dsin(m + mprime) -
+        0.0047 * dsin(m - mprime) +
+        0.0003 * dsin(2 * f + m) -
+        0.0004 * dsin(2 * f - m) -
+        0.0006 * dsin(2 * f + mprime) +
+        0.0021 * dsin(2 * f - mprime) +
+        0.0003 * dsin(m + 2 * mprime) +
+        0.0004 * dsin(m - 2 * mprime) -
+        0.0003 * dsin(2 * m + mprime)
+
+      // the sign of the last term depends on whether we're looking for a first
+      // or last quarter moon!
+      const sign = (tphase < FULL) ? +1 : -1
+      pt += sign * (0.0028 - 0.0004 * dcos(m) + 0.0003 * dcos(mprime))
+
+      break
+  }
+
+  return julian.toDate(pt)
+}
+
+/**
+ * Find time of phases of the moon which surround the current date.
+ * Five phases are found, starting and ending with the new moons
+ * which bound the current lunation.
+ * @param  {Date} sdate Date to start hunting from (defaults to current date)
+ * @return {Object}     Object containing recent past and future phases
+ */
+function phaseHunt (sdate) {
+  if (!sdate) {
+    sdate = new Date()
+  }
+  if (!(sdate instanceof Date)) {
+    throw new TypeError('Invalid parameter')
+  }
+  if (Number.isNaN(sdate.getTime())) {
+    throw new RangeError('Invalid Date')
+  }
+
+  let adate = new Date(sdate.getTime() - (45 * 86400000)) // 45 days prior
+  let k1 = Math.floor(12.3685 * (adate.getFullYear() + (1.0 / 12.0) * adate.getMonth() - 1900))
+  let nt1 = meanphase(adate.getTime(), k1)
+
+  sdate = julian.fromDate(sdate)
+  adate = nt1 + SYNODIC_MONTH
+  let k2 = k1 + 1
+  let nt2 = meanphase(adate, k2)
+  while (nt1 > sdate || sdate >= nt2) {
+    adate += SYNODIC_MONTH
+    k1++
+    k2++
+    nt1 = nt2
+    nt2 = meanphase(adate, k2)
+  }
+
+  return {
+    new_date: truephase(k1, NEW),
+    q1_date: truephase(k1, FIRST),
+    full_date: truephase(k1, FULL),
+    q3_date: truephase(k1, LAST),
+    nextnew_date: truephase(k2, NEW)
+  }
+}
+
+function phaseRange (start, end, phase) {
+  if (!(start instanceof Date)) {
+    throw new TypeError('First argument must be a Date object.')
+  }
+  if (Number.isNaN(start.getTime())) {
+    throw new RangeError('First argument not a valid date.')
+  }
+  if (!(end instanceof Date)) {
+    throw new TypeError('Second argument must be a Date object.')
+  }
+  if (Number.isNaN(end.getTime())) {
+    throw new RangeError('Second argument not a valid date.')
+  }
+
+  if (end - start < 0) {
+    let temp = end
+    end = start
+    start = temp
+  }
+
+  start = start.getTime()
+  end = end.getTime()
+
+  let t = start - 45 * 86400000
+
+  let k
+  {
+    const d = new Date(t)
+    k = Math.floor(12.3685 * (d.getFullYear() + (1.0 / 12.0) * d.getMonth() - 1900))
+  }
+
+  let date = truephase(k, phase)
+  // skip every phase before starting date
+  while (date.getTime() < start) {
+    k++
+    date = truephase(k, phase)
+  }
+  // add every phase before (or on!) ending date to a list, and return it
+  const list = []
+  while (date.getTime() <= end) {
+    list.push(date)
+    k++
+    date = truephase(k, phase)
+  }
+  return list
+}
+
+exports.PHASE_NEW = NEW
+exports.PHASE_FIRST = FIRST
+exports.PHASE_FULL = FULL
+exports.PHASE_LAST = LAST
+exports.phase = phase
+exports.phase_hunt = phaseHunt
+exports.phase_range = phaseRange