使用Ruby Date类获取天文数据

时间:2011-02-23 18:38:21

标签: ruby astronomy ordinal julian-date

〜近似太阳中午

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标准

根据此page,我将其计算为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很有可能计算julian-date。     我正在查看来自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。谁是对的? Ruby还是NOAA?


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

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

3 个答案:

答案 0 :(得分:3)

Ruby有多种计算朱利安日的方法,你需要选择正确的方法。如你所知,NOAA正在计算自公元前4713年1月1日格林威治中午以来的JD。它始终以.5结尾,因为它们会遗漏分数天。

Ruby的Julian Day很奇怪:

  

出于科学目的,它是   方便简单地参考日期   作为一天的计数,从一个数   任意的第一天。第一个日期   为此选择的是4713年1月1日   BCE。从这个日期算起的天数是   朱利安日号或朱利安日期,   在日期中缩写为jd   类。这是当地时间,而且   从最初的午夜算起   一天。

对于天文使用没有任何意义。但等等..

  

更严格的用法是UTC,和   从第一天中午算起。   这在Date类中引用   作为天文朱利安日数,   并缩写为ajd。在日期   班级,天文朱利安日   号码包括小数天。

rubydoc

这就是你要找的东西,ajd。只是在没有分数天的情况下得到它:

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

=> 2455622.5

无需从NOAA移植9行JavaScript。 Ruby让你回来了! ;)

答案 1 :(得分:0)

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

答案 2 :(得分:0)

非常感谢大家,我想我现在可以回答我自己的问题了。我忽略了Date类中的一个简单方法。它是Date.day_fraction_to_time(日小数)。由于我现在有一个工作程序,我想与eveyone分享。

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}"