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の 2 つの方程式から派生しています。

ここでユーザーから得た最初の回答は、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 は、2000 年 1 月 1 日の値 2451545.0 を使用して、jd から減算して、このように分数の世紀で時間を取得します。

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

3 に答える 3

3

Ruby にはユリウス日を計算する方法がいくつかあり、適切な方法を選択する必要があります。ご存知のように、NOAA は紀元前 4713 年 1 月 1 日グリニッジ正午から JD を計算しています。小数日を省略しているため、常に .5 で終わります。

Ruby のユリウス日は奇妙です。

科学的な目的のために、任意の最初の日から数えて、単に日数として日付を参照すると便利です。これに最初に選ばれた日付は、紀元前 4713 年 1 月 1 日でした。この日付からの日数がユリウス日番号またはユリウス日であり、Date クラスでは jd と省略されます。これは現地時間で、初日の午前 0 時からカウントされます。

これは天文学的な使用には意味がありません。ちょっと待って..

より厳密な使用法は UTC であり、初日の正午からカウントされます。これは Date クラスでは Astronomical Julian Day Number と呼ばれ、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 に答える