Aldebaran has asked for the wisdom of the Perl Monks concerning the following question:
Hello Monks,
When did fall begin? Is there only one answer to that question? I'm honestly not sure. Let me describe the scene in terms of the dynamics of gilligan's island, because if we can't generalize to the arbitrary location in the pacific, then this isn't much of a script. 'MaryAnn' and I found ourselves on an island with a west wind coming in that made it hard to stand. It was 9/11, and our phones were gone. The Gilligan in me savors being lost, but we were up against the elements, and knowing west was important. In such conditions, we hunkered down, stayed close, estimated waves, and watched events along the ecliptic.
Several days after the ordeal, we're looking at the sunset, talking about the onset of fall, and this time with perl at hand...didn't want to donate my computer to the Columbia. I looked at the sky maps and realized that fall occurs exactly when the sun sets in the west. Maryann's question was "how long was the day today?" I'd like to be informed by my compiler. Output precedes code.
C:\Users\Fred\Desktop>perl fall1.pl
cos tau = - tan phi * tan delta
onset of fall ==> delta equal zero
delta is 0
phi is latitude: 45 in portland (close enough)
phi is 0.785398163397448
rhs is 0
tau is 1.5707963267949
degrees is 90
C:\Users\Fred\Desktop>type fall1.pl
#!/usr/bin/perl -w
use strict;
use 5.010;
use Math::Trig;
use Math::Trig ':pi';
say "cos tau = - tan phi * tan delta";
say "onset of fall ==> delta equal zero";
my $delta = tan( 0);
say "delta is $delta";
say "phi is latitude: 45 in portland (close enough)";
my $phi = deg2rad(45);
say "phi is $phi";
my $rhs = - tan ($phi) * tan ($delta);
say "rhs is $rhs";
my $tau = acos($rhs);
say "tau is $tau";
my $degrees = rad2deg($tau);
say "degrees is $degrees";
I'm given to believe that the output in degrees is a measurement of time. I've read two differing treatments on how it is *exactly* so, both of which differ, and are wrong. The better one gets to 1.3%. That's not good enough for an oblate spheroid, unless I can't come up with better. What's more, the entire scenario makes me think of re-creating giant wheels, and history is replete with able people who have been making this a thing for much longer than I have.
My question is: when did fall hit you?
Счастливая осень!
Re: calculate length of day as function of space at onset of fall
by haukex (Archbishop) on Sep 24, 2016 at 11:01 UTC
|
Hi Datz_cozee75,
When did fall begin? Is there only one answer to that question?
A quick reading of Wikipedia leads me to believe that there are plenty of different definitions of the beginnings and ends of the seasons, depending on region and culture. But apparently in North America (aside from the simpler meteorological definitions based on calendar months), it's the March & September equinoxes and the June & December solstices. That also seems to match with your definition, "fall occurs exactly when the sun sets in the west".
how long was the day today?
A bit more research, and CPAN comes to the rescue. First, the output:
At 21.3N 157.816667W:
In 2016:
Spring begins on the March equinox at 2016-03-19 18:29:48 HST.
Sunrise is at 06:32:58 HST, sunset is at 18:40:50 HST,
and the day is 12 hours, 7 minutes, and 52 seconds long.
Summer begins on the June solstice at 2016-06-20 12:33:55 HST.
Sunrise is at 05:48:34 HST, sunset is at 19:14:27 HST,
and the day is 13 hours, 25 minutes, and 53 seconds long.
Fall begins on the September equinox at 2016-09-22 04:20:41 HST.
Sunrise is at 06:18:46 HST, sunset is at 18:24:11 HST,
and the day is 12 hours, 5 minutes, and 25 seconds long.
Winter begins on the December solstice at 2016-12-21 00:44:00 HST.
Sunrise is at 07:03:22 HST, sunset is at 17:53:41 HST,
and the day is 10 hours, 50 minutes, and 19 seconds long.
In 2017:
Spring begins on the March equinox at 2017-03-20 00:28:31 HST.
Sunrise is at 06:32:16 HST, sunset is at 18:41:04 HST,
and the day is 12 hours, 8 minutes, and 48 seconds long.
Summer begins on the June solstice at 2017-06-20 18:23:42 HST.
Sunrise is at 05:48:31 HST, sunset is at 19:14:24 HST,
and the day is 13 hours, 25 minutes, and 53 seconds long.
Fall begins on the September equinox at 2017-09-22 10:01:07 HST.
Sunrise is at 06:18:43 HST, sunset is at 18:24:25 HST,
and the day is 12 hours, 5 minutes, and 42 seconds long.
Winter begins on the December solstice at 2017-12-21 06:27:50 HST.
Sunrise is at 07:03:15 HST, sunset is at 17:53:33 HST,
and the day is 10 hours, 50 minutes, and 18 seconds long.
And the code:
I know this doesn't address the "as function of space" part of the question, but still, a fun little weekend project :-)
Update: Perhaps Astro::Coord::ECI::Sun could be useful?
Regards, -- Hauke D | [reply] [d/l] [select] |
|
Thank you, hauke. You have answered my question much more thoroughly than I had hoped for as a final result on this thread. What a tour de force for cpan. I removed the loop that iterated over years, and instead created one that supplies the sun heights for several of the cases mentioned here: http://search.cpan.org/dist/DateTime-Event-Sunrise/lib/DateTime/Event/Sunrise.pm#Sun_Height I had always puzzled about how you account for the sun not being a point source. Well, this is it, mod one. My current script is:
#!/usr/bin/perl
use warnings;
use strict;
use 5.010;
use Astro::Utils;
use DateTime;
use DateTime::Event::Sunrise;
use DateTime::Format::Strptime;
use DateTime::Format::Human::Duration;
my $LONG = -122.5; # E = +, W = -
my $LAT = 45; # N = +, S = -
my $ZONE = 'America/Los_Angeles';
for my $sun_height ( 0, -0.833, -6, -12, -18 ) {
my $sun = DateTime::Event::Sunrise->new(
precise => 1,
longitude => $LONG,
latitude => $LAT,
altitude => $sun_height
);
say "sun height is $sun_height";
my $strp = DateTime::Format::Strptime->new(
pattern => '%Y-%m-%d %H:%M:%S',
time_zone => 'UTC',
on_error => 'croak'
);
my $durfmt = DateTime::Format::Human::Duration->new();
print "At "
. abs($LAT)
. ( $LAT > 0 ? "N" : "S" ) . " "
. abs($LONG)
. ( $LONG > 0 ? "E" : "W" ) . ":\n";
my $now_year = DateTime->now->year;
for my $year ($now_year) {
print " In $year:\n";
my @seas = (
[
'Spring', 'March equinox', calculate_equinox( 'mar', 'utc'
+, $year )
],
[
'Summer',
'June solstice',
calculate_solstice( 'jun', 'utc', $year )
],
[
'Fall',
'September equinox',
calculate_equinox( 'sep', 'utc', $year )
],
[
'Winter',
'December solstice',
calculate_solstice( 'dec', 'utc', $year )
],
);
for my $seas (@seas) {
my ( $sname, $when, $start ) = @$seas;
$start = $strp->parse_datetime($start);
$start->set_time_zone($ZONE);
my $rise = $sun->sunrise_datetime($start);
my $set = $sun->sunset_datetime($start);
my $dur = $durfmt->format_duration_between( $rise, $set );
print " $sname begins on the $when at ",
$start->strftime('%Y-%m-%d %H:%M:%S %Z'), ".\n";
print " Sunrise is at ", $rise->strftime('%H:%M:%S %Z'),
", sunset is at ", $set->strftime('%H:%M:%S %Z'), ",\n";
print " and the day is $dur long.\n";
}
}
}
The output is interesting but verbose:
It is true that D. Rolsky, haukex, and many others made the solution to my question simply a matter of installing cpan modules and replicating code, yet I seek to extend this result into the idiom of _Intermediate Perl_ and Gilligan's island. I've been checking off exercises as I go through, and submitting a pull request on github was one of them. https://github.com/TBlazer66/ephemeris/pull/1/commits/523b4584798a0589cb3c083cc3db3716c37dd046
I know this doesn't address the "as function of space" part of the question, but still, a fun little weekend project :-)
On the contrary, it covers it pretty well for a terrestrial coordinate system with r fixed. Having latitude and longitude, they form an orthogonal spacial basis of order 3, which along with time creates the Vierervektor. The missing element I can't get over is r. There's a lot of things that make a viewer taller at a given location, like mountains, or being a couple standard deviations above the norm in height, and to the contrary dwarves, but they see the sun set too with a differing metric. The shape of this "shell" is particularly important when we consider glaciation. I know NASA has a lot on it, wonder if perl does.
Finally, there's nothing to apologize for with terrestrial-based coordinate systems unless you start claiming that it's the *only* way to look at matters, as we learn from Uncle Albert that the choice of an origin is beliebig...arbitrary. Just like you wouldn't use the sun as an origin to build a house, you wouldn't use heliocentrism for the task of "when does the sun set?" It has been an act of revolution to suggest that the "Gods" were one way or the other.
Happy that the world revolved today....
| [reply] [d/l] [select] |
Re: calculate length of day as function of space at onset of fall
by Linicks (Scribe) on Sep 24, 2016 at 07:58 UTC
|
| [reply] |
|
While this is correct, it won't help the OP very much, because the script in the linked article starts with $day_since_equinox, which is just where OP would like to end up :-)
| [reply] [d/l] |
|
Thanks all for responses. They have all been helpful. The above link says You can, of course, spend a lot of time and effort downloading and installing CPAN astronomical modules to calculate the time of sunrise and sunset, and reading manuals and doing a whole lot of stuff. But if you are content with approximate times, you can use some delightful shortcuts. I spent that time having every advantage. It did take north of an hour to happen on my computer, but south of two. Given fewer advantages, I would go with the approximations that would have fall simply be a day, one of 360, good enough for naked-eye, but now that I've got the tools, and I want to use them.
The response that has stuck out in this thread is the one from haukex, and I'm still writing up the results in a way that might befit my future friar status as well as the keystroke equity he put into a response that catered to my exact level of aptitude. Let's however, finish with the original script.
Given right ascension, a naive model has half of it before solar noon, and half after. Finally, we divide by 15 for dimensional analysis. The greeks really did use the sun like a watch.
With the original script, there is no surprises. It doesn't matter where you are on Earth at the onset of autumn, delta will equal zero. So for everyone except 2 simple poles, you will have 12 hour days:
C:\Users\Fred\Desktop>perl fall2.pl
cos tau = - tan phi * tan delta
onset of fall ==> delta equal zero
delta is 0
delta equals zero will zero out rhs for entire globe
phi is latitude: 45 in portland (close enough)
phi is 0.785398163397448
rhs is 0
tau is 1.5707963267949
degrees is 90
estimate is 12
agrees with theory given mathematical objects with primitive assumptio
+ns
C:\Users\Fred\Desktop>type fall2.pl
#!/usr/bin/perl -w
use strict;
use 5.010;
use Math::Trig;
use Math::Trig ':pi';
say "cos tau = - tan phi * tan delta";
say "onset of fall ==> delta equal zero";
my $delta = tan( 0);
say "delta is $delta";
say "delta equals zero will zero out rhs for entire globe";
say "phi is latitude: 45 in portland (close enough)";
my $phi = deg2rad(45);
say "phi is $phi";
my $rhs = - tan ($phi) * tan ($delta);
say "rhs is $rhs";
my $tau = acos($rhs);
say "tau is $tau";
my $degrees = rad2deg($tau);
say "degrees is $degrees";
my $estimate = 2 * $degrees/15;
say "estimate is $estimate";
say "agrees with theory given mathematical
There's *a lot* of reading, but the good news is that we stand on the shoulders of people who make compilers hum for an hour. Much of the work seemed to be the product of a D. Rolsky. I show none of his work in this, so maybe that's a teaser for downthread. Having witnessed the US presidential debate tonight, my ability to use words larger than a 12 year old might be impaired. Das wird ebenfalls passierien.
Schoenen Gruss
| [reply] [d/l] |
Re: calculate length of day as function of space at onset of fall
by CountZero (Bishop) on Sep 26, 2016 at 19:51 UTC
|
realized that fall occurs exactly when the sun sets in the west Mmmm, that's not exactly true. Autumn starts at the fall equinox, i.e. when the center of the sun (moving along the ecliptic) crosses the celestial equator (downward as seen from the Northern hemisphere). That can happen at any odd moment day or night, not necessarily the moment when the sun rises or sets. Suppose the sun crosses the equator just after midnight, then at the moment of sunset she has already travelled a little over 44 arcminutes (3/4 of a degree) along her path and the center of the sun will thus not be exactly due west when she sets. As the angular size of the sun as seen from the earth is a little bit over half a degree, the full disk of the sun "misses" due west totally.
CountZero A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James My blog: Imperial Deltronics
| [reply] |
|
That can happen at any odd moment day or night, not necessarily the moment when the sun rises or sets.
Agreed. The coincidence of the solar plane and the terrestrial plane is instantaneous, because we're supplying the coordinate system and numbers. There is a bias for when sunset is actually occuring, and I think they really are worth reading:
Let's say you add in these biases, which frankly are in the wrong direction unless you happen to be stranded on a remote island. The act of observation requires an observer and a location, so I submit that the point in space-time where autumn occurs is where a dwarf of zero height observes the sun setting in the west, which fixes the longitude in a time-zone, ready to export to others.
Tyrion is definitely my favorite Lannister anyways....
| [reply] |
Re: calculate length of day as function of space at onset of fall
by Linicks (Scribe) on Oct 29, 2016 at 12:49 UTC
|
I found some more code that calculates sunrise/sunset. After a lot of messing about, I found it is pretty accurate (it's a day out this year though, as it doesn't understand leap years). In the code below, search for 'Nick' as I have put in a few comments of how to set it up for your lat/long/timezone etc.
#!/usr/bin/perl
use POSIX;
sub sr_main
{
($rs, $rise, $set) = sunriset($year, $month, $day, $lon, $lat);
return $rs, $rise, $set;
}
sub sunriset
{
# GLOBAL variable definitions
local($pi) = 3.1415926535897932384;
local($radeg) = 180.0 / $pi;
local($degrad) = $pi / 180.0;
local($inv360) = 1.0 / 360.0;
# Passed variables
local($year) = $_[0]; local($month) = $_[1];
local($day) = $_[2]; local($lon) = $_[3];
local($lat) = $_[4]; local($altit) = -35/60;
local($upper_limb) = 1;
# Return Values:
local($rc) = 0;
local($trise) = $_[7];
local($tset) = $_[8];
local($d); # Days since 2000 Jan 0.0
local($sr); # Solar distance
local($sra); # Sun's right ascension
local($sdec); # Sun's declination
local($sradius);# Sun's apparent radius
local($t); # diurnam arc;
local($tsouth); # time when Sun is at south
local($sidtime);# local sidereal time
$d = days_since_2000_Jan_0($year, $month, $day) + 0.5 - $lon/3
+60.0;
$sidtime = revolution(GMST0($d) + 180.0 + $lon);
($sra, $sdec, $sr) = sun_RA_dec($d, $sr);
$tsouth = 12.0 - rev180($sidtime - $sra) / 15.0;
$sradius = 0.2666 / $sr;
if($upper_limb)
{ $altit -= $sradius; }
$cost = (sind($altit) - sind($lat) * sind($sdec)) / (cosd($lat
+) * cosd($sdec));
if($cost >= 1.0)
{ $rc = -1, $t = 0.0; }
elsif($cost <= -1.0)
{ $rc = +1; $t = 12.0; }
else { $t = acosd($cost) / 15.0; }
$trise = $tsouth - $t;
$tset = $tsouth + $t;
return $rc, $trise, $tset;
}
sub sunpos
{
## Input variables
local($d) = $_[0];
## Return variables
local($lon);
local($r);
## Local declerations
local($M, $w, $e, $E, $x, $y, $v);
$M = revolution(356.0470 + 0.9856002585 * $d);
$w = 282.9404 + 4.70935E-5 * $d;
$e = 0.016709 - 1.151E-9 * $d;
$E = $M + $e * $radeg * sind($M) * (1.0 + $e * cosd($M));
$x = cosd($E) - $e;
$y = sqrt(1.0 - $e * $e) * sind($E);
$r = sqrt($x * $x + $y * $y);
$v = atan2d($y, $x);
$lon = $v + $w;
if( $lon >= 360.0 ) { $lon -= 360.0; }
return $lon, $r;
}
sub sun_RA_dec
{
## Input variables
local($d) = $_[0];
## Return Variables
local($RA, $dec);
local($r) = $_[1];
## Local reserved variables
local($lon, $obl_ecl, $x, $y, $z);
($lon, $r) = sunpos($d);
$x = $r * cosd($lon);
$y = $r * sind($lon);
$obl_ecl = 23.4393 - 3.563E-7 * $d;
$z = $y * sind($obl_ecl);
$y = $y * cosd($obl_ecl);
$RA = atan2d($y, $x);
$dec = atan2d($z, sqrt($x * $x + $y * $y));
return $RA, $dec, $r;
}
sub revolution
{ return ($_[0] - 360.0 * floor($_[0] * $inv360)); }
sub rev180
{ return ($_[0] - 360.0 * floor($_[0] * $inv360 + 0.5)); }
sub GMST0
{
return revolution((180.0 + 356.0470 + 282.9404) +
(0.9856002585 + 4.70935E-5) * $_[0]);
}
sub days_since_2000_Jan_0
{
my($y) = $_[0]; my($m) = $_[1]; my($d) = $_[2];
return (367 * ($y) - ((7 * (($y) + ((($m) + 9) / 12))) /4) +
((275 * ($m)) / 9) + ($d) - 730530);
}
sub sind { return sin($_[0] * $degrad); }
sub cosd { return cos($_[0] * $degrad); }
sub tand { return tan($_[0] * $degrad); }
sub atand { return ($radeg * atan($_[0])); }
sub asind { return ($radeg * asin($_[0])); }
sub acosd { return ($radeg * acos($_[0])); }
sub atan2d { return ($radeg * atan2($_[0], $_[1])); }
#1;
#($rs,$sunrise,$sunset)=sunriset($year, $month, $day, $latitude, $logi
+tude);
#print "Sunrise: ".$sunrise."n";
$year=2016;
$month=1;
#$day=11;
# Nick - 29/10/2016
# Put your lat and long here:
$lat="+50.8198";
$lon="-1.0880";
# From the origianl code
#$lat="+43.6667";
#$lon="-79.4";
# End Nick
$counter=1;
while ($counter < 366)
{
$day=$counter;
($rs, $rise, $set)=sr_main;
#print $rs;
#print $rise;
$prettycounter=0;
$lines=(24-($set-$rise));
for ($lines; $lines >= 0; $lines--) {
print "-";
$prettycounter++;
}
$stars=($set-$rise)*2;
for ($stars; $stars >= 0; $stars--) {
print "*";
$prettycounter++;
}
$lines=(24-($set-$rise));
for ($lines; $lines >= 0; $lines--) {
print "-";
$prettycounter++;
}
if ($prettycounter<50) { print "-"; };
# Nick - 29/10/2016
# daylight savings (i.e. +3, -2 etc.)
my $dls = +1;
# Nick - 29/10/2016 - round down the time to minutes, not decimals
my $riseh = $rise;
my $risef = $rise;
$riseh =~ s/\..*//;
$risef =~ s/.*\././;
my $risem = (60*$risef);
$risem =~ s/\..*//;
if ($risem < 10) {
$risem = "0".$risem;
}
my $seth = $set;
my $setf = $set;
$seth =~ s/\..*//;
$setf =~ s/.*\././;
my $setm = (60*$setf);
$setm =~ s/\..*//;
if ($setm < 10) {
$setm = "0".$setm;
}
#print "Day: $counter , sunrise: ".($rise-4)." , sunset: ".($set-4)."
+ ";
print "Day: $counter , sunrise: ".($riseh+$dls).":".$risem." , sunset:
+ ".($seth+$dls).":".$setm;
# End Nick
print "\n";
$counter++;
}
Nick | [reply] [d/l] |
|
|