-
-
Save DouglasAllen/2032003 to your computer and use it in GitHub Desktop.
```code | |
# Usage | |
# Set your time zone offset at the line tz =.... | |
# Mine is -5 hours use 5.5 if you're on a half hour offset. | |
# The latitude and longitude arguments are my coordinates. | |
# Yours are most likely different. | |
# If you are west of Greenwich meridian then use longitude negative. | |
# If you are south of the equator then use latitude negative. | |
# Ruby program begins | |
@jpd_2000 = 2_451_545.0 | |
@latitude = 41.943 | |
@longitude = -88.75 | |
@tz = -6 | |
def local_angle | |
@longitude / 360.0 | |
end | |
time = Time.now.utc | |
@year = Time.now.year | |
@month = Time.now.month | |
@day = Time.now.day | |
include Math | |
@d2r = PI / 180.0 | |
@r2d = 180.0 / PI | |
require 'date' | |
def jpd_date | |
Date.new(@year, @month, @day).jd | |
end | |
# Calculate current Julian Period Cycle | |
# http://maia.usno.navy.mil/ser7/deltat.data | |
jps_delta_time = 67.0258 / 86_400.0 | |
$ca = 0.00014 # jps_delta_time or 0.0009 adds too much time | |
def jpd_cycle | |
jpd_date - @jpd_2000 | |
end | |
# Mean Solar Transit for your Local Hour Angle | |
def jpd_noon | |
@jpd_2000 + jpd_cycle - local_angle | |
end | |
# Solar Mean Anomaly | |
def mean_anomaly | |
(357.5291 + 0.98560028 * (jpd_noon - @jpd_2000)) % 360 | |
end | |
include Math | |
# Equation of Center | |
def equation_of_center | |
ma_r = mean_anomaly * @d2r | |
1.9148 * sin(ma_r) + 0.0200 * sin(2.0 * ma_r) + 0.0003 * sin(3.0 * ma_r) | |
end | |
# ............. lambda_periapsis.............. | |
# An approximation of angle when earth is closest to sun in a new | |
# year (about the 2nd or 3rd day). There are ways to avoid using it | |
# but since wikipedia does then I will. | |
# ............................................ | |
@lambda_periapsis = 180.0 + 102.9372 | |
def ecliptic_longitude | |
(mean_anomaly + equation_of_center + @lambda_periapsis) % 360 | |
end | |
def j_eot | |
0.0053 * sin(mean_anomaly * @d2r) - | |
0.0069 * sin(2.0 * ecliptic_longitude * @d2r) | |
end | |
def j_transit | |
jpd_noon + j_eot | |
end | |
def sine_declination | |
sin(ecliptic_longitude * @d2r) * | |
sin(23.436 * @d2r) | |
end | |
def declination | |
asin(sine_declination) * @r2d | |
end | |
# Horizon Angle | |
# Horizon Angle is the angle between Sunrise to Transit or Transit to Sunset. | |
def cosine_omega | |
lat_r = @latitude * @d2r | |
dec_r = declination * @d2r | |
sin(-0.8333 * @d2r) - sin(lat_r) * sin(dec_r) / cos(lat_r) * cos(dec_r) | |
end | |
def hour_angle | |
acos(cosine_omega) * @r2d | |
end | |
def j_set | |
j_transit + hour_angle / 360.0 | |
end | |
def j_rise | |
j_transit - hour_angle / 360.0 | |
end | |
def jpd_fraction(jpd_time) | |
fraction = jpd_time - 0.5 - Integer(jpd_time - 0.5) | |
(fraction * 100_000_000.0).round / 100_000_000.0 | |
end | |
def _hours(jpd_time) | |
Integer(jpd_fraction(jpd_time) * 24.0) | |
end | |
def _minutes(jpd_time) | |
hours = _hours(jpd_time) | |
Integer((jpd_fraction(jpd_time) - hours / 24.0) * 1440.0) | |
end | |
def _seconds(jpd_time) | |
hours = _hours(jpd_time) | |
minutes = _minutes(jpd_time) | |
Integer((jpd_fraction(jpd_time) - hours / 24.0 - minutes / 1440.0) * 86_400.0) | |
end | |
def julian_period_day_fraction_to_time(jpd_time) | |
hours = _hours(jpd_time) | |
minutes = _minutes(jpd_time) | |
seconds = _seconds(jpd_time) | |
Time.new(@year, | |
@month, | |
@day, | |
hours, | |
minutes, | |
seconds) + | |
@tz * 3600 | |
end | |
# Output results | |
text = <<-HEREDOC | |
The current time UTC = #{time} | |
Current Julian Cycle = #{jpd_cycle} | |
Julian Mean Solar transit = #{jpd_noon} | |
Approximate Julian EOT = #{j_eot} | |
Julian True Solar transit = #{j_transit} | |
Julian Sunrise #{j_rise} | |
Julian Sunset #{j_set} | |
Local Mean Noon #{julian_period_day_fraction_to_time(jpd_noon)} | |
Local Noon #{julian_period_day_fraction_to_time(j_transit)} | |
Local Sunrise #{julian_period_day_fraction_to_time(j_rise)} | |
Local Sunset #{julian_period_day_fraction_to_time(j_set)} | |
HEREDOC | |
puts text | |
``` |
I'm trying to understand Wikipedia's Sunrise equation page to help my daughters in a math experiment; specifically https://en.wikipedia.org/wiki/Sunrise_equation#Calculate_current_Julian_cycle The meaning of Julian date is clear, but what is the conceptual definition of current Julian cycle? We take our current Julian date (JD), subtract the JD of Jan 1, 2000, subtract our longitude as a fraction of 360 degrees, and round to the nearest integer ... but what does this mean? What is the Julian cycle? (We then use this to compute solar noon.) Thanks for any help you can offer in how to conceptualize this!
I use the term Julian Cycle loosely for the number of days since the year 2000/01/01 12:00.
This is a constant in most calculations of this sort. Even for planets and stars.
It's the reference point that the formula are based on.
We have to add on our longitude as time for convenience paying attention to the direction in terms of Earth rotation.
A western longitude means the point in space comes later than our earthly zero reference point which was the Greenwich Mean Time(GMT).
https://equationoftime.herokuapp.com/gm
But it has since been changed to Coordinated Universal Time(UTC) probably to avoid confusion with sidereal terms like GMST and GAST.
East is ahead of that point by the number of degrees divided by 15.0 to yield it in hours.
We may eliminate that step and just go for the Julian offset longitude / 360.0. Julian is a daily number. 1 day / 24.0 hours gives time.
(see http://curious.astro.cornell.edu/physics/125-observational-astronomy/timekeeping/calendars/763-how-was-the-starting-point-for-the-julian-date-system-chosen-advanced)...
or some equivalent site.
Joseph named this system after his father. He could have called it Joseph Numbers but we honor a mans will sometimes.
Just keep in mind that I just roughed this bit of code together rather quickly just to see it working.
It may some errors but I've done a lot of testing on the EOT gem that I posted the link to.
It's all Ruby code except for some Ruby C extensions.
A nice wrapper for the IAU Standards Of Fundamental Astronomy (SOFA) C library is a gem is called Celes.
https://rubygems.org/gems/celes/versions/0.0.1
This was a long time ago and it's not best practice for Ruby but was a quick scratch together to see if it works kind of thing. I look at it now and see how horrible it is. Rubocop would beat me to my grave. It isn't even OOP because there's no class or instance variables. I'm working on one now though and will post it soon. Thanks for your interest.
see http://en.wikipedia.org/wiki/Sunrise_equation for more information
also http://en.wikipedia.org/wiki/Greek_letters_used_in_mathematics,_science,_and_engineering may be helpful