2

~ 大约太阳正午

lw = 88.743  # my longitude

jdate = Date.ordinal_to_jd(Time.now.year, Time.now.yday)
n = (jdate - 2451545 - 0.0009 - lw / 360).round  # lw is users longitude west of 0.
j_noon = 2451545 + 0.0009 + lw / 360 + n 
puts j_noon

=> 2455616.24740833

作为更新,部分混淆是太阳正午是自公元前 4713 年 1 月 1 日格林威治中午以来所有计算开始的地方。

Date.ordinal_to_jd 的正确使用并没有弥补这一事实。因此,通过像这样添加或减去 12 小时:

jdn = Date.ordinal_to_jd(Time.now.year, Time.now.yday) - 0.5

我们应该得到更少的错误。既然我们的计算是从昨天中午开始的,那么我们使用哪个呢?

该代码来自此页面Sunrise_equation的两个方程式。

我从这里的一位用户那里得到的第一个答案是,我们不了解 0.0009 和 lw / 360 的使用。lw / 360 似乎是本初子午线的小数日。至于 0.0009,它必须是自公元前 4713 年 1 月 1 日格林威治中午以来以秒为单位的少量方差。有关更多信息,请参阅 IAU 标准

根据此页面,我计算为 0.007776 秒。

我有一些来自 Date 类的信息,不包括方法细节。

        =begin
--------------------------------------------------------------------- Class: Date
Class representing a date.

See the documentation to the file date.rb for an overview.

Internally, the date is represented as an Astronomical Julian Day Number, ajd. 
The Day of Calendar Reform, sg, is also stored, for conversions to other date formats. 
(There is also an of field for a time zone offset, 
but this is only for the use of the DateTime subclass.)

A new Date object is created using one of the object creation class methods named  
after the corresponding date format, and the arguments appropriate to that date
format; for instance, Date::civil() 
(aliased to Date::new()) with year, month, and day-of-month, or Date::ordinal() with
year and day-of-year.

All of these object creation class methods also take the Day of Calendar Reform as an
optional argument.

Date objects are immutable once created.

Once a Date has been created, date values can be retrieved for the different date
formats supported using instance methods. For instance, #mon() gives the Civil month,
#cwday() gives the Commercial day of the week, and #yday() gives the Ordinal day of
the year. Date values can be retrieved in any format, regardless of what format was
used to create the Date instance.

The Date class includes the Comparable module, allowing date objects to be compared
and sorted, ranges of dates to be created, and so forth.

---------------------------------------------------------------------------------

Includes:
Comparable(<, <=, ==, >, >=, between?)

Constants:
MONTHNAMES:      [nil] + %w(January February March April May June July August
                            September October November December)
DAYNAMES:        %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday)
ABBR_MONTHNAMES: [nil] + %w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
ABBR_DAYNAMES:   %w(Sun Mon Tue Wed Thu Fri Sat)
ITALY:           2299161
ENGLAND:         2361222
JULIAN:          Infinity.new
GREGORIAN:       -Infinity.new

Class methods:
_load, _parse, _strptime, ajd_to_amjd, ajd_to_jd, amjd_to_ajd, civil, civil_to_jd,
commercial, commercial_to_jd, day_fraction_to_time, gregorian?, gregorian_leap?, jd,
jd_to_ajd, jd_to_civil, jd_to_commercial, jd_to_ld, jd_to_mjd, jd_to_ordinal,
jd_to_wday, julian?, julian_leap?, ld_to_jd, mjd_to_jd, new, now, ordinal,
ordinal_to_jd, parse, s3e, strptime, time_to_day_fraction, today, valid_civil?,
valid_commercial?, valid_jd?, valid_ordinal?, valid_time?

Instance methods:
+, -, <<, <=>, ===, >>, _dump, ajd, amjd, asctime, civil, commercial, ctime, cwday,
cweek, cwyear, day, day_fraction, downto, england, eql?, gregorian, gregorian?, hash,
hour, inspect, italy, jd, julian, julian?, ld, leap?, mday, min, mjd, mon, month,
new_offset, new_start, next, next_day, offset, ordinal, sec, sec_fraction, start,
step, strftime, succ, time, to_s, to_yaml, upto, wday, weeknum0, weeknum1, wnum0, 
wnum1, yday, year, zone

=end

附带说明一下,Ruby 有一种计算朱利安日期的方法真是太好了。我正在研究NOAA的 Javascript 代码。

这是我受到链接启发而写的一堂课。

class JulianDayNumber

  def initialize(year = 2000, month = 1, day = 1) #defaults to Jan. 01, 2000
    @year = year
    @month = month
    @day = day
  end

  def calcJDN

    if (@month <= 2) then 
      @year -= 1
      @month += 12
    end

    varA = (@year/100).floor
    varB = 2 - varA + (varA/4).floor

    jdn = (365.25*(@year + 4716)).floor \
           + (30.6001*(@month+1)).floor \
           + @day + varB - 1524.5

    return jdn
  end

end

jd = JulianDayNumber.new(2011, 3, 2)
julianday = jd.calcJDN
puts julianday

=> 2455622.5

现在这让我到了那里,但我仍在研究如何返回一个数字,例如由最上面的方程计算的数字。试试这个,我们可以看到我们在 JDN 中确实得到了 0.5。谁是对的?红宝石还是 NOAA?


NOAA 使用从 jd 中减去的 2000 年 1 月 1 日值 2451545.0 来获得像这样的分数世纪时间

    def calcTimeJulianCent(j)
      t = (j - 2451545.0)/36525.0
      return t
    end 
4

3 回答 3

3

Ruby 有多种计算 Julian Day 的方法,您需要选择正确的一种。如您所知,NOAA 从 4713 年 1 月 1 日格林威治中午开始计算 JD。它总是以 0.5 结尾,因为它们省略了小数天。

Ruby 的 Julian Day 很奇怪:

出于科学目的,将日期简单地称为天数是很方便的,从任意的初始日期开始计数。为此首先选择的日期是公元前 4713 年 1 月 1 日。从该日期算起的天数是 Julian Day Number 或 Julian Date,在 Date 类中缩写为 jd。这是当地时间,从第一天的午夜开始计算。

这对天文用途毫无意义。可是等等..

更严格的用法是 UTC,从第一天的中午开始计算。这在 Date 类中称为天文儒略日数,缩写为 ajd。在 Date 类中,天文儒略日数包括小数天数。

红宝石

这就是你要找的东西,ajd。无需小数天即可获得它:

julianday = Date.civil(@year, @month, @day).ajd
puts julianday

=> 2455622.5

无需从 NOAA 移植 9 行 JavaScript。鲁比支持你!;)

于 2011-03-08T10:56:42.150 回答
0

好吧,谢谢大家,我想我现在可以回答我自己的问题了。我忽略了 Date 类中的一个简单方法。它是 Date.day_fraction_to_time(天小数)。因为我现在有一个工作程序,所以我想与大家分享。

include Math
to_r = PI / 180.0
to_d = 180.0 / PI

latitude = 41.9478 # my latitude
longitude = 88.74277  # my longitude
lw = longitude / 360

jdate = Date.civil(Time.now.year, Time.now.month, Time.now.day).ajd
jdate = (jdate * 2).to_i/2 + 1

n = (jdate - 2451545 - 0.0009 - lw).round
j_noon = 2451545  + 0.0009   + lw  + n
mean_anomaly = (357.52911 + 0.98560028 * (jdate - 2451545)) % 360
center = 1.9148 * sin(mean_anomaly * to_r) + 0.0200 * sin(2 * mean_anomaly * to_r) + \
         0.0003 * sin(3 *  mean_anomaly * to_r)
lambda = (mean_anomaly + 102.9372 + center + 180) % 360
j_transit = j_noon + (0.0053 * sin(mean_anomaly * to_r)) - (0.0069 * sin(2 * lambda * \
            to_r))
delta = asin(0.397753054 * sin(lambda * to_r)) * to_d
omega = acos(sin(-0.83 * to_r)/cos(latitude * to_r) * cos(delta * to_r) \
        - tan(latitude * to_r) * tan(delta * to_r)) * to_d
j_set = 2451545 + 0.0009 + ((omega + longitude)/360 + n + 0.0053 * sin(mean_anomaly * \
        to_r)) - 0.0069 * sin(2 * lambda * to_r)

j_rise = j_transit - (j_set - j_transit)

rise = Date.day_fraction_to_time(j_rise - jdate)# + 0.25 for + 6 hours
risehour = rise[0].to_s
risemin = rise[1].to_s
risetime = "#{risehour}:#{risemin}"
puts "Sun rise = #{risetime} UTC"

transit = Date.day_fraction_to_time(j_transit - jdate)# + 0.25
transithour = transit[0].to_s
transitmin = transit[1].to_s
transittime = "#{transithour}:#{transitmin}"
puts "Solar noon = #{transittime} UTC"

set = Date.day_fraction_to_time(j_set - jdate)# + 0.25
sethour = set[0].to_s
setmin = set[1].to_s
settime = "#{sethour}:#{setmin} UTC"
puts "Sun set = #{settime}"
于 2011-03-12T04:23:47.877 回答
0

ordinal_to_jd 方法将 2011 年(公历)索引为 0 的日期转换为儒略历中的相应日期,然后您使用 0.0009 的神奇值,我不知道任何原因,然后您正在添加比率您的整个 360* 圈的经度(东还是西?),然后添加今天的一年中的某一天(如果您今天评估它,则为 54)。儒略历和纵向比率的组合没有多大意义,但嘿,这是一个不错的数字,因为您混合了 0.0009 英寸。

于 2011-02-23T18:49:03.053 回答