@@ -1,55 +1,86 @@
-Revision history for Perl extension sunrise.
-
-0.01 Fri Dec 10 08:13:24 1999
- - original version; created by h2xs 1.18
-0.02 Tues Jun 20 08:30:00 2000
- - Added code to convert to local time. R.Hill
-
-0.03 Thurs Feb 15 08:30:00 2001
- - Added copyright information
- - fixed bug for converting to local time
- - updated documentation R.Hill
-
-0.04 Sun Mar 11 13:51:22 2001
- - I've moved the POD around and added a function documentation block for
- the sunrise() function. And I moved all the variables out of the use
- vars block at the top, making them my variables, wherever possible.
- I added a small test suite that leaves a lot of room for future expansion.
-
- Finally, I moved all of those tiny subs out of the sunrise() function
- into their own space. They are not really private subs, and they are
- referencing values as global variables anyway. Oh, yeah, and I generated
- the README with pod2text so that the README on CPAN will be a little
- more informative. R.Bowen
-0.05 Wed Oct 17 7:00:00 2001
- - Fixed bug for converting to local time for points east of GMT
- Thanks to Adrian Blockley [adrian.blockley@environ.wa.gov.au]
-0.6 Wed Feb 5 2003
- Performed a complete rewrite of the module to conform with
- Paul's C code. Fixed a nasty bug the computing the number of days elapsed
- since 2000 Jan 0.0.
- Added warnings for no sunrise/sunset
- Added Rob's enhancements using the time object modules
- Added new subs sun_rise,sun_set per Rob's recomendation
- Added Rob's enhancements for selecting different Alt's
-0.7 Fri Feb 14 2003
- Fixed a bug in dependency, Added Iteration function, Added
- documentation for subs
-0.8 Changed the dependency from Time::Object to Time::Piece
- (shame on me)
-0.85 Wed Aug 14 2003
- Fixed bug in local time conversion (the same bug for 0.05)
- Changed dependency from Time::Piece to DateTime (Per Joshua Hoblitt)
- Updated Documentation to reflect DateTime dependency
-0.90 Updated the convert_hour sub, This was badly broken Patch from
- Chris Phillps applied. Added Constants for Altitude provided by
- Brian dfoy.
-0.91 Major update to the test script 001basic.t I have added many tests
- for cities around the world. Changed the convert_hour sub to format
- the hour (add a zero).
-0.92 Monday 8 July 2013
- New co-maint JFORGET
- Fix tickets 47049 and 83394: wrong calculations on 19/20/21 March
- Fix ticket 9377: documentation improvement
- Minor formatting changes and spelling fixes
-
+-*- encoding: utf-8; indent-tabs-mode: nil -*-
+
+Revision history for Perl extension sunrise.
+
+0.95 Tuesday 21 April 2015
+ - Some improvements in the POD documentation.
+ - New time_zone parameter to sun_rise and sun_set.
+ - New tests for fork-less systems
+ - New tests to check for parameter checking
+
+0.94 Tuesday 10 March 2015
+ - Fix typos in the POD documentation
+ - Fix problem in the t/03dst.t test file.
+
+0.93 Tuesday 3 March 2015
+ - Stylistic and kwalitee issues: license, distro structure, etc.
+ - Fix ticket 62593 (patch from Slaven Rezic)
+ - Parameters to sunrise can be passed by name (using a hashref)
+ - The upper_limb is not longer hard-coded, it is now a parameter
+ - The behaviour for polar day and polar night can change: no warning,
+ but a special return value.
+ - Make degree-trigonometric functions available for import.
+
+0.92 Monday 8 July 2013
+ New co-maint JFORGET
+ Fix tickets 47049 and 83394: wrong calculations on 19/20/21 March
+ Fix ticket 9377: documentation improvement
+ Minor formatting changes and spelling fixes
+
+0.91 Major update to the test script 001basic.t I have added many tests
+ for cities around the world. Changed the convert_hour sub to format
+ the hour (add a zero).
+
+0.90 Updated the convert_hour sub, This was badly broken Patch from
+ Chris Phillps applied. Added Constants for Altitude provided by
+ Brian dfoy.
+
+0.85 Wed Aug 14 2003
+ Fixed bug in local time conversion (the same bug for 0.05)
+ Changed dependency from Time::Piece to DateTime (Per Joshua Hoblitt)
+ Updated Documentation to reflect DateTime dependency
+
+0.8 Changed the dependency from Time::Object to Time::Piece
+ (shame on me)
+
+0.7 Fri Feb 14 2003
+ Fixed a bug in dependency, Added Iteration function, Added
+ documentation for subs
+
+0.6 Wed Feb 5 2003
+ Performed a complete rewrite of the module to conform with
+ Paul's C code. Fixed a nasty bug the computing the number of days elapsed
+ since 2000 Jan 0.0.
+ Added warnings for no sunrise/sunset
+ Added Rob's enhancements using the time object modules
+ Added new subs sun_rise,sun_set per Rob's recomendation
+ Added Rob's enhancements for selecting different Alt's
+
+0.05 Wed Oct 17 7:00:00 2001
+ - Fixed bug for converting to local time for points east of GMT
+ Thanks to Adrian Blockley [adrian.blockley@environ.wa.gov.au]
+
+0.04 Sun Mar 11 13:51:22 2001
+ - I've moved the POD around and added a function documentation block for
+ the sunrise() function. And I moved all the variables out of the use
+ vars block at the top, making them my variables, wherever possible.
+ I added a small test suite that leaves a lot of room for future expansion.
+
+ Finally, I moved all of those tiny subs out of the sunrise() function
+ into their own space. They are not really private subs, and they are
+ referencing values as global variables anyway. Oh, yeah, and I generated
+ the README with pod2text so that the README on CPAN will be a little
+ more informative. R.Bowen
+
+0.03 Thurs Feb 15 08:30:00 2001
+ - Added copyright information
+ - fixed bug for converting to local time
+ - updated documentation R.Hill
+
+0.02 Tues Jun 20 08:30:00 2000
+ - Added code to convert to local time. R.Hill
+
+
+0.01 Fri Dec 10 08:13:24 1999
+ - original version; created by h2xs 1.18
+
@@ -0,0 +1,391 @@
+-*- encoding: utf-8; indent-tabs-mode: nil -*-
+
+Terms of Perl itself
+
+a) the GNU General Public License as published by the Free
+ Software Foundation; either version 1, or (at your option) any
+ later version, or
+b) the "Artistic License"
+
+---------------------------------------------------------------------------
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 1, February 1989
+
+ Copyright (C) 1989 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The license agreements of most software companies try to keep users
+ at the mercy of those companies. By contrast, our General Public
+ License is intended to guarantee your freedom to share and change free
+ software--to make sure the software is free for all its users. The
+ General Public License applies to the Free Software Foundation's
+ software and to any other program whose authors commit to using it.
+ You can use it for your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+ price. Specifically, the General Public License is designed to make
+ sure that you have the freedom to give away or sell copies of free
+ software, that you receive source code or can get it if you want it,
+ that you can change the software or use pieces of it in new free
+ programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if you
+ distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of a such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have. You must make sure that they, too, receive or can get the
+ source code. And you must tell them their rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+ (2) offer you this license which gives you legal permission to copy,
+ distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on, we
+ want its recipients to know that what they have is not the original, so
+ that any problems introduced by others will not reflect on the original
+ authors' reputations.
+
+ The precise terms and conditions for copying, distribution and
+ modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any program or other work which
+ contains a notice placed by the copyright holder saying it may be
+ distributed under the terms of this General Public License. The
+ "Program", below, refers to any such program or work, and a "work based
+ on the Program" means either the Program or any work containing the
+ Program or a portion of it, either verbatim or with modifications. Each
+ licensee is addressed as "you".
+
+ 1. You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously and
+ appropriately publish on each copy an appropriate copyright notice and
+ disclaimer of warranty; keep intact all the notices that refer to this
+ General Public License and to the absence of any warranty; and give any
+ other recipients of the Program a copy of this General Public License
+ along with the Program. You may charge a fee for the physical act of
+ transferring a copy.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+ it, and copy and distribute such modifications under the terms of Paragraph
+ 1 above, provided that you also do the following:
+
+ a) cause the modified files to carry prominent notices stating that
+ you changed the files and the date of any change; and
+
+ b) cause the whole of any work that you distribute or publish, that
+ in whole or in part contains the Program or any part thereof, either
+ with or without modifications, to be licensed at no charge to all
+ third parties under the terms of this General Public License (except
+ that you may choose to grant warranty protection to some or all
+ third parties, at your option).
+
+ c) If the modified program normally reads commands interactively when
+ run, you must cause it, when started running for such interactive use
+ in the simplest and most usual way, to print or display an
+ announcement including an appropriate copyright notice and a notice
+ that there is no warranty (or else, saying that you provide a
+ warranty) and that users may redistribute the program under these
+ conditions, and telling the user how to view a copy of this General
+ Public License.
+
+ d) You may charge a fee for the physical act of transferring a
+ copy, and you may at your option offer warranty protection in
+ exchange for a fee.
+
+ Mere aggregation of another independent work with the Program (or its
+ derivative) on a volume of a storage or distribution medium does not bring
+ the other work under the scope of these terms.
+
+ 3. You may copy and distribute the Program (or a portion or derivative of
+ it, under Paragraph 2) in object code or executable form under the terms of
+ Paragraphs 1 and 2 above provided that you also do one of the following:
+
+ a) accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ b) accompany it with a written offer, valid for at least three
+ years, to give any third party free (except for a nominal charge
+ for the cost of distribution) a complete machine-readable copy of the
+ corresponding source code, to be distributed under the terms of
+ Paragraphs 1 and 2 above; or,
+
+ c) accompany it with the information you received as to where the
+ corresponding source code may be obtained. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form alone.)
+
+ Source code for a work means the preferred form of the work for making
+ modifications to it. For an executable file, complete source code means
+ all the source code for all modules it contains; but, as a special
+ exception, it need not include source code for modules which are standard
+ libraries that accompany the operating system on which the executable
+ file runs, or for standard header files or definitions files that
+ accompany that operating system.
+
+ 4. You may not copy, modify, sublicense, distribute or transfer the
+ Program except as expressly provided under this General Public License.
+ Any attempt otherwise to copy, modify, sublicense, distribute or transfer
+ the Program is void, and will automatically terminate your rights to use
+ the Program under this License. However, parties who have received
+ copies, or rights to use copies, from you under this General Public
+ License will not have their licenses terminated so long as such parties
+ remain in full compliance.
+
+ 5. By copying, distributing or modifying the Program (or any work based
+ on the Program) you indicate your acceptance of this license to do so,
+ and all its terms and conditions.
+
+ 6. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the original
+ licensor to copy, distribute or modify the Program subject to these
+ terms and conditions. You may not impose any further restrictions on the
+ recipients' exercise of the rights granted herein.
+
+ 7. The Free Software Foundation may publish revised and/or new versions
+ of the General Public License from time to time. Such new versions will
+ be similar in spirit to the present version, but may differ in detail to
+ address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Program
+ specifies a version number of the license which applies to it and "any
+ later version", you have the option of following the terms and conditions
+ either of that version or of any later version published by the Free
+ Software Foundation. If the Program does not specify a version number of
+ the license, you may choose any version ever published by the Free Software
+ Foundation.
+
+ 8. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the author
+ to ask for permission. For software which is copyrighted by the Free
+ Software Foundation, write to the Free Software Foundation; we sometimes
+ make exceptions for this. Our decision will be guided by the two goals
+ of preserving the free status of all derivatives of our free software and
+ of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+ REPAIR OR CORRECTION.
+
+ 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+ possible use to humanity, the best way to achieve this is to make it
+ free software which everyone can redistribute and change under these
+ terms.
+
+ To do so, attach the following notices to the program. It is safest to
+ attach them to the start of each source file to most effectively convey
+ the exclusion of warranty; and each file should have at least the
+ "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+
+ Also add information on how to contact you by electronic and paper mail.
+
+ If the program is interactive, make it output a short notice like this
+ when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19xx name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+ The hypothetical commands `show w' and `show c' should show the
+ appropriate parts of the General Public License. Of course, the
+ commands you use may be called something other than `show w' and `show
+ c'; they could even be mouse-clicks or menu items--whatever suits your
+ program.
+
+ You should also get your employer (if you work as a programmer) or your
+ school, if any, to sign a "copyright disclaimer" for the program, if
+ necessary. Here a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ program `Gnomovision' (a program to direct compilers to make passes
+ at assemblers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+ That's all there is to it!
+
+
+---------------------------------------------------------------------------
+
+
+ The "Artistic License"
+
+ Preamble
+
+The intent of this document is to state the conditions under which a
+Package may be copied, such that the Copyright Holder maintains some
+semblance of artistic control over the development of the package,
+while giving the users of the package the right to use and distribute
+the Package in a more-or-less customary fashion, plus the right to make
+reasonable modifications.
+
+Definitions:
+
+ "Package" refers to the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection of files
+ created through textual modification.
+
+ "Standard Version" refers to such a Package if it has not been
+ modified, or has been modified in accordance with the wishes
+ of the Copyright Holder as specified below.
+
+ "Copyright Holder" is whoever is named in the copyright or
+ copyrights for the package.
+
+ "You" is you, if you're thinking about copying or distributing
+ this Package.
+
+ "Reasonable copying fee" is whatever you can justify on the
+ basis of media cost, duplication charges, time of people involved,
+ and so on. (You will not be required to justify it to the
+ Copyright Holder, but only to the computing community at large
+ as a market that must bear the fee.)
+
+ "Freely Available" means that no fee is charged for the item
+ itself, though there may be fees involved in handling the item.
+ It also means that recipients of the item may redistribute it
+ under the same conditions they received it.
+
+1. You may make and give away verbatim copies of the source form of the
+Standard Version of this Package without restriction, provided that you
+duplicate all of the original copyright notices and associated disclaimers.
+
+2. You may apply bug fixes, portability fixes and other modifications
+derived from the Public Domain or from the Copyright Holder. A Package
+modified in such a way shall still be considered the Standard Version.
+
+3. You may otherwise modify your copy of this Package in any way, provided
+that you insert a prominent notice in each changed file stating how and
+when you changed that file, and provided that you do at least ONE of the
+following:
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or
+ an equivalent medium, or placing the modifications on a major archive
+ site such as uunet.uu.net, or by allowing the Copyright Holder to include
+ your modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict
+ with standard executables, which must also be provided, and provide
+ a separate manual page for each non-standard executable that clearly
+ documents how it differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+4. You may distribute the programs of this Package in object code or
+executable form, provided that you do at least ONE of the following:
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where
+ to get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of
+ the Package with your modifications.
+
+ c) give non-standard executables non-standard names, and clearly
+ document the differences in manual pages (or equivalent), together
+ with instructions on where to get the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+5. You may charge a reasonable copying fee for any distribution of this
+Package. You may charge any fee you choose for support of this
+Package. You may not charge a fee for this Package itself. However,
+you may distribute this Package in aggregate with other (possibly
+commercial) programs as part of a larger (possibly commercial) software
+distribution provided that you do not advertise this Package as a
+product of your own. You may embed this Package's interpreter within
+an executable of yours (by linking); this shall be construed as a mere
+form of aggregation, provided that the complete Standard Version of the
+interpreter is so embedded.
+
+6. The scripts and library files supplied as input to or produced as
+output from the programs of this Package do not automatically fall
+under the copyright of this Package, but belong to whoever generated
+them, and may be sold commercially, and may be aggregated with this
+Package. If such scripts or library files are aggregated with this
+Package via the so-called "undump" or "unexec" methods of producing a
+binary executable image, then distribution of such an image shall
+neither be construed as a distribution of this Package nor shall it
+fall under the restrictions of Paragraphs 3 and 4, provided that you do
+not represent such an executable image as a Standard Version of this
+Package.
+
+7. C subroutines (or comparably compiled subroutines in other
+languages) supplied by you and linked into this Package in order to
+emulate subroutines and variables of the language defined by this
+Package shall not be considered part of this Package, but are the
+equivalent of input as in Paragraph 6, provided these subroutines do
+not change the language in any way that would cause it to fail the
+regression tests for the language.
+
+8. Aggregation of this Package with a commercial distribution is always
+permitted provided that the use of this Package is embedded; that is,
+when no overt attempt is made to make this Package's interfaces visible
+to the end user of the commercial distribution. Such use shall not be
+construed as a distribution of this Package.
+
+9. The name of the Copyright Holder may not be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ The End
@@ -1,9 +1,21 @@
-Changes
-MANIFEST
-Makefile.PL
-README
-Sunrise.pm
-t/00load.t
-t/01basic.t
-t/02constants.t
-META.yml Module meta-data (added by MakeMaker)
+Changes
+LICENSE
+MANIFEST
+Makefile.PL
+README
+TODO
+lib/Astro/Sunrise.pm
+t/00load.t
+t/01basic.t
+t/02constants.t
+t/03dst.t
+t/04basic.t
+t/05polar.t
+t/06datetime.t
+t/07trig.t
+t/08timezone.t
+t/09springforward.t
+t/10fallback.t
+t/11fatal.t
+META.yml Module YAML meta-data (added by MakeMaker)
+META.json Module JSON meta-data (added by MakeMaker)
@@ -0,0 +1,45 @@
+{
+ "abstract" : "Perl extension for computing the sunrise/sunset on a given day",
+ "author" : [
+ "Ron Hill <rkhill@firstlight.net>",
+ "Jean Forget <JFORGET@cpan.org>"
+ ],
+ "dynamic_config" : 1,
+ "generated_by" : "ExtUtils::MakeMaker version 6.6302, CPAN::Meta::Converter version 2.120630",
+ "license" : [
+ "perl_5"
+ ],
+ "meta-spec" : {
+ "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+ "version" : "2"
+ },
+ "name" : "Astro-Sunrise",
+ "no_index" : {
+ "directory" : [
+ "t",
+ "inc"
+ ]
+ },
+ "prereqs" : {
+ "runtime" : {
+ "recommends" : {
+ "DateTime" : "0.16"
+ }
+ }
+ },
+ "provides" : {
+ "Astro::Sunrise" : {
+ "file" : "lib/Astro/Sunrise.pm",
+ "version" : "0.95"
+ }
+ },
+ "release_status" : "stable",
+ "resources" : {
+ "repository" : {
+ "type" : "git",
+ "url" : "https://github.com/jforget/Astro-Sunrise.git",
+ "web" : "https://github.com/jforget/Astro-Sunrise"
+ }
+ },
+ "version" : "0.95"
+}
@@ -1,21 +1,26 @@
---- #YAML:1.0
-name: Astro-Sunrise
-version: 0.92
-abstract: ~
-author: []
-license: unknown
-distribution_type: module
-configure_requires:
- ExtUtils::MakeMaker: 0
-build_requires:
- ExtUtils::MakeMaker: 0
-requires:
- DateTime: 0.16
-no_index:
- directory:
- - t
- - inc
-generated_by: ExtUtils::MakeMaker version 6.57_05
+---
+abstract: 'Perl extension for computing the sunrise/sunset on a given day'
+author:
+ - 'Ron Hill <rkhill@firstlight.net>'
+ - 'Jean Forget <JFORGET@cpan.org>'
+build_requires: {}
+dynamic_config: 1
+generated_by: 'ExtUtils::MakeMaker version 6.6302, CPAN::Meta::Converter version 2.120630'
+license: perl
meta-spec:
- url: http://module-build.sourceforge.net/META-spec-v1.4.html
- version: 1.4
+ url: http://module-build.sourceforge.net/META-spec-v1.4.html
+ version: 1.4
+name: Astro-Sunrise
+no_index:
+ directory:
+ - t
+ - inc
+provides:
+ Astro::Sunrise:
+ file: lib/Astro/Sunrise.pm
+ version: 0.95
+recommends:
+ DateTime: 0.16
+resources:
+ repository: https://github.com/jforget/Astro-Sunrise.git
+version: 0.95
@@ -1,8 +1,68 @@
-use ExtUtils::MakeMaker;
-# See lib/ExtUtils/MakeMaker.pm for details of how to influence
-# the contents of the Makefile that is written.
-WriteMakefile(
- 'NAME' => 'Astro::Sunrise',
- 'VERSION_FROM' => 'Sunrise.pm', # finds $VERSION
- 'PREREQ_PM' =>{ 'DateTime' => 0.16, },
-);
+#
+# Configuration script for Astro::Sunrise
+# Copyright (C) 2001, 2002, 2003, 2013, 2015 Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+WriteMakefile(
+ NAME => 'Astro::Sunrise',
+ VERSION_FROM => 'lib/Astro/Sunrise.pm', # finds $VERSION
+ ABSTRACT => 'Perl extension for computing the sunrise/sunset on a given day',
+ PREREQ_PM => { # DateTime => '0.16',
+ POSIX => 0,
+ 'Math::Trig' => 0, },
+ AUTHOR => [ 'Ron Hill <rkhill@firstlight.net>', 'Jean Forget <JFORGET@cpan.org>' ],
+ LICENSE => 'perl',
+ # The oldest Perl to check Astro::Sunrise 0.92 is 5.6.2. Therefore, I guess Astro::Sunrise 0.93 and next will work in 5.6.2 too.
+ MIN_PERL_VERSION => '5.6.2',
+ BUILD_REQUIRES => { 'Test::More' => '0', # should be 'TEST_REQUIRES', except that ExtUtils::MakeMaker 6.5705 does not accept it
+ 'ExtUtils::MakeMaker' => '6.57_02', # the first version to accept several authors in an arrayref
+ },
+ META_MERGE => {
+ prereqs => {
+ runtime => {
+ recommends => {
+ DateTime => '0.16',
+ },
+ },
+ },
+ provides => {
+ 'Astro::Sunrise' => {
+ file => 'lib/Astro/Sunrise.pm',
+ version => '0.95',
+ },
+ },
+ 'meta-spec' => { version => 2 },
+ resources => {
+ repository => {
+ type => 'git',
+ url => 'https://github.com/jforget/Astro-Sunrise.git',
+ web => 'https://github.com/jforget/Astro-Sunrise',
+ },
+ },
+ },
+);
@@ -1,204 +1,66 @@
-NAME
- Astro::Sunrise - Perl extension for computing the sunrise/sunset on a
- given day
-
-SYNOPSIS
- use Astro::Sunrise;
-
- ($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST);
- ($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST,ALT);
- ($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST,ALT,inter);
-
- $sunrise = sun_rise(longitude,latitude);
- $sunset = sun_set(longitude,latitude);
-
- $sunrise = sun_rise(longitude,latitude,ALT);
- $sunset = sun_set(longitude,latitude,ALT);
-
- $sunrise = sun_rise(longitude,latitude,ALT,day_offset);
- $sunset = sun_set(longitude,latitude,ALT,day_offset);
-
-DESCRIPTION
- This module will return the sunrise/sunset for a given day.
-
- Eastern longitude is entered as a positive number
- Western longitude is entered as a negative number
- Northern latitude is entered as a positive number
- Southern latitude is entered as a negative number
-
- inter is set to either 0 or 1. If set to 0 no Iteration will occur. If
- set to 1 Iteration will occur. Default is 0.
-
- There are a number of sun altitudes to chose from. The default is -0.833
- because this is what most countries use. Feel free to specify it if you
- need to. Here is the list of values to specify altitude (ALT) with:
-
- 0 degrees
- Center of Sun's disk touches a mathematical horizon
-
- -0.25 degrees
- Sun's upper limb touches a mathematical horizon
-
- -0.583 degrees
- Center of Sun's disk touches the horizon; atmospheric refraction
- accounted for
-
- -0.833 degrees
- Sun's supper limb touches the horizon; atmospheric refraction
- accounted for
-
- -6 degrees
- Civil twilight (one can no longer read outside without artificial
- illumination)
-
- -12 degrees
- Nautical twilight (navigation using a sea horizon no longer
- possible)
-
- -15 degrees
- Amateur astronomical twilight (the sky is dark enough for most
- astronomical observations)
-
- -18 degrees
- Astronomical twilight (the sky is completely dark)
-
-USAGE
- sunrise
- "($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time
- Zone,DST);"
- "($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time
- Zone,DST,ALT);"
- Returns the sunrise and sunset times, in HH:MM format. (Note:
- Time Zone is the offset from GMT and DST is daylight savings
- time, 1 means DST is in effect and 0 is not). In the first form,
- a default altitude of -.0833 is used. In the second form, the
- altitude is specified as the last argument. Note that adding 1
- to the Time Zone during DST and specifying DST as 0 is the same
- as indicating the Time Zone correctly and specifying DST as 1.
-
- Notes on Iteration
- ($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time
- Zone,DST,ALT,inter);
- The original method only gives an approximate value of the
- Sun's rise/set times. The error rarely exceeds one or two
- minutes, but at high latitudes, when the Midnight Sun soon
- will start or just has ended, the errors may be much larger.
- If you want higher accuracy, you must then use the iteration
- feature. This feature is new as of version 0.7. Here is what
- I have tried to accomplish with this.
-
- a) Compute sunrise or sunset as always, with one exception:
- to convert LHA from degrees to hours, divide by 15.04107
- instead of 15.0 (this accounts for the difference between
- the solar day and the sidereal day.
-
- b) Re-do the computation but compute the Sun's RA and Decl,
- and also GMST0, for the moment of sunrise or sunset last
- computed.
-
- c) Iterate b) until the computed sunrise or sunset no longer
- changes significantly. Usually 2 iterations are enough, in
- rare cases 3 or 4 iterations may be needed.
-
- *For Example*
- ($sunrise, $sunset) = sunrise( 2001, 3, 10, 17.384, 98.625, -5, 0 );
- ($sunrise, $sunset) = sunrise( 2002, 10, 14, -105.181, 41.324, -7, 1, -18);
- ($sunrise, $sunset) = sunrise( 2002, 10, 14, -105.181, 41.324, -7, 1, -18, 1);
- =back
-
- sun_rise
- "$sun_rise = sun_rise( longitude, latitude );"
- "$sun_rise = sun_rise( longitude, latitude, ALT );"
- "$sun_rise = sun_rise( longitude, latitude, ALT, day_offset
- );"
- Returns the sun rise time for the given location. The
- first form uses today's date (from Time::Object) and the
- default altitude. The second form adds specifying a
- custom altitude. The third form allows for specifying an
- integer day offset from today, either positive or
- negative.
-
- *For Example*
- $sunrise = sun_rise( -105.181, 41.324 );
- $sunrise = sun_rise( -105.181, 41.324, -15 );
- $sunrise = sun_rise( -105.181, 41.324, -12, +3 );
- $sunrise = sun_rise( -105.181, 41.324, undef, -12);
-
- sun_set
- "$sun_set = sun_set( longitude, latitude );"
- "$sun_set = sun_set( longitude, latitude, ALT );"
- "$sun_set = sun_set( longitude, latitude, ALT, day_offset
- );"
- Returns the sun set time for the given location. The
- first form uses today's date (from Time::Object) and the
- default altitude. The second form adds specifying a
- custom altitude. The third form allows for specifying an
- integer day offset from today, either positive or
- negative.
-
- *For Example*
- $sunrise = sun_set( -105.181, 41.324 );
- $sunrise = sun_set( -105.181, 41.324, -15 );
- $sunrise = sun_set( -105.181, 41.324, -12, +3 );
- $sunrise = sun_set( -105.181, 41.324, undef, -12);
-
-AUTHOR
- Ron Hill rkhill@firstlight.net
-
-SPECIAL THANKS
- Robert Creager [Astro-Sunrise@LogicalChaos.org] For providing
- help with converting Paul's C code to perl For providing code
- for sun_rise, sun_set sub's Also adding options for different
- altitudes.
-
- Joshua Hoblitt [jhoblitt@ifa.hawaii.edu]
- For providing the patch to convert to DateTime
-
-
-CREDITS
- Paul Schlyter, Stockholm, Sweden
- for his excellent web page on the subject.
-
- Rich Bowen (rbowen@rbowen.com)
- for suggestions
-
- Adrian Blockley [adrian.blockley@environ.wa.gov.au]
- for finding a bug in the conversion to local time
-
- Lightly verified against
- http://aa.usno.navy.mil/data/docs/RS_OneYear.html
-
-COPYRIGHT and LICENSE
- Here is the copyright information provided by Paul Schlyter:
-
- Written as DAYLEN.C, 1989-08-16
-
- Modified to SUNRISET.C, 1992-12-01
-
- (c) Paul Schlyter, 1989, 1992
-
- Released to the public domain by Paul Schlyter, December 1992
-
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-BUGS
-SEE ALSO
- perl(1).
-
+-*- encoding: utf-8; indent-tabs-mode: nil -*-
+
+Astro::Sunrise version 0.95
+===========================
+
+This module commpute the sunrise and sunset for a given day.
+
+The simplest way to install the module is by using your favorite
+utility: CPAN shell, cpanplus, cpanminus, dist-zilla, etc.
+
+To install this module from a cloned git repository or from a tarball
+type the following:
+
+ perl Makefile.PL
+ make
+ make test
+ make install
+
+
+DEPENDENCIES
+
+This module requires these other modules and libraries:
+ Math::Trig
+ POSIX
+
+The following module is recommended:
+ DateTime.pm
+
+COPYRIGHT AND LICENCE
+
+Copyright (C) 2000, 2001, 2002, 2003, 2013, 2015 Ron Hill and Jean Forget
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl 5.16.3. For more details, see the full
+text of the licenses in the LICENSE file.
+
+This program is distributed in the hope that it will be useful, but it
+is provided “as is” and without any express or implied warranties. For
+details, see the full text of the licenses in the file LICENSE.
+
+Based on a public domain C program sunriset.c (c) Paul Schlyter, 1989, 1992
+NAME
+
+ Astro::Sunrise - Perl extension for computing the sunrise/sunset on a given day
+
+SYNOPSIS
+
+ # When will the sun rise on YAPC::Europe 2015?
+ use Astro::Sunrise;
+ my ($sunrise, $sunset) = sunrise( { year => 2015, month => 9, day => 2, # YAPC::EU starts on 2nd September 2015
+ lon => -3.6, lat => 37.17, # Granada is 37°10'N, 3°36'W
+ tz => 1, dst => 1 } ); # This is still summer, therefore DST
+
+ # When does the sun rise today in Salt Lake City (home to YAPC::NA 2015)?
+ use Astro::Sunrise;
+ use DateTime;
+ $sunrise_today = sun_rise( { lon => -111.88, lat => 40.75 } ); # 40°45'N, 111°53'W
+
+ # And when does it set tomorrow at Salt Lake City?
+ use Astro::Sunrise;
+ use DateTime;
+ $sunset_tomorrow = sun_set( { lat => 40.75, # 40°45'N,
+ lon => -111.88, # 111°53'W
+ alt => -0.833, # standard value for the sun altitude at sunset
+ offset => 1 } ); # day offset up to tomorrow
+
@@ -1,784 +0,0 @@
-package Astro::Sunrise;
-
-=head1 NAME
-
-Astro::Sunrise - Perl extension for computing the sunrise/sunset on a given day
-
-=head1 SYNOPSIS
-
- use Astro::Sunrise;
-#use Astro::Sunrise qw(:constants);
-
- ($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST);
- ($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST,ALT);
- ($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST,ALT,inter);
-
- $sunrise = sun_rise(longitude,latitude);
- $sunset = sun_set(longitude,latitude);
-
- $sunrise = sun_rise(longitude,latitude,ALT);
- $sunset = sun_set(longitude,latitude,ALT);
-
- $sunrise = sun_rise(longitude,latitude,ALT,day_offset);
- $sunset = sun_set(longitude,latitude,ALT,day_offset);
-
-=head1 DESCRIPTION
-
-This module will return the sunrise/sunset for a given day.
-
-Months are numbered 1 to 12, in the usual way, not 0 to 11 as in
-C and in Perl's localtime.
-
- Eastern longitude is entered as a positive number
- Western longitude is entered as a negative number
- Northern latitude is entered as a positive number
- Southern latitude is entered as a negative number
-
-Please note that the longitude is specified before the latitude.
-
-The time zone is given as the numeric value of the offset from UTC.
-
-inter is set to either 0 or 1.
-If set to 0 no Iteration will occur.
-If set to 1 Iteration will occur.
-Default is 0.
-
-There are a number of sun altitudes to chose from. The default is
--0.833 because this is what most countries use. Feel free to
-specify it if you need to. Here is the list of values to specify
-altitude (ALT) with, including symbolic constants for each.
-
-=over
-
-=item B<0> degrees
-
-Center of Sun's disk touches a mathematical horizon
-
-=item B<-0.25> degrees
-
-Sun's upper limb touches a mathematical horizon
-
-=item B<-0.583> degrees
-
-Center of Sun's disk touches the horizon; atmospheric refraction accounted for
-
-=item B<-0.833> degrees, DEFAULT
-
-Sun's upper limb touches the horizon; atmospheric refraction accounted for
-
-=item B<-6> degrees, CIVIL
-
-Civil twilight (one can no longer read outside without artificial illumination)
-
-=item B<-12> degrees, NAUTICAL
-
-Nautical twilight (navigation using a sea horizon no longer possible)
-
-=item B<-15> degrees, AMATEUR
-
-Amateur astronomical twilight (the sky is dark enough for most astronomical observations)
-
-=item B<-18> degrees, ASTRONOMICAL
-
-Astronomical twilight (the sky is completely dark)
-
-=back
-
-=cut
-use strict;
-#use warnings;
-use POSIX qw(floor);
-use Math::Trig;
-use Carp;
-use DateTime;
-use vars qw( $VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $RADEG $DEGRAD );
-
-require Exporter;
-
-@ISA = qw( Exporter );
-@EXPORT = qw( sunrise sun_rise sun_set );
-@EXPORT_OK = qw( DEFAULT CIVIL NAUTICAL AMATEUR ASTRONOMICAL );
-%EXPORT_TAGS = (
- constants => [ @EXPORT_OK ],
- );
-
-$VERSION = '0.92';
-$RADEG = ( 180 / pi );
-$DEGRAD = ( pi / 180 );
-my $INV360 = ( 1.0 / 360.0 );
-
-my $upper_limb = '1';
-
-=head1 USAGE
-
-=over
-
-=item B<sunrise>
-
-=over
-
-=item C<($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST);>
-
-=item C<($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST,ALT);>
-
-
-
-Returns the sunrise and sunset times, in HH:MM format.
-(Note: Time Zone is the offset from GMT and DST is daylight
-savings time, 1 means DST is in effect and 0 is not). In the first form,
-a default altitude of -.0833 is used. In the second form, the altitude
-is specified as the last argument. Note that adding 1 to the
-Time Zone during DST and specifying DST as 0 is the same as indicating the
-Time Zone correctly and specifying DST as 1.
-
-=item F<Notes on Iteration>
-
-=over
-
-=item F<($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST,ALT,inter);>
-
-The original method only gives an approximate value of the Sun's rise/set times.
-The error rarely exceeds one or two minutes, but at high latitudes, when the Midnight Sun
-soon will start or just has ended, the errors may be much larger. If you want higher accuracy,
-you must then use the iteration feature. This feature is new as of version 0.7. Here is
-what I have tried to accomplish with this.
-
-a) Compute sunrise or sunset as always, with one exception: to convert LHA from degrees to hours,
- divide by 15.04107 instead of 15.0 (this accounts for the difference between the solar day
- and the sidereal day.
-
-b) Re-do the computation but compute the Sun's RA and Decl, and also GMST0, for the moment
- of sunrise or sunset last computed.
-
-c) Iterate b) until the computed sunrise or sunset no longer changes significantly.
- Usually 2 iterations are enough, in rare cases 3 or 4 iterations may be needed.
-
-=item I<For Example>
-
- ($sunrise, $sunset) = sunrise( 2001, 3, 10, 17.384, 98.625, -5, 0 );
- ($sunrise, $sunset) = sunrise( 2002, 10, 14, -105.181, 41.324, -7, 1, -18);
- ($sunrise, $sunset) = sunrise( 2002, 10, 14, -105.181, 41.324, -7, 1, -18, 1);
-
-=back
-
-=back
-
-=back
-
-=cut
-
-sub sunrise {
- my ( $year, $month, $day, $lon, $lat, $TZ, $isdst, $alt, $iter ) = @_;
- my $altit = $alt || -0.833;
- my $iteration = defined($iter) ? $iter:0 ;
-
- if ($iteration) {
- # This is the initial start
-
- my $d = days_since_2000_Jan_0( $year, $month, $day ) + 0.5 - $lon / 360.0;
- my ($tmp_rise_1,$tmp_set_1) = sun_rise_set($d, $lon, $lat,$altit,15.04107);
-
- # Now we have the initial rise/set times next recompute d using the exact moment
- # recompute sunrise
-
- my $tmp_rise_2 = 9;
- my $tmp_rise_3 = 0;
- until (equal($tmp_rise_2, $tmp_rise_3, 8) ) {
-
- my $d_sunrise_1 = $d + $tmp_rise_1/24.0;
- ($tmp_rise_2,undef) = sun_rise_set($d_sunrise_1, $lon, $lat,$altit,15.04107);
- $tmp_rise_1 = $tmp_rise_3;
- my $d_sunrise_2 = $d + $tmp_rise_2/24.0;
- ($tmp_rise_3,undef) = sun_rise_set($d_sunrise_2, $lon, $lat,$altit,15.04107);
-
- #print "tmp_rise2 is: $tmp_rise_2 tmp_rise_3 is:$tmp_rise_3\n";
- }
-
- my $tmp_set_2 = 9;
- my $tmp_set_3 = 0;
-
- until (equal($tmp_set_2, $tmp_set_3, 8) ) {
-
- my $d_sunset_1 = $d + $tmp_set_1/24.0;
- (undef,$tmp_set_2) = sun_rise_set($d_sunset_1, $lon, $lat,$altit,15.04107);
- $tmp_set_1 = $tmp_set_3;
- my $d_sunset_2 = $d + $tmp_set_2/24.0;
- (undef,$tmp_set_3) = sun_rise_set($d_sunset_2, $lon, $lat,$altit,15.04107);
-
- #print "tmp_set_1 is: $tmp_set_1 tmp_set_3 is:$tmp_set_3\n";
-
- }
-
-
- return convert_hour($tmp_rise_3, $tmp_set_3, $TZ, $isdst);
-
- }
- else {
- my $d = days_since_2000_Jan_0( $year, $month, $day ) + 0.5 - $lon / 360.0;
- my ($h1,$h2) = sun_rise_set($d, $lon, $lat, $altit, 15.0);
- return convert_hour($h1, $h2, $TZ, $isdst);
- }
-}
-#######################################################################################
-# end sunrise
-###################################################################################
-
-
-sub sun_rise_set {
- my ($d, $lon, $lat,$altit) =@_;
- #my ( $year, $month, $day, $lon, $lat, $TZ, $isdst, $alt ) = @_;
- #my $altit = $alt || -0.833;
- #my $d = days_since_2000_Jan_0( $year, $month, $day ) + 0.5 - $lon / 360.0;
-
- # Compute local sidereal time of this moment
- my $sidtime = revolution( GMST0($d) + 180.0 + $lon );
-
- # Compute Sun's RA + Decl + distance at this moment
- my ( $sRA, $sdec, $sr ) = sun_RA_dec($d);
-
- # Compute time when Sun is at south - in hours UT
- my $tsouth = 12.0 - rev180( $sidtime - $sRA ) / 15.0;
-
- # Compute the Sun's apparent radius, degrees
- my $sradius = 0.2666 / $sr;
-
- if ($upper_limb) {
- $altit -= $sradius;
- }
-
- # Compute the diurnal arc that the Sun traverses to reach
- # the specified altitude altit:
-
- my $cost =
- ( sind($altit) - sind($lat) * sind($sdec) ) /
- ( cosd($lat) * cosd($sdec) );
-
- my $t;
- if ( $cost >= 1.0 ) {
- carp "Sun never rises!!\n";
- $t = 0.0; # Sun always below altit
- }
- elsif ( $cost <= -1.0 ) {
- carp "Sun never sets!!\n";
- $t = 12.0; # Sun always above altit
- }
- else {
- $t = acosd($cost) / 15.0; # The diurnal arc, hours
- }
-
- # Store rise and set times - in hours UT
-
- my $hour_rise_ut = $tsouth - $t;
- my $hour_set_ut = $tsouth + $t;
- return($hour_rise_ut, $hour_set_ut);
- #return convert_hour($hour_rise_ut,$hour_set_ut,$TZ, $isdst);
-}
-
-#########################################################################################################
-#
-#
-# FUNCTIONAL SEQUENCE for GMST0
-#
-# _GIVEN
-# Day number
-#
-# _THEN
-#
-# computes GMST0, the Greenwich Mean Sidereal Time
-# at 0h UT (i.e. the sidereal time at the Greenwhich meridian at
-# 0h UT). GMST is then the sidereal time at Greenwich at any
-# time of the day..
-#
-#
-# _RETURN
-#
-# Sidtime
-#
-sub GMST0 {
- my ($d) = @_;
-
- my $sidtim0 =
- revolution( ( 180.0 + 356.0470 + 282.9404 ) +
- ( 0.9856002585 + 4.70935E-5 ) * $d );
- return $sidtim0;
-
-}
-
-
-#
-#
-# FUNCTIONAL SEQUENCE for sunpos
-#
-# _GIVEN
-# day number
-#
-# _THEN
-#
-# Computes the Sun's ecliptic longitude and distance */
-# at an instant given in d, number of days since */
-# 2000 Jan 0.0.
-#
-#
-# _RETURN
-#
-# ecliptic longitude and distance
-# ie. $True_solar_longitude, $Solar_distance
-#
-sub sunpos {
- my ($d) = @_;
-
- # Mean anomaly of the Sun
- # Mean longitude of perihelion
- # Note: Sun's mean longitude = M + w
- # Eccentricity of Earth's orbit
- # Eccentric anomaly
- # x, y coordinates in orbit
- # True anomaly
-
- # Compute mean elements
- my $Mean_anomaly_of_sun = revolution( 356.0470 + 0.9856002585 * $d );
- my $Mean_longitude_of_perihelion = 282.9404 + 4.70935E-5 * $d;
- my $Eccentricity_of_Earth_orbit = 0.016709 - 1.151E-9 * $d;
-
- # Compute true longitude and radius vector
- my $Eccentric_anomaly =
- $Mean_anomaly_of_sun + $Eccentricity_of_Earth_orbit * $RADEG *
- sind($Mean_anomaly_of_sun) *
- ( 1.0 + $Eccentricity_of_Earth_orbit * cosd($Mean_anomaly_of_sun) );
-
- my $x = cosd($Eccentric_anomaly) - $Eccentricity_of_Earth_orbit;
-
- my $y =
- sqrt( 1.0 - $Eccentricity_of_Earth_orbit * $Eccentricity_of_Earth_orbit )
- * sind($Eccentric_anomaly);
-
- my $Solar_distance = sqrt( $x * $x + $y * $y ); # Solar distance
- my $True_anomaly = atan2d( $y, $x ); # True anomaly
-
- my $True_solar_longitude =
- $True_anomaly + $Mean_longitude_of_perihelion; # True solar longitude
-
- if ( $True_solar_longitude >= 360.0 ) {
- $True_solar_longitude -= 360.0; # Make it 0..360 degrees
- }
-
- return ( $Solar_distance, $True_solar_longitude );
-}
-
-
-#
-#
-# FUNCTIONAL SEQUENCE for sun_RA_dec
-#
-# _GIVEN
-# day number, $r and $lon (from sunpos)
-#
-# _THEN
-#
-# compute RA and dec
-#
-#
-# _RETURN
-#
-# Sun's Right Ascension (RA), Declination (dec) and distance (r)
-#
-#
-sub sun_RA_dec {
- my ($d) = @_;
-
- # Compute Sun's ecliptical coordinates
- my ( $r, $lon ) = sunpos($d);
-
- # Compute ecliptic rectangular coordinates (z=0)
- my $x = $r * cosd($lon);
- my $y = $r * sind($lon);
-
- # Compute obliquity of ecliptic (inclination of Earth's axis)
- my $obl_ecl = 23.4393 - 3.563E-7 * $d;
-
- # Convert to equatorial rectangular coordinates - x is unchanged
- my $z = $y * sind($obl_ecl);
- $y = $y * cosd($obl_ecl);
-
- # Convert to spherical coordinates
- my $RA = atan2d( $y, $x );
- my $dec = atan2d( $z, sqrt( $x * $x + $y * $y ) );
-
- return ( $RA, $dec, $r );
-
-} # sun_RA_dec
-
-
-#
-#
-# FUNCTIONAL SEQUENCE for days_since_2000_Jan_0
-#
-# _GIVEN
-# year, month, day
-#
-# _THEN
-#
-# process the year month and day (counted in days)
-# Day 0.0 is at Jan 1 2000 0.0 UT
-# Note that ALL divisions here should be INTEGER divisions
-#
-# _RETURN
-#
-# day number
-#
-sub days_since_2000_Jan_0 {
- use integer;
- my ( $year, $month, $day ) = @_;
-
- my $d =
- ( 367 * ($year) -
- int( ( 7 * ( ($year) + ( ( ($month) + 9 ) / 12 ) ) ) / 4 ) +
- int( ( 275 * ($month) ) / 9 ) + ($day) - 730530 );
-
- return $d;
-
-}
-
-sub sind {
- sin( ( $_[0] ) * $DEGRAD );
-}
-
-sub cosd {
- cos( ( $_[0] ) * $DEGRAD );
-}
-
-sub tand {
- tan( ( $_[0] ) * $DEGRAD );
-}
-
-sub atand {
- ( $RADEG * atan( $_[0] ) );
-}
-
-sub asind {
- ( $RADEG * asin( $_[0] ) );
-}
-
-sub acosd {
- ( $RADEG * acos( $_[0] ) );
-}
-
-sub atan2d {
- ( $RADEG * atan2( $_[0], $_[1] ) );
-}
-
-#
-#
-# FUNCTIONAL SEQUENCE for revolution
-#
-# _GIVEN
-# any angle
-#
-# _THEN
-#
-# reduces any angle to within the first revolution
-# by subtracting or adding even multiples of 360.0
-#
-#
-# _RETURN
-#
-# the value of the input is >= 0.0 and < 360.0
-#
-
-sub revolution {
- my $x = $_[0];
- return ( $x - 360.0 * floor( $x * $INV360 ) );
-}
-
-#
-#
-# FUNCTIONAL SEQUENCE for rev180
-#
-# _GIVEN
-#
-# any angle
-#
-# _THEN
-#
-# Reduce input to within +180..+180 degrees
-#
-#
-# _RETURN
-#
-# angle that was reduced
-#
-sub rev180 {
- my ($x) = @_;
-
- return ( $x - 360.0 * floor( $x * $INV360 + 0.5 ) );
-}
-
-sub equal {
- my ($A, $B, $dp) = @_;
-
- return sprintf("%.${dp}g", $A) eq sprintf("%.${dp}g", $B);
- }
-
-
-
-#
-#
-# FUNCTIONAL SEQUENCE for convert_hour
-#
-# _GIVEN
-# Hour_rise, Hour_set, Time zone offset, DST setting
-# hours are in UT
-#
-# _THEN
-#
-# convert to local time
-#
-#
-# _RETURN
-#
-# hour:min rise and set
-#
-
-sub convert_hour {
- my ($hour_rise_ut, $hour_set_ut, $TZ, $isdst) = @_;
-
- my $rise_local = $hour_rise_ut + $TZ;
- my $set_local = $hour_set_ut + $TZ;
- if ($isdst) {
- $rise_local +=1;
- $set_local +=1;
- }
-
- # Rise and set should be between 0 and 24;
- if ($rise_local<0) {
- $rise_local+=24;
- }
- elsif ($rise_local>24) {
- $rise_local -=24;
- }
- if ($set_local<0) {
- $set_local+=24;
- }
- elsif ($set_local>24) {
- $set_local -=24;
- }
-
- my $hour_rise = int ($rise_local);
- my $hour_set = int($set_local);
-
- my $min_rise = floor(($rise_local-$hour_rise)*60+0.5);
- my $min_set = floor(($set_local-$hour_set)*60+0.5);
-
- if ($min_rise>=60) {
- $min_rise -=60;
- $hour_rise+=1;
- $hour_rise-=24 if ($hour_rise>=24);
- }
- if ($min_set>=60) {
- $min_set -=60;
- $hour_set+=1;
- $hour_set-=24 if ($hour_set>=24);
- }
-
- if ( $min_rise < 10 ) {
- $min_rise = sprintf( "%02d", $min_rise );
- }
- if ( $min_set < 10 ) {
- $min_set = sprintf( "%02d", $min_set );
- }
- $hour_rise = sprintf( "%02d", $hour_rise );
- $hour_set = sprintf( "%02d", $hour_set );
- return ( "$hour_rise:$min_rise", "$hour_set:$min_set" );
-
-}
-
-=over
-
-=item B<sun_rise>
-
-=over
-
-=item C<$sun_rise = sun_rise( longitude, latitude );>
-
-=item C<$sun_rise = sun_rise( longitude, latitude, ALT );>
-
-=item C<$sun_rise = sun_rise( longitude, latitude, ALT, day_offset );>
-
-Returns the sun rise time for the given location. The first form
-uses today's date (from DateTime) and the default altitude. The second
-form adds specifying a custom altitude. The third form allows for specifying
-an integer day offset from today, either positive or negative.
-
-=item I<For Example>
-
- $sunrise = sun_rise( -105.181, 41.324 );
- $sunrise = sun_rise( -105.181, 41.324, -15 );
- $sunrise = sun_rise( -105.181, 41.324, -12, +3 );
- $sunrise = sun_rise( -105.181, 41.324, undef, -12);
-
-=back
-
-=back
-
-=cut
-
-sub sun_rise
- {
- my $longitude = shift;
- my $latitude = shift;
- my $alt = shift || -0.833;
- my $offset = int( shift || 0 );
-
- my $today = DateTime->today->set_time_zone( 'local' );
- $today->add( days => $offset );
-
- my( $sun_rise, undef ) = sunrise( $today->year, $today->mon, $today->mday,
- $longitude, $latitude,
- ( $today->offset / 3600 ),
- #
- # DST is always 0 because DateTime
- # currently (v 0.16) adds one to the
- # offset during DST hours
- 0,
- $alt );
- return $sun_rise;
- }
-
-=over
-
-=item B<sun_set>
-
-=over
-
-=item C<$sun_set = sun_set( longitude, latitude );>
-
-=item C<$sun_set = sun_set( longitude, latitude, ALT );>
-
-=item C<$sun_set = sun_set( longitude, latitude, ALT, day_offset );>
-
-Returns the sun set time for the given location. The first form
-uses today's date (from DateTime) and the default altitude. The second
-form adds specifying a custom altitude. The third form allows for specifying
-an integer day offset from today, either positive or negative.
-
-=item I<For Example>
-
- $sunset = sun_set( -105.181, 41.324 );
- $sunset = sun_set( -105.181, 41.324, -15 );
- $sunset = sun_set( -105.181, 41.324, -12, +3 );
- $sunset = sun_set( -105.181, 41.324, undef, -12);
-
-=back
-
-=back
-
-=cut
-
-sub sun_set
- {
- my $longitude = shift;
- my $latitude = shift;
- my $alt = shift || -0.833;
- my $offset = int( shift || 0 );
-
- my $today = DateTime->today->set_time_zone( 'local' );
- $today->add( days => $offset );
-
- my( undef, $sun_set ) = sunrise( $today->year, $today->mon, $today->mday,
- $longitude, $latitude,
- ( $today->offset / 3600 ),
- #
- # DST is always 0 because DateTime
- # currently (v 0.16) adds one to the
- # offset during DST hours
- 0,
- $alt );
- return $sun_set;
- }
-
-sub DEFAULT () { -0.833 }
-sub CIVIL () { - 6 }
-sub NAUTICAL () { -12 }
-sub AMATEUR () { -15 }
-sub ASTRONOMICAL () { -18 }
-
-=head1 AUTHOR
-
-Ron Hill
-rkhill@firstlight.net
-
-=head1 SPECIAL THANKS
-
-Robert Creager [Astro-Sunrise@LogicalChaos.org]
-For providing help with converting Paul's C code to perl
-For providing code for sun_rise, sun_set sub's
-Also adding options for different altitudes.
-
-Joshua Hoblitt [jhoblitt@ifa.hawaii.edu]
-For providing the patch to convert to DateTime
-
-Chris Phillips for providing patch for conversion to
-local time.
-
-Brian D Foy for providing patch for constants :)
-
-=head1 CREDITS
-
-=over 4
-
-=item Paul Schlyter, Stockholm, Sweden
-
-for his excellent web page on the subject.
-
-=item Rich Bowen (rbowen@rbowen.com)
-
-for suggestions
-
-=item Adrian Blockley [adrian.blockley@environ.wa.gov.au]
-
-for finding a bug in the conversion to local time
-
-=back
-
-Lightly verified against http://aa.usno.navy.mil/data/docs/RS_OneYear.html
-
-=head1 COPYRIGHT and LICENSE
-
-Here is the copyright information provided by Paul Schlyer:
-
-Written as DAYLEN.C, 1989-08-16
-
-Modified to SUNRISET.C, 1992-12-01
-
-(c) Paul Schlyter, 1989, 1992
-
-Released to the public domain by Paul Schlyter, December 1992
-
-Permission is hereby granted, free of charge, to any person obtaining a
-copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
-OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-=head1 BUGS
-
-=head1 SEE ALSO
-
-perl(1).
-
-=cut
-
-1950;
-# Hint: by BW, with GS, WH and EVS
@@ -0,0 +1,21 @@
+-*- encoding: utf-8; indent-tabs-mode: nil -*-
+
+Most remaining issues have been dealt with in version 0.93. Yet,
+two issues will need to be addressed in some next version.
+
+1) Check the "precise" algorithm.
+
+2) Improve code coverage in module checks.
+In other words, play the Devel::Cover game.
+
+3) Play the CPANTS game.
+
+But remember that this is not an end in itself. It is just a mean
+(kwalitee checking) towards an end (quality). For example, the module
+did not get the points for the LICENSE POD paragraph. Yet, there is a
+LICENSE POD paragraph. Just the automated CPANTS check did not
+recognize its contents. But any human reader will admit the paragraph
+is correct. So this is a kwalitee issue I will not fix. And I will
+not complain to the authors of the programs that power the CPANTS
+site. I have better things to do and they have better things to do.
+
@@ -0,0 +1,1089 @@
+# -*- encoding: utf-8; indent-tabs-mode: nil -*-
+#
+# Perl extension for computing the sunrise/sunset on a given day
+# Copyright (C) 1999-2003, 2013, 2015 Ron Hill and Jean Forget
+#
+# See the license in the embedded documentation below.
+#
+package Astro::Sunrise;
+
+use strict;
+use warnings;
+use POSIX qw(floor);
+use Math::Trig;
+use Carp;
+use vars qw( $VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $RADEG $DEGRAD );
+
+require Exporter;
+
+@ISA = qw( Exporter );
+@EXPORT = qw( sunrise sun_rise sun_set );
+@EXPORT_OK = qw( DEFAULT CIVIL NAUTICAL AMATEUR ASTRONOMICAL sind cosd tand asind acosd atand atan2d equal );
+%EXPORT_TAGS = (
+ constants => [ qw/DEFAULT CIVIL NAUTICAL AMATEUR ASTRONOMICAL/ ],
+ trig => [ qw/sind cosd tand asind acosd atand atan2d equal/ ],
+ );
+
+$VERSION = '0.95';
+$RADEG = ( 180 / pi );
+$DEGRAD = ( pi / 180 );
+my $INV360 = ( 1.0 / 360.0 );
+
+sub sunrise {
+ my %arg;
+ if (ref($_[0]) eq 'HASH') {
+ %arg = %{$_[0]};
+ }
+ else {
+ @arg{ qw/year month day lon lat tz isdst alt precise/ } = @_;
+ }
+ my ( $year, $month, $day, $lon, $lat, $TZ, $isdst)
+ = @arg{ qw/year month day lon lat tz isdst/ };
+ my $altit = defined($arg{alt} ) ? $arg{alt} : -0.833;
+ $arg{precise} ||= 0;
+ $arg{upper_limb} ||= 0;
+ $arg{polar} ||= 'warn';
+ croak "Year parameter is mandatory"
+ unless defined $year;
+ croak "Month parameter is mandatory"
+ unless defined $month;
+ croak "Day parameter is mandatory"
+ unless defined $day;
+ croak "Longitude parameter (keyword: 'lon') is mandatory"
+ unless defined $lon;
+ croak "Latitude parameter (keyword: 'lat') is mandatory"
+ unless defined $lat;
+ croak "Wrong value of the 'polar' argument: should be either 'warn' or 'retval'"
+ if $arg{polar} ne 'warn' and $arg{polar} ne 'retval';
+
+ if ($arg{precise}) {
+ # This is the initial start
+
+ my $d = days_since_2000_Jan_0( $year, $month, $day ) + 0.5 - $lon / 360.0;
+ my ($tmp_rise_1, $tmp_set_1) = sun_rise_set($d, $lon, $lat, $altit, 15.04107, $arg{upper_limb}, $arg{polar});
+
+ # Now we have the initial rise/set times next recompute d using the exact moment
+ # recompute sunrise
+
+ my $tmp_rise_2 = 9;
+ my $tmp_rise_3 = 0;
+ until (equal($tmp_rise_2, $tmp_rise_3, 8) ) {
+
+ my $d_sunrise_1 = $d + $tmp_rise_1/24.0;
+ ($tmp_rise_2, undef) = sun_rise_set($d_sunrise_1, $lon, $lat, $altit, 15.04107, $arg{upper_limb}, $arg{polar});
+ $tmp_rise_1 = $tmp_rise_3;
+ my $d_sunrise_2 = $d + $tmp_rise_2/24.0;
+ ($tmp_rise_3, undef) = sun_rise_set($d_sunrise_2, $lon, $lat, $altit, 15.04107, $arg{upper_limb}, $arg{polar});
+
+ #print "tmp_rise2 is: $tmp_rise_2 tmp_rise_3 is:$tmp_rise_3\n";
+ }
+
+ my $tmp_set_2 = 9;
+ my $tmp_set_3 = 0;
+
+ until (equal($tmp_set_2, $tmp_set_3, 8) ) {
+
+ my $d_sunset_1 = $d + $tmp_set_1/24.0;
+ (undef, $tmp_set_2) = sun_rise_set($d_sunset_1, $lon, $lat, $altit, 15.04107, $arg{upper_limb}, $arg{polar});
+ $tmp_set_1 = $tmp_set_3;
+ my $d_sunset_2 = $d + $tmp_set_2/24.0;
+ (undef, $tmp_set_3) = sun_rise_set($d_sunset_2, $lon, $lat, $altit, 15.04107, $arg{upper_limb}, $arg{polar});
+
+ #print "tmp_set_1 is: $tmp_set_1 tmp_set_3 is:$tmp_set_3\n";
+
+ }
+
+ return convert_hour($tmp_rise_3, $tmp_set_3, $TZ, $isdst);
+
+ }
+ else {
+ my $d = days_since_2000_Jan_0( $year, $month, $day ) + 0.5 - $lon / 360.0;
+ my ($h1, $h2) = sun_rise_set($d, $lon, $lat, $altit, 15.0, $arg{upper_limb}, $arg{polar});
+ if ($h1 eq 'day' or $h1 eq 'night' or $h2 eq 'day' or $h2 eq 'night') {
+ return ($h1, $h2);
+ }
+ return convert_hour($h1, $h2, $TZ, $isdst);
+ }
+}
+#######################################################################################
+# end sunrise
+###################################################################################
+
+
+sub sun_rise_set {
+ my ($d, $lon, $lat,$altit, $h, $upper_limb, $polar) = @_;
+
+ # Compute local sidereal time of this moment
+ my $sidtime = revolution( GMST0($d) + 180.0 + $lon );
+
+ # Compute Sun's RA + Decl + distance at this moment
+ my ( $sRA, $sdec, $sr ) = sun_RA_dec($d);
+
+ # Compute time when Sun is at south - in hours UT
+ my $tsouth = 12.0 - rev180( $sidtime - $sRA ) / $h;
+
+ if ($upper_limb) {
+ # Compute the Sun's apparent radius, degrees
+ my $sradius = 0.2666 / $sr;
+ $altit -= $sradius;
+ }
+
+ # Compute the diurnal arc that the Sun traverses to reach
+ # the specified altitude altit:
+
+ my $cost = ( sind($altit) - sind($lat) * sind($sdec) )
+ / ( cosd($lat) * cosd($sdec) );
+
+ my $t;
+ if ( $cost >= 1.0 ) {
+ if ($polar eq 'retval') {
+ return ('night', 'night');
+ }
+ carp "Sun never rises!!\n";
+ $t = 0.0; # Sun always below altit
+ }
+ elsif ( $cost <= -1.0 ) {
+ if ($polar eq 'retval') {
+ return ('day', 'day');
+ }
+ carp "Sun never sets!!\n";
+ $t = 12.0; # Sun always above altit
+ }
+ else {
+ $t = acosd($cost) / 15.0; # The diurnal arc, hours
+ }
+
+ # Store rise and set times - in hours UT
+
+ my $hour_rise_ut = $tsouth - $t;
+ my $hour_set_ut = $tsouth + $t;
+ return($hour_rise_ut, $hour_set_ut);
+}
+
+#########################################################################################################
+#
+#
+# FUNCTIONAL SEQUENCE for GMST0
+#
+# _GIVEN
+# Day number
+#
+# _THEN
+#
+# computes GMST0, the Greenwich Mean Sidereal Time
+# at 0h UT (i.e. the sidereal time at the Greenwich meridian at
+# 0h UT). GMST is then the sidereal time at Greenwich at any
+# time of the day..
+#
+#
+# _RETURN
+#
+# Sidtime
+#
+sub GMST0 {
+ my ($d) = @_;
+
+ my $sidtim0 =
+ revolution( ( 180.0 + 356.0470 + 282.9404 ) +
+ ( 0.9856002585 + 4.70935E-5 ) * $d );
+ return $sidtim0;
+
+}
+
+
+#
+#
+# FUNCTIONAL SEQUENCE for sunpos
+#
+# _GIVEN
+# day number
+#
+# _THEN
+#
+# Computes the Sun's ecliptic longitude and distance
+# at an instant given in d, number of days since
+# 2000 Jan 0.0.
+#
+#
+# _RETURN
+#
+# ecliptic longitude and distance
+# ie. $True_solar_longitude, $Solar_distance
+#
+sub sunpos {
+ my ($d) = @_;
+
+ # Mean anomaly of the Sun
+ # Mean longitude of perihelion
+ # Note: Sun's mean longitude = M + w
+ # Eccentricity of Earth's orbit
+ # Eccentric anomaly
+ # x, y coordinates in orbit
+ # True anomaly
+
+ # Compute mean elements
+ my $Mean_anomaly_of_sun = revolution( 356.0470 + 0.9856002585 * $d );
+ my $Mean_longitude_of_perihelion = 282.9404 + 4.70935E-5 * $d;
+ my $Eccentricity_of_Earth_orbit = 0.016709 - 1.151E-9 * $d;
+
+ # Compute true longitude and radius vector
+ my $Eccentric_anomaly =
+ $Mean_anomaly_of_sun + $Eccentricity_of_Earth_orbit * $RADEG *
+ sind($Mean_anomaly_of_sun) *
+ ( 1.0 + $Eccentricity_of_Earth_orbit * cosd($Mean_anomaly_of_sun) );
+
+ my $x = cosd($Eccentric_anomaly) - $Eccentricity_of_Earth_orbit;
+
+ my $y =
+ sqrt( 1.0 - $Eccentricity_of_Earth_orbit * $Eccentricity_of_Earth_orbit )
+ * sind($Eccentric_anomaly);
+
+ my $Solar_distance = sqrt( $x * $x + $y * $y ); # Solar distance
+ my $True_anomaly = atan2d( $y, $x ); # True anomaly
+
+ my $True_solar_longitude =
+ $True_anomaly + $Mean_longitude_of_perihelion; # True solar longitude
+
+ if ( $True_solar_longitude >= 360.0 ) {
+ $True_solar_longitude -= 360.0; # Make it 0..360 degrees
+ }
+
+ return ( $Solar_distance, $True_solar_longitude );
+}
+
+
+#
+#
+# FUNCTIONAL SEQUENCE for sun_RA_dec
+#
+# _GIVEN
+# day number, $r and $lon (from sunpos)
+#
+# _THEN
+#
+# compute RA and dec
+#
+#
+# _RETURN
+#
+# Sun's Right Ascension (RA), Declination (dec) and distance (r)
+#
+#
+sub sun_RA_dec {
+ my ($d) = @_;
+
+ # Compute Sun's ecliptical coordinates
+ my ( $r, $lon ) = sunpos($d);
+
+ # Compute ecliptic rectangular coordinates (z=0)
+ my $x = $r * cosd($lon);
+ my $y = $r * sind($lon);
+
+ # Compute obliquity of ecliptic (inclination of Earth's axis)
+ my $obl_ecl = 23.4393 - 3.563E-7 * $d;
+
+ # Convert to equatorial rectangular coordinates - x is unchanged
+ my $z = $y * sind($obl_ecl);
+ $y = $y * cosd($obl_ecl);
+
+ # Convert to spherical coordinates
+ my $RA = atan2d( $y, $x );
+ my $dec = atan2d( $z, sqrt( $x * $x + $y * $y ) );
+
+ return ( $RA, $dec, $r );
+
+} # sun_RA_dec
+
+
+#
+#
+# FUNCTIONAL SEQUENCE for days_since_2000_Jan_0
+#
+# _GIVEN
+# year, month, day
+#
+# _THEN
+#
+# process the year month and day (counted in days)
+# Day 0.0 is at Jan 1 2000 0.0 UT
+# Note that ALL divisions here should be INTEGER divisions
+#
+# _RETURN
+#
+# day number
+#
+sub days_since_2000_Jan_0 {
+ use integer;
+ my ( $year, $month, $day ) = @_;
+
+ my $d =
+ ( 367 * ($year) -
+ int( ( 7 * ( ($year) + ( ( ($month) + 9 ) / 12 ) ) ) / 4 ) +
+ int( ( 275 * ($month) ) / 9 ) + ($day) - 730530 );
+
+ return $d;
+
+}
+
+sub sind {
+ sin( ( $_[0] ) * $DEGRAD );
+}
+
+sub cosd {
+ cos( ( $_[0] ) * $DEGRAD );
+}
+
+sub tand {
+ tan( ( $_[0] ) * $DEGRAD );
+}
+
+sub atand {
+ ( $RADEG * atan( $_[0] ) );
+}
+
+sub asind {
+ ( $RADEG * asin( $_[0] ) );
+}
+
+sub acosd {
+ ( $RADEG * acos( $_[0] ) );
+}
+
+sub atan2d {
+ ( $RADEG * atan2( $_[0], $_[1] ) );
+}
+
+#
+#
+# FUNCTIONAL SEQUENCE for revolution
+#
+# _GIVEN
+# any angle
+#
+# _THEN
+#
+# reduces any angle to within the first revolution
+# by subtracting or adding even multiples of 360.0
+#
+#
+# _RETURN
+#
+# the value of the input is >= 0.0 and < 360.0
+#
+
+sub revolution {
+ my $x = $_[0];
+ return ( $x - 360.0 * floor( $x * $INV360 ) );
+}
+
+#
+#
+# FUNCTIONAL SEQUENCE for rev180
+#
+# _GIVEN
+#
+# any angle
+#
+# _THEN
+#
+# Reduce input to within +180..+180 degrees
+#
+#
+# _RETURN
+#
+# angle that was reduced
+#
+sub rev180 {
+ my ($x) = @_;
+
+ return ( $x - 360.0 * floor( $x * $INV360 + 0.5 ) );
+}
+
+sub equal {
+ my ($A, $B, $dp) = @_;
+
+ return sprintf("%.${dp}g", $A) eq sprintf("%.${dp}g", $B);
+}
+
+#
+#
+# FUNCTIONAL SEQUENCE for convert_hour
+#
+# _GIVEN
+# Hour_rise, Hour_set, Time zone offset, DST setting
+# hours are in UT
+#
+# _THEN
+#
+# convert to local time
+#
+#
+# _RETURN
+#
+# hour:min rise and set
+#
+
+sub convert_hour {
+ my ($hour_rise_ut, $hour_set_ut, $TZ, $isdst) = @_;
+ return (convert_1_hour($hour_rise_ut, $TZ, $isdst),
+ convert_1_hour($hour_set_ut, $TZ, $isdst));
+}
+#
+#
+# FUNCTIONAL SEQUENCE for convert_1_hour
+#
+# _GIVEN
+# Hour, Time zone offset, DST setting
+# hours are in UT
+#
+# _THEN
+#
+# convert to local time
+#
+#
+# _RETURN
+#
+# hour:min
+#
+
+sub convert_1_hour {
+ my ($hour_ut, $TZ, $isdst) = @_;
+ my $hour_local = $hour_ut + $TZ;
+ if ($isdst) {
+ $hour_local ++;
+ }
+
+ # The hour should be between 0 and 24;
+ if ($hour_local < 0) {
+ $hour_local += 24;
+ }
+ elsif ($hour_local > 24) {
+ $hour_local -= 24;
+ }
+
+ my $hour = int ($hour_local);
+
+ my $min = floor(($hour_local - $hour) * 60 + 0.5);
+
+ if ($min >= 60) {
+ $min -= 60;
+ $hour++;
+ $hour -= 24 if $hour >= 24;
+ }
+
+ return sprintf("%02d:%02d", $hour, $min);
+}
+
+sub sun_rise {
+ my ($sun_rise, undef) = sun_rise_sun_set(@_);
+ return $sun_rise;
+}
+sub sun_set {
+ my (undef, $sun_set) = sun_rise_sun_set(@_);
+ return $sun_set;
+}
+
+sub sun_rise_sun_set {
+ my %arg;
+ if (ref($_[0]) eq 'HASH') {
+ %arg = %{$_[0]};
+ }
+ else {
+ @arg{ qw/lon lat alt offset/ } = @_;
+ }
+
+ # This trick aims to fulfill two antagonistic purposes:
+ # -- do not load DateTime if the only function called is "sunrise"
+ # -- load DateTime implicitly if the user calls "sun_rise" or "sun_set". This is to be backward
+ # compatible with 0.92 or earlier, when Astro::Sunrise would load DateTime and thus, allow
+ # the user to remove this line from his script.
+ unless ($INC{DateTime}) {
+ eval "use DateTime";
+ croak $@
+ if $@;
+ }
+
+ my ($longitude, $latitude) = @arg{ qw/lon lat/ };
+ my $alt = defined($arg{alt} ) ? $arg{alt} : -0.833;
+ my $offset = defined($arg{offset} ) ? int($arg{offset}) : 0 ;
+ my $tz = defined($arg{time_zone}) ? $arg{time_zone} : 'local';
+ $arg{precise} ||= 0;
+ $arg{upper_limb} ||= 0;
+ $arg{polar} ||= 'warn';
+ croak "Longitude parameter (keyword: 'lon') is mandatory"
+ unless defined $longitude;
+ croak "Latitude parameter (keyword: 'lat') is mandatory"
+ unless defined $latitude;
+ croak "Wrong value of the 'polar' argument: should be either 'warn' or 'retval'"
+ if $arg{polar} ne 'warn' and $arg{polar} ne 'retval';
+
+ my $today = DateTime->today(time_zone => $tz);
+ $today->set( hour => 12 );
+ $today->add( days => $offset );
+
+ my( $sun_rise, $sun_set ) = sunrise( { year => $today->year,
+ month => $today->mon,
+ day => $today->mday,
+ lon => $longitude,
+ lat => $latitude,
+ tz => ( $today->offset / 3600 ),
+ #
+ # DST is always 0 because DateTime
+ # currently (v 0.16) adds one to the
+ # offset during DST hours
+ isdst => 0,
+ alt => $alt,
+ precise => $arg{precise},
+ upper_limb => $arg{upper_limb},
+ polar => $arg{polar},
+ } );
+ return ($sun_rise, $sun_set);
+}
+
+sub DEFAULT () { -0.833 }
+sub CIVIL () { - 6 }
+sub NAUTICAL () { -12 }
+sub AMATEUR () { -15 }
+sub ASTRONOMICAL () { -18 }
+
+# Ending a module with whatever, which risks to be zero, is wrong.
+# Ending a module with 1 is boring. So, let us end it with:
+1950;
+# Hint: directed by BW, with GS, WH and EVS
+
+__END__
+
+=encoding utf8
+
+=head1 NAME
+
+Astro::Sunrise - Perl extension for computing the sunrise/sunset on a given day
+
+=head1 VERSION
+
+This documentation refers to C<Astro::Sunrise> version 0.95.
+
+=head1 SYNOPSIS
+
+ # When will the sun rise on YAPC::Europe 2015?
+ use Astro::Sunrise;
+ my ($sunrise, $sunset) = sunrise( { year => 2015, month => 9, day => 2, # YAPC::EU starts on 2nd September 2015
+ lon => -3.6, lat => 37.17, # Granada is 37°10'N, 3°36'W
+ tz => 1, dst => 1 } ); # This is still summer, therefore DST
+
+ # When does the sun rise today in Salt Lake City (home to YAPC::NA 2015)?
+ use Astro::Sunrise;
+ use DateTime;
+ $sunrise_today = sun_rise( { lon => -111.88, lat => 40.75 } ); # 40°45'N, 111°53'W
+
+ # And when does it set tomorrow at Salt Lake City?
+ use Astro::Sunrise;
+ use DateTime;
+ $sunset_tomorrow = sun_set( { lat => 40.75, # 40°45'N,
+ lon => -111.88, # 111°53'W
+ alt => -0.833, # standard value for the sun altitude at sunset
+ offset => 1 } ); # day offset up to tomorrow
+
+=head1 DESCRIPTION
+
+This module will return the sunrise and sunset for a given day.
+
+Months are numbered 1 to 12, in the usual way, not 0 to 11 as in
+C and in Perl's localtime.
+
+ Eastern longitude is entered as a positive number
+ Western longitude is entered as a negative number
+ Northern latitude is entered as a positive number
+ Southern latitude is entered as a negative number
+
+Please note that, when given as positional parameters, the longitude is specified before the
+latitude.
+
+The time zone is given as the numeric value of the offset from UTC.
+
+The C<precise> parameter is set to either 0 or 1.
+If set to 0 no Iteration will occur.
+If set to 1 Iteration will occur, which will give a more precise result.
+Default is 0.
+
+There are a number of sun altitudes to chose from. The default is
+-0.833 because this is what most countries use. Feel free to
+specify it if you need to. Here is the list of values to specify
+altitude (ALT) with, including symbolic constants for each.
+
+=over
+
+=item B<0> degrees
+
+Center of Sun's disk touches a mathematical horizon
+
+=item B<-0.25> degrees
+
+Sun's upper limb touches a mathematical horizon
+
+=item B<-0.583> degrees
+
+Center of Sun's disk touches the horizon; atmospheric refraction accounted for
+
+=item B<-0.833> degrees, DEFAULT
+
+Sun's upper limb touches the horizon; atmospheric refraction accounted for
+
+=item B<-6> degrees, CIVIL
+
+Civil twilight (one can no longer read outside without artificial illumination)
+
+=item B<-12> degrees, NAUTICAL
+
+Nautical twilight (navigation using a sea horizon no longer possible)
+
+=item B<-15> degrees, AMATEUR
+
+Amateur astronomical twilight (the sky is dark enough for most astronomical observations)
+
+=item B<-18> degrees, ASTRONOMICAL
+
+Astronomical twilight (the sky is completely dark)
+
+=back
+
+=head1 USAGE
+
+=head2 B<sunrise>
+
+ ($sunrise, $sunset) = sunrise( { year => $year, month => $month, day => $day,
+ lon => $longitude, lat => $latitude,
+ tz => $tz_offset, isdst => $is_dst,
+ alt => $altitude, upper_limb => $upper_limb,
+ precise => $precise, polar => $action } );
+
+ ($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST);
+
+ ($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST,ALT);
+
+ ($sunrise, $sunset) = sunrise(YYYY,MM,DD,longitude,latitude,Time Zone,DST,ALT,precise);
+
+Returns the sunrise and sunset times, in HH:MM format.
+
+The first form uses a hash reference to pass arguments by name.
+The other forms are kept for backward compatibility. The arguments are:
+
+=over 4
+
+=item year, month, day
+
+The three elements of the date for which you want to compute the sunrise and sunset.
+Months are numbered 1 to 12, in the usual way, not 0 to 11 as in C and in Perl's localtime.
+
+Mandatory, can be positional (#1, #2 and #3).
+
+=item lon, lat
+
+The longitude and latitude of the place for which you want to compute the sunrise and sunset.
+They are given in decimal degrees. For example:
+
+ lon => -3.6, # 3° 36' W
+ lat => 37.17, # 37° 10' N
+
+ Eastern longitude is entered as a positive number
+ Western longitude is entered as a negative number
+ Northern latitude is entered as a positive number
+ Southern latitude is entered as a negative number
+
+Mandatory, can be positional (#4 and #5).
+
+=item tz
+
+Time Zone is the offset from GMT
+
+Mandatory, can be positional (#6).
+
+=item isdst
+
+1 if daylight saving time is in effect, 0 if not.
+
+Mandatory, can be positional (#7).
+
+=item alt
+
+Altitude of the sun, in decimal degrees. Usually a negative number,
+because the sun should be I<under> the mathematical horizon.
+But if there is a high mountain range sunward (that is, southward if you
+live in the Northern hemisphere), you may need to enter a positive altitude.
+
+This parameter is optional. Its default value is -0.833. It can be positional (#8).
+
+=item upper_limb
+
+If this parameter set to a true value (usually 1), the algorithm computes
+the sun apparent radius and takes it into account when computing the sun
+altitude. This parameter is useful only when the C<alt> parameter is set
+to C<0> or C<-0.583> degrees. When using C<-0.25> or C<-0.833> degrees,
+the sun radius is already taken into account. When computing twilights
+(C<-6> to C<-18>), the sun radius is irrelevant.
+
+Since the default value for the C<alt> parameter is -0.833, the
+default value for C<upper_limb> is 0.
+
+This parameter is optional and it can be specified only by keyword.
+
+=item polar
+
+When dealing with a polar location, there may be dates where there is
+a polar night (sun never rises) or a polar day. The default behaviour of
+the module is to emit a warning in these cases ("Sun never rises!!"
+or "Sun never sets!!"). But some programmers may find this inconvenient.
+An alternate behaviour is to return special values reflecting the
+situation.
+
+So, if the C<polar> parameter is set to C<'warn'>, the module emits
+a warning. If the C<polar> parameter is set to C<'retval'>, the
+module emits no warning, but it returns either C<'day'> or C<'night'>.
+
+Example:
+
+ # Loosely based on Alex Gough's activities: scientist and Perl programmer, who spent a year
+ # in Halley Base in 2006. Let us suppose he arrived there on 15th January 2006.
+ my ($sunrise, $sunset) = sunrise( { year => 2006, month => 1, day => 15,
+ lon => -26.65, lat => -75.58, # Halley Base: 75°35'S 26°39'W
+ tz => 3, polar => 'retval' } );
+ if ($sunrise eq 'day') {
+ say "Alex Gough saw the midnight sun the first day he arrived at Halley Base";
+ }
+ elsif ($sunrise eq 'night') {
+ say "It would be days, maybe weeks, before the sun would rise.";
+ }
+ else {
+ say "Alex saw his first antarctic sunset at $sunset";
+ }
+
+This parameter is optional and it can be specified only by keyword.
+
+=item precise
+
+Choice between a precise algorithm and a simpler algorithm.
+The default value is 0, that is, the simpler algorithm.
+Any true value switches to the precise algorithm.
+
+The original method only gives an approximate value of the Sun's rise/set times.
+The error rarely exceeds one or two minutes, but at high latitudes, when the Midnight Sun
+soon will start or just has ended, the errors may be much larger. If you want higher accuracy,
+you must then use the precise algorithm. This feature is new as of version 0.7. Here is
+what I have tried to accomplish with this.
+
+a) Compute sunrise or sunset as always, with one exception: to convert LHA from degrees to hours,
+ divide by 15.04107 instead of 15.0 (this accounts for the difference between the solar day
+ and the sidereal day).
+
+b) Re-do the computation but compute the Sun's RA and Decl, and also GMST0, for the moment
+ of sunrise or sunset last computed.
+
+c) Iterate b) until the computed sunrise or sunset no longer changes significantly.
+ Usually 2 iterations are enough, in rare cases 3 or 4 iterations may be needed.
+
+This parameter is optional. It can be positional (#9).
+
+=back
+
+=head3 I<For Example>
+
+ ($sunrise, $sunset) = sunrise( 2001, 3, 10, 17.384, 98.625, -5, 0 );
+ ($sunrise, $sunset) = sunrise( 2002, 10, 14, -105.181, 41.324, -7, 1, -18);
+ ($sunrise, $sunset) = sunrise( 2002, 10, 14, -105.181, 41.324, -7, 1, -18, 1);
+
+=head2 B<sun_rise>, B<sun_set>
+
+ $sun_rise = sun_rise( { lon => $longitude, lat => $latitude,
+ alt => $altitude, upper_limb => $bool,
+ offset => $day_offset,
+ precise => $bool_precise, polar => $action } );
+ $sun_set = sun_set ( { lon => $longitude, lat => $latitude,
+ alt => $altitude, upper_limb => $bool,
+ offset => $day_offset,
+ precise => $bool_precise, polar => $action } );
+ $sun_rise = sun_rise( $longitude, $latitude );
+ $sun_rise = sun_rise( $longitude, $latitude, $alt );
+ $sun_rise = sun_rise( $longitude, $latitude, $alt, $day_offset );
+
+Returns the sun rise time (resp. the sun set time) for the given location
+and for today's date (as given by DateTime), plus or minus some offset in days.
+The first form use all parameters and transmit them by name. The second form
+uses today's date (from DateTime) and the default altitude. The third
+form adds specifying a custom altitude. The fourth form allows for specifying
+an integer day offset from today, either positive or negative.
+
+The parameters are the same as the parameters for C<sunrise>. There is an additional
+parameter, C<offset>, which allows using a date other than today: C<+1> for
+to-morrow, C<-7> for one week ago, etc.
+
+The arguments are:
+
+=over 4
+
+=item lon, lat
+
+The longitude and latitude of the place for which you want to compute the sunrise and sunset.
+They are given in decimal degrees. For example:
+
+ lon => -3.6, # 3° 36' W
+ lat => 37.17, # 37° 10' N
+
+ Eastern longitude is entered as a positive number
+ Western longitude is entered as a negative number
+ Northern latitude is entered as a positive number
+ Southern latitude is entered as a negative number
+
+Mandatory, can be positional (#1 and #2).
+
+=item alt
+
+Altitude of the sun, in decimal degrees. Usually a negative number,
+because the sun should be I<under> the mathematical horizon.
+But if there is a high mountain range sunward (that is, southward if you
+live in the Northern hemisphere), you may need to enter a positive altitude.
+
+This parameter is optional. Its default value is -0.833. It can be positional (#3).
+
+=item offset
+
+By default, C<sun_rise> and C<sun_set> use the current day. If you need another
+day, you give an offset relative to the current day. For example, C<+7> means
+next week, while C<-365> means last year.
+
+This parameter has nothing to do with timezones.
+
+Optional, 0 by default, can be positional (#4).
+
+=item time_zone
+
+Time Zone is the Olson name for a timezone. By default, the functions
+C<sun_rise> and C<sun_set> will try to use the C<local> timezone.
+
+This parameter is optional and it can be specified only by keyword.
+
+=item upper_limb
+
+If this parameter set to a true value (usually 1), the algorithm computes
+the sun apparent radius and takes it into account when computing the sun
+altitude. This parameter is useful only when the C<alt> parameter is set
+to C<0> or C<-0.583> degrees. When using C<-0.25> or C<-0.833> degrees,
+the sun radius is already taken into account. When computing twilights
+(C<-6> to C<-18>), the sun radius is irrelevant.
+
+Since the default value for the C<alt> parameter is -0.833, the
+default value for C<upper_limb> is 0.
+
+This parameter is optional and it can be specified only by keyword.
+
+=item polar
+
+When dealing with a polar location, there may be dates where there is
+a polar night (sun never rises) or a polar day. The default behaviour of
+the module is to emit a warning in these cases ("Sun never rises!!"
+or "Sun never sets!!"). But some programmers may find this inconvenient.
+An alternate behaviour is to return special values reflecting the
+situation.
+
+So, if the C<polar> parameter is set to C<'warn'>, the module emits
+a warning. If the C<polar> parameter is set to C<'retval'>, the
+module emits no warning, but it returns either C<'day'> or C<'night'>.
+
+This parameter is optional and it can be specified only by keyword.
+
+=item precise
+
+Choice between a precise algorithm and a simpler algorithm.
+The default value is 0, that is, the simpler algorithm.
+Any true value switches to the precise algorithm.
+
+For more documentation, see the corresponding parameter
+for the C<sunrise> function.
+
+This parameter is optional and it can be specified only by keyword.
+
+=back
+
+=head3 For Example
+
+ $sunrise = sun_rise( -105.181, 41.324 );
+ $sunrise = sun_rise( -105.181, 41.324, -15 );
+ $sunrise = sun_rise( -105.181, 41.324, -12, +3 );
+ $sunrise = sun_rise( -105.181, 41.324, undef, -12);
+
+=head2 Trigonometric functions using degrees
+
+Since the module use trigonometry with degrees, the corresponding functions
+are available to the module user, free of charge. Just mention the
+tag C<:trig> in the C<use> statement. These functions are:
+
+=over 4
+
+=item sind, cosd, tand
+
+The direct functions, that is, sine, cosine and tangent functions, respectively.
+Each one receives one parameter, in degrees, and returns the trigonometric value.
+
+=item asind, acosd, atand
+
+The reverse functions, that is, arc-sine, arc-cosine, and arc-tangent.
+Each one receives one parameter, the trigonometric value, and returns the corresponding
+angle in degrees.
+
+=item atan2d
+
+Arc-tangent. This function receives two parameters: the numerator and the denominator
+of a fraction equal to the tangent. Use this function instead of C<atand> when you
+are not sure the denominator is not zero. E.g.:
+
+ use Astro::Sunrise qw(:trig);
+ say atan2d(1, 2) # prints 26,5
+ say atan2d(1, 0) # prints 90, without triggering a "division by zero" error
+
+=item equal
+
+Not really a trigonometrical function, but still useful at some times. This function
+receives two floating values and an integer value. It compares the floating numbers,
+and returns "1" if their most significant digits are equal. The integer value
+specifies how many digits are kept. E.g.
+
+ say equal(22/7, 355/113, 3) # prints 1, because : 22/7 = 3.14285715286 rounded to 3.14
+ # 355/113 = 3.14159292035 rounded to 3.14
+ say equal(22/7, 355/113, 4) # prints 0, because : 22/7 = 3.14285715286 rounded to 3.143
+ # 355/113 = 3.14159292035 rounded to 3.142
+
+=back
+
+=head1 EXPORTS
+
+By default, the functions C<sunrise>, C<sun_rise> and C<sun_set> are exported.
+
+The constants C<DEFAULT>, C<CIVIL>, C<NAUTICAL>, C<AMATEUR> and C<ASTRONOMICAL> are
+exported on request with the tag C<:constants>.
+
+The functions C<sind>, C<cosd>, C<tand>, C<asind>, C<acosd>, C<atand>, C<atan2d> and C<equal>
+exported on request with the tag C<:trig>.
+
+=head1 DEPENDENCIES
+
+This module requires only core modules: L<POSIX>, L<Math::Trig> and L<Carp>.
+
+If you use the C<sun_rise> and C<sun_set> functions, you will need also L<DateTime>.
+
+=head1 AUTHOR
+
+Ron Hill
+rkhill@firstlight.net
+
+Co-maintainer: Jean Forget (JFORGET at cpan dot org)
+
+=head1 SPECIAL THANKS
+
+Robert Creager [Astro-Sunrise@LogicalChaos.org]
+for providing help with converting Paul's C code to Perl,
+for providing code for sun_rise, sun_set subs.
+Also adding options for different altitudes.
+
+Joshua Hoblitt [jhoblitt@ifa.hawaii.edu]
+for providing the patch to convert to DateTime.
+
+Chris Phillips for providing patch for conversion to
+local time.
+
+Brian D Foy for providing patch for constants :)
+
+Gabor Szabo for pointing POD mistakes.
+
+=head1 CREDITS
+
+=over 4
+
+=item Paul Schlyter, Stockholm, Sweden
+
+for his excellent web page on the subject.
+
+=item Rich Bowen (rbowen@rbowen.com)
+
+for suggestions.
+
+=item Adrian Blockley [adrian.blockley@environ.wa.gov.au]
+
+for finding a bug in the conversion to local time.
+
+=item Slaven Rezić
+
+for finding and fixing a bug with DST.
+
+=back
+
+Lightly verified against L<http://aa.usno.navy.mil/data/docs/RS_OneYear.html>
+
+In addition, checked to be compatible with a C implementation of Paul Schlyter's algorithm.
+
+=head1 COPYRIGHT and LICENSE
+
+=head2 Perl Module
+
+This program is distributed under the same terms as Perl 5.16.3:
+GNU Public License version 1 or later and Perl Artistic License
+
+You can find the text of the licenses in the F<LICENSE> file or at
+L<http://www.perlfoundation.org/artistic_license_1_0>
+and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+
+Here is the summary of GPL:
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software Foundation,
+Inc., L<http://www.fsf.org/>.
+
+=head2 Original C program
+
+Here is the copyright information provided by Paul Schlyter:
+
+Written as DAYLEN.C, 1989-08-16
+
+Modified to SUNRISET.C, 1992-12-01
+
+(c) Paul Schlyter, 1989, 1992
+
+Released to the public domain by Paul Schlyter, December 1992
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
+OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+perl(1).
+
+L<DateTime::Event::Sunrise>
+
+L<DateTime::Event::Jewish::Sunrise>
+
+=cut
@@ -1,8 +1,38 @@
-use strict;
-use Test;
-
-BEGIN {$| = 1; plan tests => 1 }
-use Astro::Sunrise;
-my $loaded = 1;
-ok($loaded);
-
+#!/usr/bin/perl
+# -*- encoding: utf-8; indent-tabs-mode: nil -*-
+#
+# Test script for Astro::Sunrise
+# Copyright (C) 2001, 2002, 2003, 2013 Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+use strict;
+use warnings;
+use Test::More;
+
+BEGIN {$| = 1; plan tests => 1 }
+use Astro::Sunrise;
+my $loaded = 1;
+ok($loaded);
+
@@ -1,199 +1,196 @@
-#!/usr/bin/perl
-use strict;
-use warnings;
-use POSIX qw(floor ceil);
-use Astro::Sunrise;
-use DateTime;
-use Test::More;
-
-my @data = load_data();
-plan(tests => 5 + 2 * @data); # I prefer having Perl counting my tests than myself
-
-use vars qw($long $lat $offset);
-
-my $test_year = '2003';
-my $test_month = '6';
-my $test_day = '21';
-
-
-for (@data) {
-/(\w+),\s+(\w+)\s+(\d+)\s+(\d+)\s+(\w)\s+(\d+)\s+(\d+)\s+(\w)\s+sunrise:\s+(\d+:\d+)\s+sunset:\s+(\d+:\d+)/;
- if ( $5 eq 'N' ) {
- $lat = sprintf( "%.3f", ( $3 + ( $4 / 60 ) ) );
-
- }
- elsif ( $5 eq 'S' ) {
- $lat = sprintf( "%.3f", -( $3 + ( $4 / 60 ) ) );
-
- }
-
- if ( $8 eq 'E' ) {
- $long = sprintf( "%.3f", $6 + ( $7 / 60 ) );
-
- }
- elsif ( $8 eq 'W' ) {
- $long = sprintf( "%.3f", -( $6 + ( $7 / 60 ) ) );
-
- }
-
- if ($long < 0 ) {
- $offset = ceil( $long / 15 );
- }elsif ($long > 0 ) {
- $offset = floor( $long /15 );
- }
-
- my ( $sunrise, $sunset ) =
- sunrise( $test_year, $test_month, $test_day, $long, $lat, $offset, 0 );
-
-
- is ($sunrise, $9, "Sunrise for $1, $2");
- is ($sunset , $10, "Sunset for $1, $2");
-
-}
-
-
-my $sunrise_1 = sun_rise( -118, 33 );
-my $sunrise_2 = sun_rise( -118, 33, -.833 );
-my $sunrise_3 = sun_rise( -118, 33, -.833, 0 );
-my $sunrise_4 = sun_rise( -118, 33, undef, 0 );
-
-ok( $sunrise_1 eq $sunrise_2 , "Test W/O Alt");
-ok( $sunrise_2 eq $sunrise_3 , "Test W/O offset");
-ok( $sunrise_3 eq $sunrise_4 , "Test setting Alt to undef");
-
-
-my $then = DateTime->new (
- year => 2000,
- month => 6,
- day => 20,
- time_zone =>'America/Los_Angeles',
- );
-my $offset = ( ($then->offset) /60 /60);
-
-my ($sunrise, $sunset) = sunrise($then->year, $then->mon, $then->mday,
- -118, 33, $offset, 0);
-is ($sunrise, '05:42', "Test DateTime sunrise interface");
-is ($sunset, '20:05', "Test DateTime sunset interface");
-
-
-
-sub load_data {
- return split "\n", <<'EOD';
-Aberdeen, Scotland 57 9 N 2 9 W sunrise: 03:09 sunset: 21:11
-Adelaide, Australia 34 55 S 138 36 E sunrise: 06:52 sunset: 16:43
-Algiers, Algeria 36 50 N 3 0 E sunrise: 04:28 sunset: 19:12
-Amsterdam, Netherlands 52 22 N 4 53 E sunrise: 03:16 sunset: 20:09
-Ankara, Turkey 39 55 N 32 55 E sunrise: 04:18 sunset: 19:22
-Asuncion, Paraguay 25 15 S 57 40 W sunrise: 07:34 sunset: 18:11
-Athens, Greece 37 58 N 23 43 E sunrise: 04:01 sunset: 18:52
-Auckland, New_Zealand 36 52 S 174 45 E sunrise: 06:32 sunset: 16:13
-Bangkok, Thailand 13 45 N 100 30 E sunrise: 04:50 sunset: 17:49
-Barcelona, Spain 41 23 N 2 9 E sunrise: 04:16 sunset: 19:30
-Beijing, China 39 55 N 116 25 E sunrise: 03:44 sunset: 18:48
-Belem, Brazil 1 28 S 48 29 W sunrise: 06:13 sunset: 18:18
-Belfast, Northern_Ireland 54 37 N 5 56 W sunrise: 03:44 sunset: 21:07
-Belgrade, Yugoslavia 44 52 N 20 32 E sunrise: 03:50 sunset: 19:29
-Berlin, Germany 52 30 N 13 25 E sunrise: 02:41 sunset: 19:35
-Birmingham, England 52 25 N 1 55 W sunrise: 03:43 sunset: 20:36
-Bogota, Colombia 4 32 N 74 15 W sunrise: 06:46 sunset: 19:11
-Bombay, India 19 0 N 72 48 E sunrise: 04:31 sunset: 17:50
-Bordeaux, France 44 50 N 0 31 W sunrise: 04:14 sunset: 19:53
-Bremen, Germany 53 5 N 8 49 E sunrise: 02:56 sunset: 19:57
-Brisbane, Australia 27 29 S 153 8 E sunrise: 06:36 sunset: 17:02
-Bristol, England 51 28 N 2 35 W sunrise: 03:51 sunset: 20:33
-Brussels, Belgium 50 52 N 4 22 E sunrise: 03:26 sunset: 20:02
-Bucharest, Romania 44 25 N 26 7 E sunrise: 03:29 sunset: 19:05
-Budapest, Hungary 47 30 N 19 5 E sunrise: 03:44 sunset: 19:46
-Buenos_Aires, Argentina 34 35 S 58 22 W sunrise: 07:59 sunset: 17:52
-Cairo, Egypt 30 2 N 31 21 E sunrise: 04:52 sunset: 19:00
-Calcutta, India 22 34 N 88 24 E sunrise: 04:21 sunset: 17:55
-Canton, China 23 7 N 113 15 E sunrise: 04:41 sunset: 18:17
-Cape_Town, South_Africa 33 55 S 18 22 E sunrise: 06:50 sunset: 16:46
-Caracas, Venezuela 10 28 N 67 2 W sunrise: 06:07 sunset: 18:53
-Cayenne, French_Guiana 4 49 N 52 18 W sunrise: 06:18 sunset: 18:44
-Chihuahua, Mexico 28 37 N 106 5 W sunrise: 05:06 sunset: 19:06
-Chongqing, China 29 46 N 106 34 E sunrise: 04:52 sunset: 18:58
-Copenhagen, Denmark 55 40 N 12 34 E sunrise: 02:23 sunset: 20:00
-Cordoba, Argentina 31 28 S 64 10 W sunrise: 07:14 sunset: 17:23
-Dakar, Senegal 14 40 N 17 28 W sunrise: 05:41 sunset: 18:43
-Darwin, Australia 12 28 S 130 51 E sunrise: 05:35 sunset: 17:01
-Djibouti, Djibouti 11 30 N 43 3 E sunrise: 04:44 sunset: 17:35
-Dublin, Ireland 53 20 N 6 15 W sunrise: 03:54 sunset: 20:59
-Durban, South_Africa 29 53 S 30 53 E sunrise: 06:50 sunset: 17:06
-Edinburgh, Scotland 55 55 N 3 10 W sunrise: 03:24 sunset: 21:05
-Frankfurt, Germany 50 7 N 8 41 E sunrise: 03:13 sunset: 19:41
-Georgetown, Guyana 6 45 N 58 15 W sunrise: 06:38 sunset: 19:11
-Glasgow, Scotland 55 50 N 4 15 W sunrise: 03:29 sunset: 21:09
-Guatemala_City, Guatemala 14 37 N 90 31 W sunrise: 05:33 sunset: 18:35
-Guayaquil, Ecuador 2 10 S 79 56 W sunrise: 06:20 sunset: 18:22
-Hamburg, Germany 53 33 N 10 2 E sunrise: 02:48 sunset: 19:55
-Havana, Cuba 23 8 N 82 23 W sunrise: 05:43 sunset: 19:19
-Helsinki, Finland 60 10 N 25 0 E sunrise: 01:50 sunset: 20:53
-Hobart, Tasmania 42 52 S 147 19 E sunrise: 06:40 sunset: 15:44
-Iquique, Chile 20 10 S 70 7 W sunrise: 07:14 sunset: 18:11
-Irkutsk, Russia 52 30 N 104 20 E sunrise: 02:37 sunset: 19:32
-Jakarta, Indonesia 6 16 S 106 48 E sunrise: 06:01 sunset: 17:48
-Johannesburg, South_Africa 26 12 S 28 4 E sunrise: 05:53 sunset: 16:26
-Kingston, Jamaica 17 59 N 76 49 W sunrise: 05:32 sunset: 18:46
-Kinshasa, Congo 4 18 S 15 17 E sunrise: 06:03 sunset: 17:58
-La_Paz, Bolivia 16 27 S 68 22 W sunrise: 07:00 sunset: 18:11
-Leeds, England 53 45 N 1 30 W sunrise: 03:33 sunset: 20:43
-Lima, Peru 12 0 S 77 2 W sunrise: 06:26 sunset: 17:54
-Lisbon, Portugal 38 44 N 9 9 W sunrise: 05:10 sunset: 20:06
-Liverpool, England 53 25 N 3 0 W sunrise: 03:41 sunset: 20:47
-London, England 51 32 N 0 5 W sunrise: 03:40 sunset: 20:24
-Lyons, France 45 45 N 4 50 E sunrise: 03:49 sunset: 19:36
-Madrid, Spain 40 26 N 3 42 W sunrise: 04:43 sunset: 19:50
-Manchester, England 53 30 N 2 15 W sunrise: 03:37 sunset: 20:44
-Manila, Philippines 14 35 N 120 57 E sunrise: 05:27 sunset: 18:29
-Marseilles, France 43 20 N 5 20 E sunrise: 03:57 sunset: 19:24
-Mazatlan, Mexico 23 12 N 106 25 W sunrise: 05:19 sunset: 18:56
-Mecca, Saudi_Arabia 21 29 N 39 45 E sunrise: 04:38 sunset: 18:07
-Melbourne, Australia 37 47 S 144 58 E sunrise: 06:34 sunset: 16:10
-Mexico_City, Mexico 19 26 N 99 7 W sunrise: 05:58 sunset: 19:19
-Milan, Italy 45 27 N 9 10 E sunrise: 03:33 sunset: 19:17
-Montevideo, Uruguay 34 53 S 56 10 W sunrise: 07:51 sunset: 17:42
-Moscow, Russia 55 45 N 37 36 E sunrise: 02:42 sunset: 20:21
-Munich, Germany 48 8 N 11 35 E sunrise: 03:11 sunset: 19:19
-Nagasaki, Japan 32 48 N 129 57 E sunrise: 04:11 sunset: 18:33
-Nagoya, Japan 35 7 N 136 56 E sunrise: 04:37 sunset: 19:11
-Nairobi, Kenya 1 25 S 36 55 E sunrise: 05:32 sunset: 17:36
-Nanjing_Nanking, China 32 3 N 118 53 E sunrise: 03:57 sunset: 18:15
-Naples, Italy 40 50 N 14 15 E sunrise: 03:30 sunset: 18:40
-Newcastle-on-Tyne, England 54 58 N 1 37 W sunrise: 03:25 sunset: 20:52
-Odessa, Ukraine 46 27 N 30 48 E sunrise: 04:02 sunset: 19:55
-Osaka, Japan 34 32 N 135 30 E sunrise: 04:44 sunset: 19:15
-Oslo, Norway 59 57 N 10 42 E sunrise: 01:50 sunset: 20:48
-Panama_City, Panama 8 58 N 79 32 W sunrise: 05:59 sunset: 18:40
-Paramaribo, Suriname 5 45 N 55 15 W sunrise: 06:28 sunset: 18:58
-Paris, France 48 48 N 2 20 E sunrise: 03:45 sunset: 20:00
-Perth, Australia 31 57 S 115 52 E sunrise: 06:15 sunset: 16:21
-Plymouth, England 50 25 N 4 5 W sunrise: 04:03 sunset: 20:33
-Port_Moresby, Papua_New_Guinea 9 25 S 147 8 E sunrise: 05:25 sunset: 17:01
-Prague, Czech_Republic 50 5 N 14 26 E sunrise: 02:50 sunset: 19:18
-Rangoon, Myanmar 16 50 N 96 0 E sunrise: 05:02 sunset: 18:13
-Reykjavik, Iceland 64 4 N 21 58 W sunrise: 01:50 sunset: 23:09
-Rio_de_Janeiro, Brazil 22 57 S 43 12 W sunrise: 07:32 sunset: 18:17
-Rome, Italy 41 54 N 12 27 E sunrise: 03:33 sunset: 18:50
-Salvador, Brazil 12 56 S 38 27 W sunrise: 06:53 sunset: 18:18
-Santiago, Chile 33 28 S 70 45 W sunrise: 07:45 sunset: 17:44
-St_Petersburg, Russia 59 56 N 30 18 E sunrise: 02:32 sunset: 21:29
-Sao_Paulo, Brazil 23 31 S 46 31 W sunrise: 06:46 sunset: 17:30
-Shanghai, China 31 10 N 121 28 E sunrise: 04:49 sunset: 19:02
-Singapore, Singapore 1 14 N 103 55 E sunrise: 04:59 sunset: 17:13
-Sofia, Bulgaria 42 40 N 23 20 E sunrise: 03:47 sunset: 19:10
-Stockholm, Sweden 59 17 N 18 3 E sunrise: 02:28 sunset: 21:11
-Sydney, Australia 34 0 S 151 0 E sunrise: 07:00 sunset: 16:56
-Tananarive, Madagascar 18 50 S 47 33 E sunrise: 06:20 sunset: 17:23
-Teheran, Iran 35 45 N 51 45 E sunrise: 04:16 sunset: 18:54
-Tokyo, Japan 35 40 N 139 45 E sunrise: 04:24 sunset: 19:01
-Tripoli, Libya 32 57 N 13 12 E sunrise: 03:58 sunset: 18:20
-Venice, Italy 45 26 N 12 20 E sunrise: 03:20 sunset: 19:04
-Veracruz, Mexico 19 10 N 96 10 W sunrise: 05:47 sunset: 19:06
-Vienna, Austria 48 14 N 16 20 E sunrise: 03:52 sunset: 20:01
-Vladivostok, Russia 43 10 N 132 0 E sunrise: 03:30 sunset: 18:57
-Warsaw, Poland 52 14 N 21 0 E sunrise: 03:12 sunset: 20:03
-Wellington, New_Zealand 41 17 S 174 47 E sunrise: 06:45 sunset: 16:00
-Zurich, Switzerland 47 21 N 8 31 E sunrise: 03:27 sunset: 19:28
-EOD
-}
+#!/usr/bin/perl
+# -*- encoding: utf-8; indent-tabs-mode: nil -*-
+#
+# Test script for Astro::Sunrise
+# Copyright (C) 2001, 2002, 2003, 2013, 2015 Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+use strict;
+use warnings;
+use POSIX qw(floor ceil);
+use Astro::Sunrise;
+use Test::More;
+
+my @data = load_data();
+plan(tests => 2 * @data); # I prefer having Perl counting my tests than myself
+
+use vars qw($long $lat $offset);
+
+my $test_year = '2003';
+my $test_month = '6';
+my $test_day = '21';
+
+
+for (@data) {
+/(\w+),\s+(\w+)\s+(\d+)\s+(\d+)\s+(\w)\s+(\d+)\s+(\d+)\s+(\w)\s+sunrise:\s+(\d+:\d+)\s+sunset:\s+(\d+:\d+)/;
+ if ( $5 eq 'N' ) {
+ $lat = sprintf( "%.3f", ( $3 + ( $4 / 60 ) ) );
+ }
+ elsif ( $5 eq 'S' ) {
+ $lat = sprintf( "%.3f", -( $3 + ( $4 / 60 ) ) );
+ }
+
+ if ( $8 eq 'E' ) {
+ $long = sprintf( "%.3f", $6 + ( $7 / 60 ) );
+ }
+ elsif ( $8 eq 'W' ) {
+ $long = sprintf( "%.3f", -( $6 + ( $7 / 60 ) ) );
+ }
+
+ if ($long < 0) {
+ $offset = ceil( $long / 15 );
+ }
+ elsif ($long > 0) {
+ $offset = floor( $long /15 );
+ }
+
+ my ( $sunrise, $sunset ) =
+ sunrise( $test_year, $test_month, $test_day, $long, $lat, $offset, 0 );
+
+ is ($sunrise, $9, "Sunrise for $1, $2");
+ is ($sunset , $10, "Sunset for $1, $2");
+
+}
+
+sub load_data {
+ return split "\n", <<'EOD';
+Aberdeen, Scotland 57 9 N 2 9 W sunrise: 03:12 sunset: 21:08
+Adelaide, Australia 34 55 S 138 36 E sunrise: 06:53 sunset: 16:41
+Algiers, Algeria 36 50 N 3 0 E sunrise: 04:29 sunset: 19:10
+Amsterdam, Netherlands 52 22 N 4 53 E sunrise: 03:18 sunset: 20:06
+Ankara, Turkey 39 55 N 32 55 E sunrise: 04:20 sunset: 19:20
+Asuncion, Paraguay 25 15 S 57 40 W sunrise: 07:35 sunset: 18:09
+Athens, Greece 37 58 N 23 43 E sunrise: 04:03 sunset: 18:51
+Auckland, New_Zealand 36 52 S 174 45 E sunrise: 06:34 sunset: 16:11
+Bangkok, Thailand 13 45 N 100 30 E sunrise: 04:51 sunset: 17:48
+Barcelona, Spain 41 23 N 2 9 E sunrise: 04:18 sunset: 19:28
+Beijing, China 39 55 N 116 25 E sunrise: 03:46 sunset: 18:46
+Belem, Brazil 1 28 S 48 29 W sunrise: 06:15 sunset: 18:17
+Belfast, Northern_Ireland 54 37 N 5 56 W sunrise: 03:47 sunset: 21:04
+Belgrade, Yugoslavia 44 52 N 20 32 E sunrise: 03:52 sunset: 19:28
+Berlin, Germany 52 30 N 13 25 E sunrise: 02:43 sunset: 19:33
+Birmingham, England 52 25 N 1 55 W sunrise: 03:45 sunset: 20:34
+Bogota, Colombia 4 32 N 74 15 W sunrise: 06:47 sunset: 19:10
+Bombay, India 19 0 N 72 48 E sunrise: 04:32 sunset: 17:49
+Bordeaux, France 44 50 N 0 31 W sunrise: 04:16 sunset: 19:52
+Bremen, Germany 53 5 N 8 49 E sunrise: 02:58 sunset: 19:55
+Brisbane, Australia 27 29 S 153 8 E sunrise: 06:37 sunset: 17:01
+Bristol, England 51 28 N 2 35 W sunrise: 03:53 sunset: 20:31
+Brussels, Belgium 50 52 N 4 22 E sunrise: 03:29 sunset: 20:00
+Bucharest, Romania 44 25 N 26 7 E sunrise: 03:31 sunset: 19:03
+Budapest, Hungary 47 30 N 19 5 E sunrise: 03:46 sunset: 19:44
+Buenos_Aires, Argentina 34 35 S 58 22 W sunrise: 08:00 sunset: 17:50
+Cairo, Egypt 30 2 N 31 21 E sunrise: 04:54 sunset: 18:59
+Calcutta, India 22 34 N 88 24 E sunrise: 04:23 sunset: 17:54
+Canton, China 23 7 N 113 15 E sunrise: 04:42 sunset: 18:15
+Cape_Town, South_Africa 33 55 S 18 22 E sunrise: 06:51 sunset: 16:45
+Caracas, Venezuela 10 28 N 67 2 W sunrise: 06:08 sunset: 18:52
+Cayenne, French_Guiana 4 49 N 52 18 W sunrise: 06:19 sunset: 18:43
+Chihuahua, Mexico 28 37 N 106 5 W sunrise: 05:07 sunset: 19:05
+Chongqing, China 29 46 N 106 34 E sunrise: 04:54 sunset: 18:57
+Copenhagen, Denmark 55 40 N 12 34 E sunrise: 02:25 sunset: 19:57
+Cordoba, Argentina 31 28 S 64 10 W sunrise: 07:16 sunset: 17:21
+Dakar, Senegal 14 40 N 17 28 W sunrise: 05:42 sunset: 18:41
+Darwin, Australia 12 28 S 130 51 E sunrise: 05:36 sunset: 17:00
+Djibouti, Djibouti 11 30 N 43 3 E sunrise: 04:45 sunset: 17:33
+Dublin, Ireland 53 20 N 6 15 W sunrise: 03:57 sunset: 20:57
+Durban, South_Africa 29 53 S 30 53 E sunrise: 06:52 sunset: 17:05
+Edinburgh, Scotland 55 55 N 3 10 W sunrise: 03:26 sunset: 21:02
+Frankfurt, Germany 50 7 N 8 41 E sunrise: 03:15 sunset: 19:39
+Georgetown, Guyana 6 45 N 58 15 W sunrise: 06:39 sunset: 19:10
+Glasgow, Scotland 55 50 N 4 15 W sunrise: 03:31 sunset: 21:06
+Guatemala_City, Guatemala 14 37 N 90 31 W sunrise: 05:34 sunset: 18:34
+Guayaquil, Ecuador 2 10 S 79 56 W sunrise: 06:22 sunset: 18:21
+Hamburg, Germany 53 33 N 10 2 E sunrise: 02:50 sunset: 19:53
+Havana, Cuba 23 8 N 82 23 W sunrise: 05:45 sunset: 19:18
+Helsinki, Finland 60 10 N 25 0 E sunrise: 01:54 sunset: 20:50
+Hobart, Tasmania 42 52 S 147 19 E sunrise: 06:42 sunset: 15:43
+Iquique, Chile 20 10 S 70 7 W sunrise: 07:15 sunset: 18:09
+Irkutsk, Russia 52 30 N 104 20 E sunrise: 02:39 sunset: 19:29
+Jakarta, Indonesia 6 16 S 106 48 E sunrise: 06:02 sunset: 17:47
+Johannesburg, South_Africa 26 12 S 28 4 E sunrise: 05:55 sunset: 16:24
+Kingston, Jamaica 17 59 N 76 49 W sunrise: 05:33 sunset: 18:45
+Kinshasa, Congo 4 18 S 15 17 E sunrise: 06:04 sunset: 17:57
+La_Paz, Bolivia 16 27 S 68 22 W sunrise: 07:01 sunset: 18:10
+Leeds, England 53 45 N 1 30 W sunrise: 03:35 sunset: 20:40
+Lima, Peru 12 0 S 77 2 W sunrise: 06:27 sunset: 17:52
+Lisbon, Portugal 38 44 N 9 9 W sunrise: 05:12 sunset: 20:05
+Liverpool, England 53 25 N 3 0 W sunrise: 03:43 sunset: 20:44
+London, England 51 32 N 0 5 W sunrise: 03:43 sunset: 20:21
+Lyons, France 45 45 N 4 50 E sunrise: 03:51 sunset: 19:34
+Madrid, Spain 40 26 N 3 42 W sunrise: 04:45 sunset: 19:48
+Manchester, England 53 30 N 2 15 W sunrise: 03:40 sunset: 20:42
+Manila, Philippines 14 35 N 120 57 E sunrise: 05:28 sunset: 18:27
+Marseilles, France 43 20 N 5 20 E sunrise: 03:58 sunset: 19:22
+Mazatlan, Mexico 23 12 N 106 25 W sunrise: 05:21 sunset: 18:54
+Mecca, Saudi_Arabia 21 29 N 39 45 E sunrise: 04:39 sunset: 18:06
+Melbourne, Australia 37 47 S 144 58 E sunrise: 06:35 sunset: 16:08
+Mexico_City, Mexico 19 26 N 99 7 W sunrise: 05:59 sunset: 19:17
+Milan, Italy 45 27 N 9 10 E sunrise: 03:35 sunset: 19:15
+Montevideo, Uruguay 34 53 S 56 10 W sunrise: 07:52 sunset: 17:41
+Moscow, Russia 55 45 N 37 36 E sunrise: 02:45 sunset: 20:18
+Munich, Germany 48 8 N 11 35 E sunrise: 03:13 sunset: 19:17
+Nagasaki, Japan 32 48 N 129 57 E sunrise: 04:12 sunset: 18:31
+Nagoya, Japan 35 7 N 136 56 E sunrise: 04:38 sunset: 19:10
+Nairobi, Kenya 1 25 S 36 55 E sunrise: 05:33 sunset: 17:35
+Nanjing_Nanking, China 32 3 N 118 53 E sunrise: 03:59 sunset: 18:14
+Naples, Italy 40 50 N 14 15 E sunrise: 03:31 sunset: 18:38
+Newcastle-on-Tyne, England 54 58 N 1 37 W sunrise: 03:27 sunset: 20:49
+Odessa, Ukraine 46 27 N 30 48 E sunrise: 04:04 sunset: 19:53
+Osaka, Japan 34 32 N 135 30 E sunrise: 04:46 sunset: 19:14
+Oslo, Norway 59 57 N 10 42 E sunrise: 01:53 sunset: 20:44
+Panama_City, Panama 8 58 N 79 32 W sunrise: 06:00 sunset: 18:39
+Paramaribo, Suriname 5 45 N 55 15 W sunrise: 06:29 sunset: 18:56
+Paris, France 48 48 N 2 20 E sunrise: 03:47 sunset: 19:57
+Perth, Australia 31 57 S 115 52 E sunrise: 06:16 sunset: 16:20
+Plymouth, England 50 25 N 4 5 W sunrise: 04:05 sunset: 20:31
+Port_Moresby, Papua_New_Guinea 9 25 S 147 8 E sunrise: 05:26 sunset: 17:00
+Prague, Czech_Republic 50 5 N 14 26 E sunrise: 02:52 sunset: 19:15
+Rangoon, Myanmar 16 50 N 96 0 E sunrise: 05:04 sunset: 18:12
+Reykjavik, Iceland 64 4 N 21 58 W sunrise: 01:57 sunset: 23:02
+Rio_de_Janeiro, Brazil 22 57 S 43 12 W sunrise: 07:33 sunset: 18:16
+Rome, Italy 41 54 N 12 27 E sunrise: 03:35 sunset: 18:49
+Salvador, Brazil 12 56 S 38 27 W sunrise: 06:55 sunset: 18:16
+Santiago, Chile 33 28 S 70 45 W sunrise: 07:47 sunset: 17:43
+St_Petersburg, Russia 59 56 N 30 18 E sunrise: 02:35 sunset: 21:26
+Sao_Paulo, Brazil 23 31 S 46 31 W sunrise: 06:47 sunset: 17:28
+Shanghai, China 31 10 N 121 28 E sunrise: 04:51 sunset: 19:01
+Singapore, Singapore 1 14 N 103 55 E sunrise: 05:00 sunset: 17:12
+Sofia, Bulgaria 42 40 N 23 20 E sunrise: 03:49 sunset: 19:08
+Stockholm, Sweden 59 17 N 18 3 E sunrise: 02:31 sunset: 21:08
+Sydney, Australia 34 0 S 151 0 E sunrise: 07:01 sunset: 16:54
+Tananarive, Madagascar 18 50 S 47 33 E sunrise: 06:22 sunset: 17:21
+Teheran, Iran 35 45 N 51 45 E sunrise: 04:17 sunset: 18:52
+Tokyo, Japan 35 40 N 139 45 E sunrise: 04:25 sunset: 19:00
+Tripoli, Libya 32 57 N 13 12 E sunrise: 03:59 sunset: 18:19
+Venice, Italy 45 26 N 12 20 E sunrise: 03:22 sunset: 19:03
+Veracruz, Mexico 19 10 N 96 10 W sunrise: 05:48 sunset: 19:05
+Vienna, Austria 48 14 N 16 20 E sunrise: 03:54 sunset: 19:59
+Vladivostok, Russia 43 10 N 132 0 E sunrise: 03:32 sunset: 18:55
+Warsaw, Poland 52 14 N 21 0 E sunrise: 03:14 sunset: 20:01
+Wellington, New_Zealand 41 17 S 174 47 E sunrise: 06:47 sunset: 15:58
+Zurich, Switzerland 47 21 N 8 31 E sunrise: 03:29 sunset: 19:26
+EOD
+}
@@ -1,13 +1,43 @@
-use strict;
-use Test;
-use Astro::Sunrise qw(:constants);
-
-BEGIN { plan tests => 6 }
-
-ok( CIVIL, -6 );
-
-ok( CIVIL, Astro::Sunrise::CIVIL );
-ok( AMATEUR, Astro::Sunrise::AMATEUR );
-ok( ASTRONOMICAL, Astro::Sunrise::ASTRONOMICAL );
-ok( DEFAULT, Astro::Sunrise::DEFAULT );
-ok( NAUTICAL, Astro::Sunrise::NAUTICAL );
\ No newline at end of file
+#!/usr/bin/perl
+# -*- encoding: utf-8; indent-tabs-mode: nil -*-
+#
+# Test script for Astro::Sunrise
+# Copyright (C) 2003, 2013 Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+use strict;
+use warnings;
+use Test::More;
+use Astro::Sunrise qw(:constants);
+
+BEGIN { plan tests => 6 }
+
+is( CIVIL, -6 );
+
+is( CIVIL, Astro::Sunrise::CIVIL );
+is( AMATEUR, Astro::Sunrise::AMATEUR );
+is( ASTRONOMICAL, Astro::Sunrise::ASTRONOMICAL );
+is( DEFAULT, Astro::Sunrise::DEFAULT );
+is( NAUTICAL, Astro::Sunrise::NAUTICAL );
@@ -0,0 +1,76 @@
+#!/usr/bin/perl -w
+# -*- perl -*-
+#
+# Test script for Astro::Sunrise
+# Author: Slaven Rezic
+# Copyright (C) 2015 Slaven Rezic, Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+
+use strict;
+use warnings;
+use Test::More;
+
+BEGIN {
+ eval "use DateTime;";
+ if ($@) {
+ plan skip_all => "DateTime needed";
+ exit;
+ }
+ eval "use Time::Fake;";
+ if ($@) {
+ plan skip_all => "Time::Fake needed";
+ exit;
+ }
+ if ($^O =~ /MSWin/i) {
+ plan skip_all => "Unix-like forking needed";
+ exit;
+ }
+}
+
+my @tests = (
+ [1288545834, 'sun_rise', '07:00'],
+ [1288545834, 'sun_set', '16:39'],
+
+ [1269738800, 'sun_rise', '06:50'],
+ [1269738800, 'sun_set', '19:32'],
+ );
+
+plan tests => scalar @tests;
+
+for my $test (@tests) {
+ my($epoch, $func, $expected) = @$test;
+ my @cmd = ($^X, "-Mblib",
+ "-MTime::Fake=$epoch",
+ "-MAstro::Sunrise",
+ "-e", "print $func({ lon => 13.5, lat => 52.5, time_zone => 'Europe/Berlin' })");
+ open my $fh, "-|", @cmd or die $!;
+ local $/;
+ my $res = <$fh>;
+ close $fh or die "Failure while running @cmd: $!";
+ is $res, $expected, "Check for $func at $epoch";
+}
+
+__END__
@@ -0,0 +1,434 @@
+#!/usr/bin/perl
+# -*- encoding: utf-8; indent-tabs-mode: nil -*-
+#
+# Test script for Astro::Sunrise
+# Copyright (C) 2015 Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+use strict;
+use warnings;
+use POSIX qw(floor ceil);
+use Astro::Sunrise;
+use Test::More;
+
+my @data = load_data();
+plan(tests => 2 * @data); # I prefer having Perl counting my tests than myself
+
+my ($long, $lat, $offset);
+my $fudge = 0; # in minutes
+
+for (@data) {
+ my ($yyyy, $mm, $dd, $loc, $lat_d, $lat_m, $lat_x, $lon_d, $lon_m, $lon_x, $alt, $upper_limb, $expect_r, $expect_s)
+ = $_ =~ /(\d+)\s+(\d+)\s+(\d+) # date in YYYY MM DD format $1 $2 $3
+ \s+(\w+) # location $4
+ \s+(\d+)\s+(\d+)\s+(\w) # latitude $5 $6 $7
+ \s+(\d+)\s+(\d+)\s+(\w) # longitude $8 $9 $10
+ \s+(\S+) # altitude $11
+ \s+(\d) # upper limb $12
+ \s+sunrise:\s+(\d+:\d+) # sunrise $13
+ \s+sunset:\s+(\d+:\d+)/x; # sunset $14
+ if ( $lat_x eq 'N' ) {
+ $lat = sprintf( "%.3f", ( $lat_d + ( $lat_m / 60 ) ) );
+ }
+ elsif ( $lat_x eq 'S' ) {
+ $lat = sprintf( "%.3f", -( $lat_d + ( $lat_m / 60 ) ) );
+ }
+
+ if ( $lon_x eq 'E' ) {
+ $long = sprintf( "%.3f", $lon_d + ( $lon_m / 60 ) );
+ }
+ elsif ( $lon_x eq 'W' ) {
+ $long = sprintf( "%.3f", -( $lon_d + ( $lon_m / 60 ) ) );
+ }
+
+ if ($long < 0) {
+ $offset = ceil( $long / 15 );
+ }
+ elsif ($long > 0) {
+ $offset = floor( $long /15 );
+ }
+ else {
+ $offset = 0;
+ }
+
+ my ( $sunrise, $sunset ) = sunrise( { year => $yyyy, month => $mm, day => $dd,
+ lon => $long, lat => $lat, tz => $offset,
+ alt => $alt, upper_limb => $upper_limb } );
+
+ my $exp_h = fudge_h($expect_r, $fudge);
+ my $exp_l = fudge_l($expect_r, $fudge);
+ ok ($sunrise ge $exp_l && $sunrise le $exp_h
+ , "Sunrise for $loc $yyyy-$mm-$dd $alt $upper_limb $exp_l $sunrise $exp_h");
+ $exp_h = fudge_h($expect_s, $fudge);
+ $exp_l = fudge_l($expect_s, $fudge);
+ ok ($sunset ge $exp_l && $sunset le $exp_h
+ , "Sunset for $loc $yyyy-$mm-$dd $alt $upper_limb $exp_l $sunset $exp_h");
+
+}
+
+sub fudge_h {
+ my ($exp, $fudge) = @_;
+ my ($hh, $mn) = $exp =~ /^(\d\d):(\d\d)$/;
+ $mn += $fudge;
+ if ($mn > 59) {
+ $hh ++;
+ $mn -= 60;
+ }
+ if ($hh > 23) {
+ $hh -= 24;
+ }
+ elsif ($hh < 0) {
+ $hh += 24;
+ }
+ return sprintf("%02d:%02d", $hh, $mn);
+}
+
+sub fudge_l {
+ my ($exp, $fudge) = @_;
+ my ($hh, $mn) = $exp =~ /^(\d\d):(\d\d)$/;
+ $mn -= $fudge;
+ if ($mn < 0) {
+ $hh --;
+ $mn += 60;
+ }
+ if ($hh > 23) {
+ $hh -= 24;
+ }
+ elsif ($hh < 0) {
+ $hh += 24;
+ }
+ return sprintf("%02d:%02d", $hh, $mn);
+}
+
+#
+# The data below have been prepared by a C program which includes
+# Paul Schlyter's code. Therefore, what is tested is the compatibility
+# of the Perl code with the C code.
+#
+# See how this C program is generated in
+# https://github.com/jforget/Astro-Sunrise/blob/master/util/mktest-04a
+#
+# Why those locations?
+# Greenwich because it is located on the eponymous prime meridian
+# Reykjavik, because it is close to the Northern Arctic Circle, so it can be used to check polar night and midnight sun
+# Quito because it is near the prime parallel, better known as "equator"
+# El Hierro, because it is located on a former prime meridian
+#
+# Warning: as you can see, the computation of sunrise and sunset is called with an altitude -0.833
+# and with upper_limb = 1. This is silly, because that means that the radius is accounted
+# twice instead of just once. But the purpose of this programme is just to check
+# that the Perl implementation of the algorithm is compatible with the C implementation.
+sub load_data {
+ return split "\n", <<'EOD';
+2013 1 1 Greenwich 51 28 N 0 0 E 10 0 sunrise: 09:50 sunset: 14:17
+2013 1 1 Greenwich 51 28 N 0 0 E 10 1 sunrise: 09:47 sunset: 14:21
+2013 1 1 Greenwich 51 28 N 0 0 E 0 0 sunrise: 08:12 sunset: 15:55
+2013 1 1 Greenwich 51 28 N 0 0 E 0 1 sunrise: 08:10 sunset: 15:57
+2013 1 1 Greenwich 51 28 N 0 0 E -0.583 0 sunrise: 08:07 sunset: 16:00
+2013 1 1 Greenwich 51 28 N 0 0 E -0.583 1 sunrise: 08:05 sunset: 16:02
+2013 1 1 Greenwich 51 28 N 0 0 E -0.833 0 sunrise: 08:05 sunset: 16:02
+2013 1 1 Greenwich 51 28 N 0 0 E -0.833 1 sunrise: 08:03 sunset: 16:04
+2013 1 1 Greenwich 51 28 N 0 0 E -12 0 sunrise: 06:43 sunset: 17:25
+2013 1 1 Greenwich 51 28 N 0 0 E -12 1 sunrise: 06:41 sunset: 17:26
+2013 1 1 Greenwich 51 28 N 0 0 E -18 0 sunrise: 06:02 sunset: 18:05
+2013 1 1 Greenwich 51 28 N 0 0 E -18 1 sunrise: 06:00 sunset: 18:07
+2013 1 1 Reykjavik 64 4 N 21 58 W 10 0 sunrise: 12:32 sunset: 12:32 polar night or midnight sun
+2013 1 1 Reykjavik 64 4 N 21 58 W 10 1 sunrise: 12:32 sunset: 12:32 polar night or midnight sun
+2013 1 1 Reykjavik 64 4 N 21 58 W 0 0 sunrise: 10:34 sunset: 14:29
+2013 1 1 Reykjavik 64 4 N 21 58 W 0 1 sunrise: 10:29 sunset: 14:35
+2013 1 1 Reykjavik 64 4 N 21 58 W -0.583 0 sunrise: 10:23 sunset: 14:41
+2013 1 1 Reykjavik 64 4 N 21 58 W -0.583 1 sunrise: 10:18 sunset: 14:46
+2013 1 1 Reykjavik 64 4 N 21 58 W -0.833 0 sunrise: 10:18 sunset: 14:45
+2013 1 1 Reykjavik 64 4 N 21 58 W -0.833 1 sunrise: 10:13 sunset: 14:50
+2013 1 1 Reykjavik 64 4 N 21 58 W -12 0 sunrise: 07:55 sunset: 17:08
+2013 1 1 Reykjavik 64 4 N 21 58 W -12 1 sunrise: 07:52 sunset: 17:11
+2013 1 1 Reykjavik 64 4 N 21 58 W -18 0 sunrise: 06:55 sunset: 18:08
+2013 1 1 Reykjavik 64 4 N 21 58 W -18 1 sunrise: 06:53 sunset: 18:10
+2013 1 1 Quito 0 15 S 78 35 W 10 0 sunrise: 07:01 sunset: 17:35
+2013 1 1 Quito 0 15 S 78 35 W 10 1 sunrise: 07:00 sunset: 17:36
+2013 1 1 Quito 0 15 S 78 35 W 0 0 sunrise: 06:18 sunset: 18:19
+2013 1 1 Quito 0 15 S 78 35 W 0 1 sunrise: 06:17 sunset: 18:20
+2013 1 1 Quito 0 15 S 78 35 W -0.583 0 sunrise: 06:15 sunset: 18:21
+2013 1 1 Quito 0 15 S 78 35 W -0.583 1 sunrise: 06:14 sunset: 18:22
+2013 1 1 Quito 0 15 S 78 35 W -0.833 0 sunrise: 06:14 sunset: 18:22
+2013 1 1 Quito 0 15 S 78 35 W -0.833 1 sunrise: 06:13 sunset: 18:23
+2013 1 1 Quito 0 15 S 78 35 W -12 0 sunrise: 05:25 sunset: 19:11
+2013 1 1 Quito 0 15 S 78 35 W -12 1 sunrise: 05:24 sunset: 19:12
+2013 1 1 Quito 0 15 S 78 35 W -18 0 sunrise: 04:59 sunset: 19:37
+2013 1 1 Quito 0 15 S 78 35 W -18 1 sunrise: 04:58 sunset: 19:38
+2013 1 1 El_Hierro 27 44 N 18 3 W 10 0 sunrise: 07:59 sunset: 16:33
+2013 1 1 El_Hierro 27 44 N 18 3 W 10 1 sunrise: 07:58 sunset: 16:34
+2013 1 1 El_Hierro 27 44 N 18 3 W 0 0 sunrise: 07:07 sunset: 17:24
+2013 1 1 El_Hierro 27 44 N 18 3 W 0 1 sunrise: 07:06 sunset: 17:26
+2013 1 1 El_Hierro 27 44 N 18 3 W -0.583 0 sunrise: 07:04 sunset: 17:27
+2013 1 1 El_Hierro 27 44 N 18 3 W -0.583 1 sunrise: 07:03 sunset: 17:29
+2013 1 1 El_Hierro 27 44 N 18 3 W -0.833 0 sunrise: 07:03 sunset: 17:29
+2013 1 1 El_Hierro 27 44 N 18 3 W -0.833 1 sunrise: 07:02 sunset: 17:30
+2013 1 1 El_Hierro 27 44 N 18 3 W -12 0 sunrise: 06:08 sunset: 18:23
+2013 1 1 El_Hierro 27 44 N 18 3 W -12 1 sunrise: 06:07 sunset: 18:25
+2013 1 1 El_Hierro 27 44 N 18 3 W -18 0 sunrise: 05:40 sunset: 18:52
+2013 1 1 El_Hierro 27 44 N 18 3 W -18 1 sunrise: 05:39 sunset: 18:53
+2013 3 21 Greenwich 51 28 N 0 0 E 10 0 sunrise: 07:10 sunset: 17:05
+2013 3 21 Greenwich 51 28 N 0 0 E 10 1 sunrise: 07:08 sunset: 17:06
+2013 3 21 Greenwich 51 28 N 0 0 E 0 0 sunrise: 06:05 sunset: 18:09
+2013 3 21 Greenwich 51 28 N 0 0 E 0 1 sunrise: 06:03 sunset: 18:11
+2013 3 21 Greenwich 51 28 N 0 0 E -0.583 0 sunrise: 06:01 sunset: 18:13
+2013 3 21 Greenwich 51 28 N 0 0 E -0.583 1 sunrise: 06:00 sunset: 18:15
+2013 3 21 Greenwich 51 28 N 0 0 E -0.833 0 sunrise: 06:00 sunset: 18:15
+2013 3 21 Greenwich 51 28 N 0 0 E -0.833 1 sunrise: 05:58 sunset: 18:16
+2013 3 21 Greenwich 51 28 N 0 0 E -12 0 sunrise: 04:47 sunset: 19:27
+2013 3 21 Greenwich 51 28 N 0 0 E -12 1 sunrise: 04:45 sunset: 19:29
+2013 3 21 Greenwich 51 28 N 0 0 E -18 0 sunrise: 04:06 sunset: 20:08
+2013 3 21 Greenwich 51 28 N 0 0 E -18 1 sunrise: 04:04 sunset: 20:10
+2013 3 21 Reykjavik 64 4 N 21 58 W 10 0 sunrise: 08:05 sunset: 17:05
+2013 3 21 Reykjavik 64 4 N 21 58 W 10 1 sunrise: 08:02 sunset: 17:08
+2013 3 21 Reykjavik 64 4 N 21 58 W 0 0 sunrise: 06:31 sunset: 18:39
+2013 3 21 Reykjavik 64 4 N 21 58 W 0 1 sunrise: 06:29 sunset: 18:41
+2013 3 21 Reykjavik 64 4 N 21 58 W -0.583 0 sunrise: 06:26 sunset: 18:44
+2013 3 21 Reykjavik 64 4 N 21 58 W -0.583 1 sunrise: 06:24 sunset: 18:46
+2013 3 21 Reykjavik 64 4 N 21 58 W -0.833 0 sunrise: 06:24 sunset: 18:46
+2013 3 21 Reykjavik 64 4 N 21 58 W -0.833 1 sunrise: 06:21 sunset: 18:49
+2013 3 21 Reykjavik 64 4 N 21 58 W -12 0 sunrise: 04:37 sunset: 20:33
+2013 3 21 Reykjavik 64 4 N 21 58 W -12 1 sunrise: 04:35 sunset: 20:35
+2013 3 21 Reykjavik 64 4 N 21 58 W -18 0 sunrise: 03:30 sunset: 21:40
+2013 3 21 Reykjavik 64 4 N 21 58 W -18 1 sunrise: 03:27 sunset: 21:43
+2013 3 21 Quito 0 15 S 78 35 W 10 0 sunrise: 07:01 sunset: 17:41
+2013 3 21 Quito 0 15 S 78 35 W 10 1 sunrise: 07:00 sunset: 17:42
+2013 3 21 Quito 0 15 S 78 35 W 0 0 sunrise: 06:21 sunset: 18:21
+2013 3 21 Quito 0 15 S 78 35 W 0 1 sunrise: 06:20 sunset: 18:22
+2013 3 21 Quito 0 15 S 78 35 W -0.583 0 sunrise: 06:19 sunset: 18:24
+2013 3 21 Quito 0 15 S 78 35 W -0.583 1 sunrise: 06:18 sunset: 18:25
+2013 3 21 Quito 0 15 S 78 35 W -0.833 0 sunrise: 06:18 sunset: 18:25
+2013 3 21 Quito 0 15 S 78 35 W -0.833 1 sunrise: 06:17 sunset: 18:26
+2013 3 21 Quito 0 15 S 78 35 W -12 0 sunrise: 05:33 sunset: 19:09
+2013 3 21 Quito 0 15 S 78 35 W -12 1 sunrise: 05:32 sunset: 19:10
+2013 3 21 Quito 0 15 S 78 35 W -18 0 sunrise: 05:09 sunset: 19:33
+2013 3 21 Quito 0 15 S 78 35 W -18 1 sunrise: 05:08 sunset: 19:34
+2013 3 21 El_Hierro 27 44 N 18 3 W 10 0 sunrise: 07:04 sunset: 17:35
+2013 3 21 El_Hierro 27 44 N 18 3 W 10 1 sunrise: 07:02 sunset: 17:36
+2013 3 21 El_Hierro 27 44 N 18 3 W 0 0 sunrise: 06:18 sunset: 18:20
+2013 3 21 El_Hierro 27 44 N 18 3 W 0 1 sunrise: 06:17 sunset: 18:21
+2013 3 21 El_Hierro 27 44 N 18 3 W -0.583 0 sunrise: 06:16 sunset: 18:23
+2013 3 21 El_Hierro 27 44 N 18 3 W -0.583 1 sunrise: 06:15 sunset: 18:24
+2013 3 21 El_Hierro 27 44 N 18 3 W -0.833 0 sunrise: 06:15 sunset: 18:24
+2013 3 21 El_Hierro 27 44 N 18 3 W -0.833 1 sunrise: 06:13 sunset: 18:25
+2013 3 21 El_Hierro 27 44 N 18 3 W -12 0 sunrise: 05:24 sunset: 19:15
+2013 3 21 El_Hierro 27 44 N 18 3 W -12 1 sunrise: 05:23 sunset: 19:16
+2013 3 21 El_Hierro 27 44 N 18 3 W -18 0 sunrise: 04:57 sunset: 19:42
+2013 3 21 El_Hierro 27 44 N 18 3 W -18 1 sunrise: 04:55 sunset: 19:43
+2013 6 21 Greenwich 51 28 N 0 0 E 10 0 sunrise: 05:06 sunset: 18:58
+2013 6 21 Greenwich 51 28 N 0 0 E 10 1 sunrise: 05:04 sunset: 18:59
+2013 6 21 Greenwich 51 28 N 0 0 E 0 0 sunrise: 03:50 sunset: 20:14
+2013 6 21 Greenwich 51 28 N 0 0 E 0 1 sunrise: 03:48 sunset: 20:16
+2013 6 21 Greenwich 51 28 N 0 0 E -0.583 0 sunrise: 03:45 sunset: 20:19
+2013 6 21 Greenwich 51 28 N 0 0 E -0.583 1 sunrise: 03:43 sunset: 20:21
+2013 6 21 Greenwich 51 28 N 0 0 E -0.833 0 sunrise: 03:43 sunset: 20:21
+2013 6 21 Greenwich 51 28 N 0 0 E -0.833 1 sunrise: 03:41 sunset: 20:23
+2013 6 21 Greenwich 51 28 N 0 0 E -12 0 sunrise: 01:41 sunset: 22:23
+2013 6 21 Greenwich 51 28 N 0 0 E -12 1 sunrise: 01:36 sunset: 22:27
+2013 6 21 Greenwich 51 28 N 0 0 E -18 0 sunrise: 00:02 sunset: 24:02 polar night or midnight sun
+2013 6 21 Greenwich 51 28 N 0 0 E -18 1 sunrise: 00:02 sunset: 24:02 polar night or midnight sun
+2013 6 21 Reykjavik 64 4 N 21 58 W 10 0 sunrise: 04:41 sunset: 20:19
+2013 6 21 Reykjavik 64 4 N 21 58 W 10 1 sunrise: 04:38 sunset: 20:22
+2013 6 21 Reykjavik 64 4 N 21 58 W 0 0 sunrise: 02:17 sunset: 22:42
+2013 6 21 Reykjavik 64 4 N 21 58 W 0 1 sunrise: 02:12 sunset: 22:48
+2013 6 21 Reykjavik 64 4 N 21 58 W -0.583 0 sunrise: 02:04 sunset: 22:56
+2013 6 21 Reykjavik 64 4 N 21 58 W -0.583 1 sunrise: 01:57 sunset: 23:02
+2013 6 21 Reykjavik 64 4 N 21 58 W -0.833 0 sunrise: 01:57 sunset: 23:02
+2013 6 21 Reykjavik 64 4 N 21 58 W -0.833 1 sunrise: 01:50 sunset: 23:09
+2013 6 21 Reykjavik 64 4 N 21 58 W -12 0 sunrise: 00:30 sunset: 24:30 polar night or midnight sun
+2013 6 21 Reykjavik 64 4 N 21 58 W -12 1 sunrise: 00:30 sunset: 24:30 polar night or midnight sun
+2013 6 21 Reykjavik 64 4 N 21 58 W -18 0 sunrise: 00:30 sunset: 24:30 polar night or midnight sun
+2013 6 21 Reykjavik 64 4 N 21 58 W -18 1 sunrise: 00:30 sunset: 24:30 polar night or midnight sun
+2013 6 21 Quito 0 15 S 78 35 W 10 0 sunrise: 07:00 sunset: 17:32
+2013 6 21 Quito 0 15 S 78 35 W 10 1 sunrise: 06:59 sunset: 17:33
+2013 6 21 Quito 0 15 S 78 35 W 0 0 sunrise: 06:17 sunset: 18:16
+2013 6 21 Quito 0 15 S 78 35 W 0 1 sunrise: 06:15 sunset: 18:17
+2013 6 21 Quito 0 15 S 78 35 W -0.583 0 sunrise: 06:14 sunset: 18:18
+2013 6 21 Quito 0 15 S 78 35 W -0.583 1 sunrise: 06:13 sunset: 18:19
+2013 6 21 Quito 0 15 S 78 35 W -0.833 0 sunrise: 06:13 sunset: 18:19
+2013 6 21 Quito 0 15 S 78 35 W -0.833 1 sunrise: 06:12 sunset: 18:21
+2013 6 21 Quito 0 15 S 78 35 W -12 0 sunrise: 05:24 sunset: 19:08
+2013 6 21 Quito 0 15 S 78 35 W -12 1 sunrise: 05:23 sunset: 19:09
+2013 6 21 Quito 0 15 S 78 35 W -18 0 sunrise: 04:58 sunset: 19:34
+2013 6 21 Quito 0 15 S 78 35 W -18 1 sunrise: 04:57 sunset: 19:36
+2013 6 21 El_Hierro 27 44 N 18 3 W 10 0 sunrise: 06:11 sunset: 18:17
+2013 6 21 El_Hierro 27 44 N 18 3 W 10 1 sunrise: 06:10 sunset: 18:19
+2013 6 21 El_Hierro 27 44 N 18 3 W 0 0 sunrise: 05:21 sunset: 19:07
+2013 6 21 El_Hierro 27 44 N 18 3 W 0 1 sunrise: 05:20 sunset: 19:08
+2013 6 21 El_Hierro 27 44 N 18 3 W -0.583 0 sunrise: 05:18 sunset: 19:10
+2013 6 21 El_Hierro 27 44 N 18 3 W -0.583 1 sunrise: 05:17 sunset: 19:11
+2013 6 21 El_Hierro 27 44 N 18 3 W -0.833 0 sunrise: 05:17 sunset: 19:11
+2013 6 21 El_Hierro 27 44 N 18 3 W -0.833 1 sunrise: 05:16 sunset: 19:12
+2013 6 21 El_Hierro 27 44 N 18 3 W -12 0 sunrise: 04:18 sunset: 20:10
+2013 6 21 El_Hierro 27 44 N 18 3 W -12 1 sunrise: 04:17 sunset: 20:11
+2013 6 21 El_Hierro 27 44 N 18 3 W -18 0 sunrise: 03:44 sunset: 20:44
+2013 6 21 El_Hierro 27 44 N 18 3 W -18 1 sunrise: 03:43 sunset: 20:45
+2013 8 31 Greenwich 51 28 N 0 0 E 10 0 sunrise: 06:22 sunset: 17:39
+2013 8 31 Greenwich 51 28 N 0 0 E 10 1 sunrise: 06:20 sunset: 17:40
+2013 8 31 Greenwich 51 28 N 0 0 E 0 0 sunrise: 05:17 sunset: 18:43
+2013 8 31 Greenwich 51 28 N 0 0 E 0 1 sunrise: 05:15 sunset: 18:45
+2013 8 31 Greenwich 51 28 N 0 0 E -0.583 0 sunrise: 05:13 sunset: 18:47
+2013 8 31 Greenwich 51 28 N 0 0 E -0.583 1 sunrise: 05:12 sunset: 18:49
+2013 8 31 Greenwich 51 28 N 0 0 E -0.833 0 sunrise: 05:12 sunset: 18:49
+2013 8 31 Greenwich 51 28 N 0 0 E -0.833 1 sunrise: 05:10 sunset: 18:51
+2013 8 31 Greenwich 51 28 N 0 0 E -12 0 sunrise: 03:54 sunset: 20:07
+2013 8 31 Greenwich 51 28 N 0 0 E -12 1 sunrise: 03:52 sunset: 20:09
+2013 8 31 Greenwich 51 28 N 0 0 E -18 0 sunrise: 03:06 sunset: 20:54
+2013 8 31 Greenwich 51 28 N 0 0 E -18 1 sunrise: 03:04 sunset: 20:57
+2013 8 31 Reykjavik 64 4 N 21 58 W 10 0 sunrise: 06:50 sunset: 18:06
+2013 8 31 Reykjavik 64 4 N 21 58 W 10 1 sunrise: 06:48 sunset: 18:09
+2013 8 31 Reykjavik 64 4 N 21 58 W 0 0 sunrise: 05:17 sunset: 19:39
+2013 8 31 Reykjavik 64 4 N 21 58 W 0 1 sunrise: 05:14 sunset: 19:42
+2013 8 31 Reykjavik 64 4 N 21 58 W -0.583 0 sunrise: 05:11 sunset: 19:45
+2013 8 31 Reykjavik 64 4 N 21 58 W -0.583 1 sunrise: 05:09 sunset: 19:48
+2013 8 31 Reykjavik 64 4 N 21 58 W -0.833 0 sunrise: 05:09 sunset: 19:47
+2013 8 31 Reykjavik 64 4 N 21 58 W -0.833 1 sunrise: 05:06 sunset: 19:50
+2013 8 31 Reykjavik 64 4 N 21 58 W -12 0 sunrise: 03:01 sunset: 21:55
+2013 8 31 Reykjavik 64 4 N 21 58 W -12 1 sunrise: 02:57 sunset: 21:59
+2013 8 31 Reykjavik 64 4 N 21 58 W -18 0 sunrise: 00:28 sunset: 24:28 polar night or midnight sun
+2013 8 31 Reykjavik 64 4 N 21 58 W -18 1 sunrise: 00:28 sunset: 24:28 polar night or midnight sun
+2013 8 31 Quito 0 15 S 78 35 W 10 0 sunrise: 06:55 sunset: 17:34
+2013 8 31 Quito 0 15 S 78 35 W 10 1 sunrise: 06:54 sunset: 17:35
+2013 8 31 Quito 0 15 S 78 35 W 0 0 sunrise: 06:15 sunset: 18:14
+2013 8 31 Quito 0 15 S 78 35 W 0 1 sunrise: 06:14 sunset: 18:15
+2013 8 31 Quito 0 15 S 78 35 W -0.583 0 sunrise: 06:12 sunset: 18:17
+2013 8 31 Quito 0 15 S 78 35 W -0.583 1 sunrise: 06:11 sunset: 18:18
+2013 8 31 Quito 0 15 S 78 35 W -0.833 0 sunrise: 06:11 sunset: 18:18
+2013 8 31 Quito 0 15 S 78 35 W -0.833 1 sunrise: 06:10 sunset: 18:19
+2013 8 31 Quito 0 15 S 78 35 W -12 0 sunrise: 05:26 sunset: 19:03
+2013 8 31 Quito 0 15 S 78 35 W -12 1 sunrise: 05:25 sunset: 19:04
+2013 8 31 Quito 0 15 S 78 35 W -18 0 sunrise: 05:02 sunset: 19:27
+2013 8 31 Quito 0 15 S 78 35 W -18 1 sunrise: 05:01 sunset: 19:28
+2013 8 31 El_Hierro 27 44 N 18 3 W 10 0 sunrise: 06:40 sunset: 17:45
+2013 8 31 El_Hierro 27 44 N 18 3 W 10 1 sunrise: 06:39 sunset: 17:46
+2013 8 31 El_Hierro 27 44 N 18 3 W 0 0 sunrise: 05:55 sunset: 18:30
+2013 8 31 El_Hierro 27 44 N 18 3 W 0 1 sunrise: 05:53 sunset: 18:32
+2013 8 31 El_Hierro 27 44 N 18 3 W -0.583 0 sunrise: 05:52 sunset: 18:33
+2013 8 31 El_Hierro 27 44 N 18 3 W -0.583 1 sunrise: 05:51 sunset: 18:34
+2013 8 31 El_Hierro 27 44 N 18 3 W -0.833 0 sunrise: 05:51 sunset: 18:34
+2013 8 31 El_Hierro 27 44 N 18 3 W -0.833 1 sunrise: 05:49 sunset: 18:35
+2013 8 31 El_Hierro 27 44 N 18 3 W -12 0 sunrise: 04:59 sunset: 19:26
+2013 8 31 El_Hierro 27 44 N 18 3 W -12 1 sunrise: 04:58 sunset: 19:27
+2013 8 31 El_Hierro 27 44 N 18 3 W -18 0 sunrise: 04:30 sunset: 19:55
+2013 8 31 El_Hierro 27 44 N 18 3 W -18 1 sunrise: 04:29 sunset: 19:56
+2013 9 21 Greenwich 51 28 N 0 0 E 10 0 sunrise: 06:55 sunset: 16:51
+2013 9 21 Greenwich 51 28 N 0 0 E 10 1 sunrise: 06:53 sunset: 16:53
+2013 9 21 Greenwich 51 28 N 0 0 E 0 0 sunrise: 05:50 sunset: 17:56
+2013 9 21 Greenwich 51 28 N 0 0 E 0 1 sunrise: 05:49 sunset: 17:57
+2013 9 21 Greenwich 51 28 N 0 0 E -0.583 0 sunrise: 05:47 sunset: 17:59
+2013 9 21 Greenwich 51 28 N 0 0 E -0.583 1 sunrise: 05:45 sunset: 18:01
+2013 9 21 Greenwich 51 28 N 0 0 E -0.833 0 sunrise: 05:45 sunset: 18:01
+2013 9 21 Greenwich 51 28 N 0 0 E -0.833 1 sunrise: 05:43 sunset: 18:03
+2013 9 21 Greenwich 51 28 N 0 0 E -12 0 sunrise: 04:32 sunset: 19:14
+2013 9 21 Greenwich 51 28 N 0 0 E -12 1 sunrise: 04:30 sunset: 19:16
+2013 9 21 Greenwich 51 28 N 0 0 E -18 0 sunrise: 03:51 sunset: 19:55
+2013 9 21 Greenwich 51 28 N 0 0 E -18 1 sunrise: 03:49 sunset: 19:57
+2013 9 21 Reykjavik 64 4 N 21 58 W 10 0 sunrise: 07:50 sunset: 16:52
+2013 9 21 Reykjavik 64 4 N 21 58 W 10 1 sunrise: 07:47 sunset: 16:54
+2013 9 21 Reykjavik 64 4 N 21 58 W 0 0 sunrise: 06:17 sunset: 18:25
+2013 9 21 Reykjavik 64 4 N 21 58 W 0 1 sunrise: 06:14 sunset: 18:27
+2013 9 21 Reykjavik 64 4 N 21 58 W -0.583 0 sunrise: 06:11 sunset: 18:30
+2013 9 21 Reykjavik 64 4 N 21 58 W -0.583 1 sunrise: 06:09 sunset: 18:33
+2013 9 21 Reykjavik 64 4 N 21 58 W -0.833 0 sunrise: 06:09 sunset: 18:33
+2013 9 21 Reykjavik 64 4 N 21 58 W -0.833 1 sunrise: 06:07 sunset: 18:35
+2013 9 21 Reykjavik 64 4 N 21 58 W -12 0 sunrise: 04:23 sunset: 20:19
+2013 9 21 Reykjavik 64 4 N 21 58 W -12 1 sunrise: 04:20 sunset: 20:22
+2013 9 21 Reykjavik 64 4 N 21 58 W -18 0 sunrise: 03:15 sunset: 21:27
+2013 9 21 Reykjavik 64 4 N 21 58 W -18 1 sunrise: 03:12 sunset: 21:30
+2013 9 21 Quito 0 15 S 78 35 W 10 0 sunrise: 06:47 sunset: 17:27
+2013 9 21 Quito 0 15 S 78 35 W 10 1 sunrise: 06:46 sunset: 17:28
+2013 9 21 Quito 0 15 S 78 35 W 0 0 sunrise: 06:07 sunset: 18:07
+2013 9 21 Quito 0 15 S 78 35 W 0 1 sunrise: 06:06 sunset: 18:08
+2013 9 21 Quito 0 15 S 78 35 W -0.583 0 sunrise: 06:05 sunset: 18:10
+2013 9 21 Quito 0 15 S 78 35 W -0.583 1 sunrise: 06:04 sunset: 18:11
+2013 9 21 Quito 0 15 S 78 35 W -0.833 0 sunrise: 06:04 sunset: 18:11
+2013 9 21 Quito 0 15 S 78 35 W -0.833 1 sunrise: 06:03 sunset: 18:12
+2013 9 21 Quito 0 15 S 78 35 W -12 0 sunrise: 05:19 sunset: 18:55
+2013 9 21 Quito 0 15 S 78 35 W -12 1 sunrise: 05:18 sunset: 18:56
+2013 9 21 Quito 0 15 S 78 35 W -18 0 sunrise: 04:55 sunset: 19:19
+2013 9 21 Quito 0 15 S 78 35 W -18 1 sunrise: 04:54 sunset: 19:20
+2013 9 21 El_Hierro 27 44 N 18 3 W 10 0 sunrise: 06:49 sunset: 17:21
+2013 9 21 El_Hierro 27 44 N 18 3 W 10 1 sunrise: 06:48 sunset: 17:22
+2013 9 21 El_Hierro 27 44 N 18 3 W 0 0 sunrise: 06:04 sunset: 18:06
+2013 9 21 El_Hierro 27 44 N 18 3 W 0 1 sunrise: 06:03 sunset: 18:07
+2013 9 21 El_Hierro 27 44 N 18 3 W -0.583 0 sunrise: 06:01 sunset: 18:09
+2013 9 21 El_Hierro 27 44 N 18 3 W -0.583 1 sunrise: 06:00 sunset: 18:10
+2013 9 21 El_Hierro 27 44 N 18 3 W -0.833 0 sunrise: 06:00 sunset: 18:10
+2013 9 21 El_Hierro 27 44 N 18 3 W -0.833 1 sunrise: 05:59 sunset: 18:11
+2013 9 21 El_Hierro 27 44 N 18 3 W -12 0 sunrise: 05:10 sunset: 19:01
+2013 9 21 El_Hierro 27 44 N 18 3 W -12 1 sunrise: 05:09 sunset: 19:02
+2013 9 21 El_Hierro 27 44 N 18 3 W -18 0 sunrise: 04:42 sunset: 19:28
+2013 9 21 El_Hierro 27 44 N 18 3 W -18 1 sunrise: 04:41 sunset: 19:29
+2013 12 31 Greenwich 51 28 N 0 0 E 10 0 sunrise: 09:51 sunset: 14:16
+2013 12 31 Greenwich 51 28 N 0 0 E 10 1 sunrise: 09:47 sunset: 14:19
+2013 12 31 Greenwich 51 28 N 0 0 E 0 0 sunrise: 08:12 sunset: 15:54
+2013 12 31 Greenwich 51 28 N 0 0 E 0 1 sunrise: 08:10 sunset: 15:56
+2013 12 31 Greenwich 51 28 N 0 0 E -0.583 0 sunrise: 08:08 sunset: 15:59
+2013 12 31 Greenwich 51 28 N 0 0 E -0.583 1 sunrise: 08:05 sunset: 16:01
+2013 12 31 Greenwich 51 28 N 0 0 E -0.833 0 sunrise: 08:06 sunset: 16:01
+2013 12 31 Greenwich 51 28 N 0 0 E -0.833 1 sunrise: 08:03 sunset: 16:03
+2013 12 31 Greenwich 51 28 N 0 0 E -12 0 sunrise: 06:43 sunset: 17:23
+2013 12 31 Greenwich 51 28 N 0 0 E -12 1 sunrise: 06:41 sunset: 17:25
+2013 12 31 Greenwich 51 28 N 0 0 E -18 0 sunrise: 06:02 sunset: 18:04
+2013 12 31 Greenwich 51 28 N 0 0 E -18 1 sunrise: 06:00 sunset: 18:06
+2013 12 31 Reykjavik 64 4 N 21 58 W 10 0 sunrise: 12:31 sunset: 12:31 polar night or midnight sun
+2013 12 31 Reykjavik 64 4 N 21 58 W 10 1 sunrise: 12:31 sunset: 12:31 polar night or midnight sun
+2013 12 31 Reykjavik 64 4 N 21 58 W 0 0 sunrise: 10:35 sunset: 14:27
+2013 12 31 Reykjavik 64 4 N 21 58 W 0 1 sunrise: 10:30 sunset: 14:32
+2013 12 31 Reykjavik 64 4 N 21 58 W -0.583 0 sunrise: 10:24 sunset: 14:38
+2013 12 31 Reykjavik 64 4 N 21 58 W -0.583 1 sunrise: 10:19 sunset: 14:43
+2013 12 31 Reykjavik 64 4 N 21 58 W -0.833 0 sunrise: 10:19 sunset: 14:43
+2013 12 31 Reykjavik 64 4 N 21 58 W -0.833 1 sunrise: 10:14 sunset: 14:48
+2013 12 31 Reykjavik 64 4 N 21 58 W -12 0 sunrise: 07:55 sunset: 17:07
+2013 12 31 Reykjavik 64 4 N 21 58 W -12 1 sunrise: 07:52 sunset: 17:10
+2013 12 31 Reykjavik 64 4 N 21 58 W -18 0 sunrise: 06:56 sunset: 18:06
+2013 12 31 Reykjavik 64 4 N 21 58 W -18 1 sunrise: 06:53 sunset: 18:09
+2013 12 31 Quito 0 15 S 78 35 W 10 0 sunrise: 07:01 sunset: 17:34
+2013 12 31 Quito 0 15 S 78 35 W 10 1 sunrise: 06:59 sunset: 17:36
+2013 12 31 Quito 0 15 S 78 35 W 0 0 sunrise: 06:17 sunset: 18:18
+2013 12 31 Quito 0 15 S 78 35 W 0 1 sunrise: 06:16 sunset: 18:19
+2013 12 31 Quito 0 15 S 78 35 W -0.583 0 sunrise: 06:15 sunset: 18:20
+2013 12 31 Quito 0 15 S 78 35 W -0.583 1 sunrise: 06:13 sunset: 18:22
+2013 12 31 Quito 0 15 S 78 35 W -0.833 0 sunrise: 06:13 sunset: 18:22
+2013 12 31 Quito 0 15 S 78 35 W -0.833 1 sunrise: 06:12 sunset: 18:23
+2013 12 31 Quito 0 15 S 78 35 W -12 0 sunrise: 05:25 sunset: 19:10
+2013 12 31 Quito 0 15 S 78 35 W -12 1 sunrise: 05:24 sunset: 19:11
+2013 12 31 Quito 0 15 S 78 35 W -18 0 sunrise: 04:59 sunset: 19:36
+2013 12 31 Quito 0 15 S 78 35 W -18 1 sunrise: 04:57 sunset: 19:38
+2013 12 31 El_Hierro 27 44 N 18 3 W 10 0 sunrise: 07:59 sunset: 16:32
+2013 12 31 El_Hierro 27 44 N 18 3 W 10 1 sunrise: 07:58 sunset: 16:33
+2013 12 31 El_Hierro 27 44 N 18 3 W 0 0 sunrise: 07:07 sunset: 17:24
+2013 12 31 El_Hierro 27 44 N 18 3 W 0 1 sunrise: 07:06 sunset: 17:25
+2013 12 31 El_Hierro 27 44 N 18 3 W -0.583 0 sunrise: 07:04 sunset: 17:27
+2013 12 31 El_Hierro 27 44 N 18 3 W -0.583 1 sunrise: 07:03 sunset: 17:28
+2013 12 31 El_Hierro 27 44 N 18 3 W -0.833 0 sunrise: 07:03 sunset: 17:28
+2013 12 31 El_Hierro 27 44 N 18 3 W -0.833 1 sunrise: 07:01 sunset: 17:29
+2013 12 31 El_Hierro 27 44 N 18 3 W -12 0 sunrise: 06:08 sunset: 18:23
+2013 12 31 El_Hierro 27 44 N 18 3 W -12 1 sunrise: 06:07 sunset: 18:24
+2013 12 31 El_Hierro 27 44 N 18 3 W -18 0 sunrise: 05:39 sunset: 18:51
+2013 12 31 El_Hierro 27 44 N 18 3 W -18 1 sunrise: 05:38 sunset: 18:52
+EOD
+}
@@ -0,0 +1,345 @@
+#!/usr/bin/perl -w
+# -*- perl -*-
+#
+# Test script for Astro::Sunrise
+# Copyright (C) 2015 Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+
+use strict;
+use warnings;
+use POSIX qw(floor ceil);
+use Test::More;
+use Astro::Sunrise;
+
+my $check_warn;
+
+BEGIN {
+ $check_warn = 1;
+ eval "use Test::Warn";
+ $check_warn = 0
+ if $@;
+}
+
+my @tests = load_data();
+my ($long, $lat, $offset);
+my $fudge = 1; # in minutes
+
+plan tests => (2 + $check_warn) * scalar @tests;
+
+for (@tests) {
+ my ($yyyy, $mm, $dd, $loc, $lat_d, $lat_m, $lat_x, $lon_d, $lon_m, $lon_x, $alt, $upper_limb, $polar_night, $day_and_night, $polar_day, $expect_r, $expect_s)
+ = $_ =~ /(\d+)\s+(\d+)\s+(\d+) # date in YYYY MM DD format $1 $2 $3
+ \s+(\w+) # location $4
+ \s+(\d+)\s+(\d+)\s+(\w) # latitude $5 $6 $7
+ \s+(\d+)\s+(\d+)\s+(\w) # longitude $8 $9 $10
+ \s+(\S+) # altitude $11
+ \s+(\d) # upper limb $12
+ \s+(\d)\s+(\d)\s+(\d) # polar night $13, day and night $14, polar day $15
+ \s+sunrise:\s+([-\d]+:\d+) # sunrise $16
+ \s+sunset:\s+(\d+:\d+)/x; # sunset $17
+ if ( $lat_x eq 'N' ) {
+ $lat = sprintf( "%.3f", ( $lat_d + ( $lat_m / 60 ) ) );
+ }
+ elsif ( $lat_x eq 'S' ) {
+ $lat = sprintf( "%.3f", -( $lat_d + ( $lat_m / 60 ) ) );
+ }
+
+ if ( $lon_x eq 'E' ) {
+ $long = sprintf( "%.3f", $lon_d + ( $lon_m / 60 ) );
+ }
+ elsif ( $lon_x eq 'W' ) {
+ $long = sprintf( "%.3f", -( $lon_d + ( $lon_m / 60 ) ) );
+ }
+
+ if ($long < 0) {
+ $offset = ceil( $long / 15 );
+ }
+ elsif ($long > 0) {
+ $offset = floor( $long /15 );
+ }
+ else {
+ $offset = 0;
+ }
+ if ($check_warn) {
+ if ($polar_night) {
+ warning_like { sunrise ( { year => $yyyy, month => $mm, day => $dd, tz => 0,
+ lon => $long, lat => $lat, alt => $alt, upper_limb => $upper_limb, } ); }
+ qr/sun never rises!!/i,
+ "Polar night at $loc on $yyyy-$mm-$dd";
+ }
+ if ($day_and_night) {
+ warning_is { sunrise ( { year => $yyyy, month => $mm, day => $dd, tz => 0,
+ lon => $long, lat => $lat, alt => $alt, upper_limb => $upper_limb, } ); }
+ undef, # which means "no warning"
+ "Day and night at $loc on $yyyy-$mm-$dd";
+ }
+ if ($polar_day) {
+ warning_like { sunrise ( { year => $yyyy, month => $mm, day => $dd, tz => 0,
+ lon => $long, lat => $lat, alt => $alt, upper_limb => $upper_limb, } ); }
+ qr/sun never sets!!/i,
+ "Polar day at $loc on $yyyy-$mm-$dd";
+ }
+ }
+ my ($sunrise, $sunset) = sunrise ( { year => $yyyy, month => $mm, day => $dd, tz => 0,
+ lon => $long, lat => $lat, alt => $alt, upper_limb => $upper_limb, polar => 'retval', } );
+ if ($polar_night) {
+ is ($sunrise, 'night', "Polar night at $loc on $yyyy-$mm-$dd");
+ is ($sunset , 'night', "Polar night at $loc on $yyyy-$mm-$dd");
+ }
+ if ($day_and_night) {
+ my $exp_h = fudge_h($expect_r, $fudge);
+ my $exp_l = fudge_l($expect_r, $fudge);
+ ok ($sunrise ge $exp_l && $sunrise le $exp_h
+ , "Sunrise for $loc $yyyy-$mm-$dd $alt $upper_limb $exp_l $sunrise $exp_h");
+ $exp_h = fudge_h($expect_s, $fudge);
+ $exp_l = fudge_l($expect_s, $fudge);
+ ok ($sunset ge $exp_l && $sunset le $exp_h
+ , "Sunset for $loc $yyyy-$mm-$dd $alt $upper_limb $exp_l $sunset $exp_h");
+ }
+ if ($polar_day) {
+ is ($sunrise, 'day', "Polar day at $loc on $yyyy-$mm-$dd");
+ is ($sunset , 'day', "Polar day at $loc on $yyyy-$mm-$dd");
+ }
+}
+
+sub fudge_h {
+ my ($exp, $fudge) = @_;
+ my ($hh, $mn) = $exp =~ /^(\d\d):(\d\d)$/;
+ $mn += $fudge;
+ if ($mn > 59) {
+ $hh ++;
+ $mn -= 60;
+ }
+ if ($hh > 23) {
+ $hh -= 24;
+ }
+ elsif ($hh < 0) {
+ $hh += 24;
+ }
+ return sprintf("%02d:%02d", $hh, $mn);
+}
+
+sub fudge_l {
+ my ($exp, $fudge) = @_;
+ my ($hh, $mn) = $exp =~ /^(\d\d):(\d\d)$/;
+ $mn -= $fudge;
+ if ($mn < 0) {
+ $hh --;
+ $mn += 60;
+ }
+ if ($hh > 23) {
+ $hh -= 24;
+ }
+ elsif ($hh < 0) {
+ $hh += 24;
+ }
+ return sprintf("%02d:%02d", $hh, $mn);
+}
+
+sub load_data {
+ return split "\n", <<'EOD';
+2013 1 1 North_Pole 89 59 N 0 0 E 0 0 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 1 1 North_Pole 89 59 N 0 0 E 0 1 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 1 1 North_Pole 89 59 N 0 0 E -0.583 0 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 1 1 North_Pole 89 59 N 0 0 E -0.583 1 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 1 1 North_Pole 89 59 N 0 0 E -0.833 0 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 1 1 North_Pole 89 59 N 0 0 E -0.833 1 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 1 1 North_Pole 89 59 N 0 0 E -12 0 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 1 1 North_Pole 89 59 N 0 0 E -12 1 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 1 1 North_Pole 89 59 N 0 0 E -18 0 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 1 1 North_Pole 89 59 N 0 0 E -18 1 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 3 21 North_Pole 89 59 N 0 0 E 0 0 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 North_Pole 89 59 N 0 0 E 0 1 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 North_Pole 89 59 N 0 0 E -0.583 0 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 North_Pole 89 59 N 0 0 E -0.583 1 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 North_Pole 89 59 N 0 0 E -0.833 0 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 North_Pole 89 59 N 0 0 E -0.833 1 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 North_Pole 89 59 N 0 0 E -12 0 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 North_Pole 89 59 N 0 0 E -12 1 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 North_Pole 89 59 N 0 0 E -18 0 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 North_Pole 89 59 N 0 0 E -18 1 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 6 21 North_Pole 89 59 N 0 0 E 0 0 0 0 1 sunrise: 00:01 sunset: 24:01
+2013 6 21 North_Pole 89 59 N 0 0 E 0 1 0 0 1 sunrise: 00:01 sunset: 24:01
+2013 6 21 North_Pole 89 59 N 0 0 E -0.583 0 0 0 1 sunrise: 00:01 sunset: 24:01
+2013 6 21 North_Pole 89 59 N 0 0 E -0.583 1 0 0 1 sunrise: 00:01 sunset: 24:01
+2013 6 21 North_Pole 89 59 N 0 0 E -0.833 0 0 0 1 sunrise: 00:01 sunset: 24:01
+2013 6 21 North_Pole 89 59 N 0 0 E -0.833 1 0 0 1 sunrise: 00:01 sunset: 24:01
+2013 6 21 North_Pole 89 59 N 0 0 E -12 0 0 0 1 sunrise: 00:01 sunset: 24:01
+2013 6 21 North_Pole 89 59 N 0 0 E -12 1 0 0 1 sunrise: 00:01 sunset: 24:01
+2013 6 21 North_Pole 89 59 N 0 0 E -18 0 0 0 1 sunrise: 00:01 sunset: 24:01
+2013 6 21 North_Pole 89 59 N 0 0 E -18 1 0 0 1 sunrise: 00:01 sunset: 24:01
+2013 8 31 North_Pole 89 59 N 0 0 E 0 0 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 North_Pole 89 59 N 0 0 E 0 1 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 North_Pole 89 59 N 0 0 E -0.583 0 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 North_Pole 89 59 N 0 0 E -0.583 1 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 North_Pole 89 59 N 0 0 E -0.833 0 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 North_Pole 89 59 N 0 0 E -0.833 1 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 North_Pole 89 59 N 0 0 E -12 0 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 North_Pole 89 59 N 0 0 E -12 1 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 North_Pole 89 59 N 0 0 E -18 0 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 North_Pole 89 59 N 0 0 E -18 1 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 9 21 North_Pole 89 59 N 0 0 E 0 0 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 North_Pole 89 59 N 0 0 E 0 1 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 North_Pole 89 59 N 0 0 E -0.583 0 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 North_Pole 89 59 N 0 0 E -0.583 1 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 North_Pole 89 59 N 0 0 E -0.833 0 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 North_Pole 89 59 N 0 0 E -0.833 1 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 North_Pole 89 59 N 0 0 E -12 0 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 North_Pole 89 59 N 0 0 E -12 1 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 North_Pole 89 59 N 0 0 E -18 0 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 North_Pole 89 59 N 0 0 E -18 1 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 12 31 North_Pole 89 59 N 0 0 E 0 0 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 12 31 North_Pole 89 59 N 0 0 E 0 1 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 12 31 North_Pole 89 59 N 0 0 E -0.583 0 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 12 31 North_Pole 89 59 N 0 0 E -0.583 1 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 12 31 North_Pole 89 59 N 0 0 E -0.833 0 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 12 31 North_Pole 89 59 N 0 0 E -0.833 1 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 12 31 North_Pole 89 59 N 0 0 E -12 0 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 12 31 North_Pole 89 59 N 0 0 E -12 1 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 12 31 North_Pole 89 59 N 0 0 E -18 0 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 12 31 North_Pole 89 59 N 0 0 E -18 1 1 0 0 sunrise: 12:03 sunset: 12:03
+2013 1 1 Halley_Base 75 35 S 26 39 W 0 0 0 0 1 sunrise: 01:50 sunset: 25:50
+2013 1 1 Halley_Base 75 35 S 26 39 W 0 1 0 0 1 sunrise: 01:50 sunset: 25:50
+2013 1 1 Halley_Base 75 35 S 26 39 W -0.583 0 0 0 1 sunrise: 01:50 sunset: 25:50
+2013 1 1 Halley_Base 75 35 S 26 39 W -0.583 1 0 0 1 sunrise: 01:50 sunset: 25:50
+2013 1 1 Halley_Base 75 35 S 26 39 W -0.833 0 0 0 1 sunrise: 01:50 sunset: 25:50
+2013 1 1 Halley_Base 75 35 S 26 39 W -0.833 1 0 0 1 sunrise: 01:50 sunset: 25:50
+2013 1 1 Halley_Base 75 35 S 26 39 W -12 0 0 0 1 sunrise: 01:50 sunset: 25:50
+2013 1 1 Halley_Base 75 35 S 26 39 W -12 1 0 0 1 sunrise: 01:50 sunset: 25:50
+2013 1 1 Halley_Base 75 35 S 26 39 W -18 0 0 0 1 sunrise: 01:50 sunset: 25:50
+2013 1 1 Halley_Base 75 35 S 26 39 W -18 1 0 0 1 sunrise: 01:50 sunset: 25:50
+2013 3 21 Halley_Base 75 35 S 26 39 W 0 0 0 1 0 sunrise: 08:00 sunset: 19:46
+2013 3 21 Halley_Base 75 35 S 26 39 W 0 1 0 1 0 sunrise: 07:56 sunset: 19:51
+2013 3 21 Halley_Base 75 35 S 26 39 W -0.583 0 0 1 0 sunrise: 07:51 sunset: 19:56
+2013 3 21 Halley_Base 75 35 S 26 39 W -0.583 1 0 1 0 sunrise: 07:46 sunset: 20:00
+2013 3 21 Halley_Base 75 35 S 26 39 W -0.833 0 0 1 0 sunrise: 07:47 sunset: 20:00
+2013 3 21 Halley_Base 75 35 S 26 39 W -0.833 1 0 1 0 sunrise: 07:42 sunset: 20:04
+2013 3 21 Halley_Base 75 35 S 26 39 W -12 0 0 1 0 sunrise: 04:19 sunset: 23:28
+2013 3 21 Halley_Base 75 35 S 26 39 W -12 1 0 1 0 sunrise: 04:11 sunset: 23:35
+2013 3 21 Halley_Base 75 35 S 26 39 W -18 0 0 0 1 sunrise: 01:53 sunset: 25:53
+2013 3 21 Halley_Base 75 35 S 26 39 W -18 1 0 0 1 sunrise: 01:53 sunset: 25:53
+2013 6 21 Halley_Base 75 35 S 26 39 W 0 0 1 0 0 sunrise: 13:48 sunset: 13:48
+2013 6 21 Halley_Base 75 35 S 26 39 W 0 1 1 0 0 sunrise: 13:48 sunset: 13:48
+2013 6 21 Halley_Base 75 35 S 26 39 W -0.583 0 1 0 0 sunrise: 13:48 sunset: 13:48
+2013 6 21 Halley_Base 75 35 S 26 39 W -0.583 1 1 0 0 sunrise: 13:48 sunset: 13:48
+2013 6 21 Halley_Base 75 35 S 26 39 W -0.833 0 1 0 0 sunrise: 13:48 sunset: 13:48
+2013 6 21 Halley_Base 75 35 S 26 39 W -0.833 1 1 0 0 sunrise: 13:48 sunset: 13:48
+2013 6 21 Halley_Base 75 35 S 26 39 W -12 0 0 1 0 sunrise: 11:12 sunset: 16:24
+2013 6 21 Halley_Base 75 35 S 26 39 W -12 1 0 1 0 sunrise: 11:05 sunset: 16:31
+2013 6 21 Halley_Base 75 35 S 26 39 W -18 0 0 1 0 sunrise: 09:06 sunset: 18:30
+2013 6 21 Halley_Base 75 35 S 26 39 W -18 1 0 1 0 sunrise: 09:01 sunset: 18:35
+2013 8 31 Halley_Base 75 35 S 26 39 W 0 0 0 1 0 sunrise: 10:08 sunset: 17:25
+2013 8 31 Halley_Base 75 35 S 26 39 W 0 1 0 1 0 sunrise: 10:02 sunset: 17:30
+2013 8 31 Halley_Base 75 35 S 26 39 W -0.583 0 0 1 0 sunrise: 09:56 sunset: 17:37
+2013 8 31 Halley_Base 75 35 S 26 39 W -0.583 1 0 1 0 sunrise: 09:51 sunset: 17:42
+2013 8 31 Halley_Base 75 35 S 26 39 W -0.833 0 0 1 0 sunrise: 09:51 sunset: 17:41
+2013 8 31 Halley_Base 75 35 S 26 39 W -0.833 1 0 1 0 sunrise: 09:46 sunset: 17:46
+2013 8 31 Halley_Base 75 35 S 26 39 W -12 0 0 1 0 sunrise: 06:45 sunset: 20:48
+2013 8 31 Halley_Base 75 35 S 26 39 W -12 1 0 1 0 sunrise: 06:40 sunset: 20:53
+2013 8 31 Halley_Base 75 35 S 26 39 W -18 0 0 1 0 sunrise: 04:56 sunset: 22:37
+2013 8 31 Halley_Base 75 35 S 26 39 W -18 1 0 1 0 sunrise: 04:50 sunset: 22:42
+2013 9 21 Halley_Base 75 35 S 26 39 W 0 0 0 1 0 sunrise: 07:47 sunset: 19:31
+2013 9 21 Halley_Base 75 35 S 26 39 W 0 1 0 1 0 sunrise: 07:43 sunset: 19:36
+2013 9 21 Halley_Base 75 35 S 26 39 W -0.583 0 0 1 0 sunrise: 07:37 sunset: 19:41
+2013 9 21 Halley_Base 75 35 S 26 39 W -0.583 1 0 1 0 sunrise: 07:33 sunset: 19:45
+2013 9 21 Halley_Base 75 35 S 26 39 W -0.833 0 0 1 0 sunrise: 07:33 sunset: 19:45
+2013 9 21 Halley_Base 75 35 S 26 39 W -0.833 1 0 1 0 sunrise: 07:29 sunset: 19:49
+2013 9 21 Halley_Base 75 35 S 26 39 W -12 0 0 1 0 sunrise: 04:06 sunset: 23:12
+2013 9 21 Halley_Base 75 35 S 26 39 W -12 1 0 1 0 sunrise: 03:59 sunset: 23:19
+2013 9 21 Halley_Base 75 35 S 26 39 W -18 0 0 0 1 sunrise: 01:39 sunset: 25:39
+2013 9 21 Halley_Base 75 35 S 26 39 W -18 1 0 0 1 sunrise: 01:39 sunset: 25:39
+2013 12 31 Halley_Base 75 35 S 26 39 W 0 0 0 0 1 sunrise: 01:49 sunset: 25:49
+2013 12 31 Halley_Base 75 35 S 26 39 W 0 1 0 0 1 sunrise: 01:49 sunset: 25:49
+2013 12 31 Halley_Base 75 35 S 26 39 W -0.583 0 0 0 1 sunrise: 01:49 sunset: 25:49
+2013 12 31 Halley_Base 75 35 S 26 39 W -0.583 1 0 0 1 sunrise: 01:49 sunset: 25:49
+2013 12 31 Halley_Base 75 35 S 26 39 W -0.833 0 0 0 1 sunrise: 01:49 sunset: 25:49
+2013 12 31 Halley_Base 75 35 S 26 39 W -0.833 1 0 0 1 sunrise: 01:49 sunset: 25:49
+2013 12 31 Halley_Base 75 35 S 26 39 W -12 0 0 0 1 sunrise: 01:49 sunset: 25:49
+2013 12 31 Halley_Base 75 35 S 26 39 W -12 1 0 0 1 sunrise: 01:49 sunset: 25:49
+2013 12 31 Halley_Base 75 35 S 26 39 W -18 0 0 0 1 sunrise: 01:49 sunset: 25:49
+2013 12 31 Halley_Base 75 35 S 26 39 W -18 1 0 0 1 sunrise: 01:49 sunset: 25:49
+2013 1 1 South_Pole 89 59 S 0 0 W 0 0 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 1 1 South_Pole 89 59 S 0 0 W 0 1 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 1 1 South_Pole 89 59 S 0 0 W -0.583 0 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 1 1 South_Pole 89 59 S 0 0 W -0.583 1 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 1 1 South_Pole 89 59 S 0 0 W -0.833 0 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 1 1 South_Pole 89 59 S 0 0 W -0.833 1 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 1 1 South_Pole 89 59 S 0 0 W -12 0 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 1 1 South_Pole 89 59 S 0 0 W -12 1 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 1 1 South_Pole 89 59 S 0 0 W -18 0 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 1 1 South_Pole 89 59 S 0 0 W -18 1 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 3 21 South_Pole 89 59 S 0 0 W 0 0 1 0 0 sunrise: 12:07 sunset: 12:07
+2013 3 21 South_Pole 89 59 S 0 0 W 0 1 1 0 0 sunrise: 12:07 sunset: 12:07
+2013 3 21 South_Pole 89 59 S 0 0 W -0.583 0 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 South_Pole 89 59 S 0 0 W -0.583 1 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 South_Pole 89 59 S 0 0 W -0.833 0 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 South_Pole 89 59 S 0 0 W -0.833 1 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 South_Pole 89 59 S 0 0 W -12 0 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 South_Pole 89 59 S 0 0 W -12 1 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 South_Pole 89 59 S 0 0 W -18 0 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 3 21 South_Pole 89 59 S 0 0 W -18 1 0 0 1 sunrise: 00:07 sunset: 24:07
+2013 6 21 South_Pole 89 59 S 0 0 W 0 0 1 0 0 sunrise: 12:01 sunset: 12:01
+2013 6 21 South_Pole 89 59 S 0 0 W 0 1 1 0 0 sunrise: 12:01 sunset: 12:01
+2013 6 21 South_Pole 89 59 S 0 0 W -0.583 0 1 0 0 sunrise: 12:01 sunset: 12:01
+2013 6 21 South_Pole 89 59 S 0 0 W -0.583 1 1 0 0 sunrise: 12:01 sunset: 12:01
+2013 6 21 South_Pole 89 59 S 0 0 W -0.833 0 1 0 0 sunrise: 12:01 sunset: 12:01
+2013 6 21 South_Pole 89 59 S 0 0 W -0.833 1 1 0 0 sunrise: 12:01 sunset: 12:01
+2013 6 21 South_Pole 89 59 S 0 0 W -12 0 1 0 0 sunrise: 12:01 sunset: 12:01
+2013 6 21 South_Pole 89 59 S 0 0 W -12 1 1 0 0 sunrise: 12:01 sunset: 12:01
+2013 6 21 South_Pole 89 59 S 0 0 W -18 0 1 0 0 sunrise: 12:01 sunset: 12:01
+2013 6 21 South_Pole 89 59 S 0 0 W -18 1 1 0 0 sunrise: 12:01 sunset: 12:01
+2013 8 31 South_Pole 89 59 S 0 0 W 0 0 1 0 0 sunrise: 12:00 sunset: 12:00
+2013 8 31 South_Pole 89 59 S 0 0 W 0 1 1 0 0 sunrise: 12:00 sunset: 12:00
+2013 8 31 South_Pole 89 59 S 0 0 W -0.583 0 1 0 0 sunrise: 12:00 sunset: 12:00
+2013 8 31 South_Pole 89 59 S 0 0 W -0.583 1 1 0 0 sunrise: 12:00 sunset: 12:00
+2013 8 31 South_Pole 89 59 S 0 0 W -0.833 0 1 0 0 sunrise: 12:00 sunset: 12:00
+2013 8 31 South_Pole 89 59 S 0 0 W -0.833 1 1 0 0 sunrise: 12:00 sunset: 12:00
+2013 8 31 South_Pole 89 59 S 0 0 W -12 0 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 South_Pole 89 59 S 0 0 W -12 1 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 South_Pole 89 59 S 0 0 W -18 0 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 8 31 South_Pole 89 59 S 0 0 W -18 1 0 0 1 sunrise: 00:00 sunset: 24:00
+2013 9 21 South_Pole 89 59 S 0 0 W 0 0 1 0 0 sunrise: 11:53 sunset: 11:53
+2013 9 21 South_Pole 89 59 S 0 0 W 0 1 1 0 0 sunrise: 11:53 sunset: 11:53
+2013 9 21 South_Pole 89 59 S 0 0 W -0.583 0 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 South_Pole 89 59 S 0 0 W -0.583 1 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 South_Pole 89 59 S 0 0 W -0.833 0 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 South_Pole 89 59 S 0 0 W -0.833 1 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 South_Pole 89 59 S 0 0 W -12 0 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 South_Pole 89 59 S 0 0 W -12 1 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 South_Pole 89 59 S 0 0 W -18 0 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 9 21 South_Pole 89 59 S 0 0 W -18 1 0 0 1 sunrise: -1:53 sunset: 23:53
+2013 12 31 South_Pole 89 59 S 0 0 W 0 0 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 12 31 South_Pole 89 59 S 0 0 W 0 1 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 12 31 South_Pole 89 59 S 0 0 W -0.583 0 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 12 31 South_Pole 89 59 S 0 0 W -0.583 1 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 12 31 South_Pole 89 59 S 0 0 W -0.833 0 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 12 31 South_Pole 89 59 S 0 0 W -0.833 1 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 12 31 South_Pole 89 59 S 0 0 W -12 0 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 12 31 South_Pole 89 59 S 0 0 W -12 1 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 12 31 South_Pole 89 59 S 0 0 W -18 0 0 0 1 sunrise: 00:03 sunset: 24:03
+2013 12 31 South_Pole 89 59 S 0 0 W -18 1 0 0 1 sunrise: 00:03 sunset: 24:03
+EOD
+}
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+# -*- encoding: utf-8; indent-tabs-mode: nil -*-
+#
+# Test script for Astro::Sunrise
+# Copyright (C) 2001, 2002, 2003, 2013, 2015 Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+use strict;
+use warnings;
+use Astro::Sunrise(qw(:DEFAULT :constants));
+use Test::More;
+
+
+BEGIN {
+ eval "use DateTime;";
+ if ($@) {
+ plan skip_all => "DateTime needed";
+ exit;
+ }
+}
+plan(tests => 12);
+
+use vars qw($long $lat $offset);
+
+my $sunrise_1 = sun_rise( -118, 33 );
+my $sunrise_2 = sun_rise( -118, 33, -.833 );
+my $sunrise_3 = sun_rise( -118, 33, -.833, 0 );
+my $sunrise_4 = sun_rise( -118, 33, undef, 0 );
+my $sunrise_5 = sun_rise({ lon => -118, lat => 33 });
+my $sunrise_6 = sun_rise({ lon => -118, lat => 33, alt => DEFAULT, offset => 0, upper_limb => 0, precise => 0 });
+
+ok( $sunrise_1 eq $sunrise_2 , "Test W/O Alt");
+ok( $sunrise_2 eq $sunrise_3 , "Test W/O offset");
+ok( $sunrise_3 eq $sunrise_4 , "Test setting Alt to undef");
+ok( $sunrise_4 eq $sunrise_5 , "Test using named basic parameters");
+ok( $sunrise_5 eq $sunrise_6 , "Test using all named parameters");
+
+my $sunset_1 = sun_set( -118, 33 );
+my $sunset_2 = sun_set( -118, 33, -.833 );
+my $sunset_3 = sun_set( -118, 33, -.833, 0 );
+my $sunset_4 = sun_set( -118, 33, undef, 0 );
+my $sunset_5 = sun_set({ lon => -118, lat => 33 });
+my $sunset_6 = sun_set({ lon => -118, lat => 33, alt => DEFAULT, offset => 0, upper_limb => 0, precise => 0 });
+
+ok( $sunset_1 eq $sunset_2 , "Test W/O Alt");
+ok( $sunset_2 eq $sunset_3 , "Test W/O offset");
+ok( $sunset_3 eq $sunset_4 , "Test setting Alt to undef");
+ok( $sunset_4 eq $sunset_5 , "Test using named basic parameters");
+ok( $sunset_5 eq $sunset_6 , "Test using all named parameters");
+
+my $then = DateTime->new (
+ year => 2000,
+ month => 6,
+ day => 20,
+ time_zone =>'America/Los_Angeles',
+ );
+my $offset = ( ($then->offset) /60 /60);
+
+my ($sunrise, $sunset) = sunrise($then->year, $then->mon, $then->mday,
+ -118, 33, $offset, 0);
+is ($sunrise, '05:44', "Test DateTime sunrise interface");
+is ($sunset, '20:04', "Test DateTime sunset interface");
+
@@ -0,0 +1,66 @@
+# -*- encoding: utf-8; indent-tabs-mode: nil -*-
+#
+# Test script for Astro::Sunrise: checking degree trigonometry
+# Copyright (C) 2015 Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+use strict;
+use warnings;
+use Test::More;
+use Astro::Sunrise qw(:trig);
+
+# Hand copied from "Tables numériques de fonctions élémentaires", J. LABORDE, publ Dunod, ISBN 2-04-010181-0
+my @table1 = ( [ 0, 0 , 1 , 0 , 6],
+ [ 10, 0.173648, 0.984808, 0.176327, 6],
+ [ 30, 0.5 , 0.866025, 0.577350, 6],
+ [ 45, 0.707107, 0.707107, 1 , 6],
+ [ 60, 0.866025, 0.5 , 1.73205 , 6],
+ [ 77, 0.974370, 0.224951, 4.3315 , 5],
+ );
+
+my @table2 = ( [ 0, 1, 0 ],
+ [ 1, 3, 18.4 ],
+ [ 1, 2, 26.6 ],
+ [ 2, 3, 33.7 ],
+ [ 3, 3, 45 ],
+ [ 7, 4, 60.3 ],
+ [ 1, 0, 90 ],
+ );
+
+plan(tests => 6 * @table1 + @table2);
+for (@table1) {
+ my ($angle, $sind, $cosd, $tand, $pres) = @$_;
+ ok(equal(sind($angle), $sind, 6), "sin($angle) = $sind");
+ ok(equal(cosd($angle), $cosd, 6), "cos($angle) = $cosd");
+ ok(equal(tand($angle), $tand, 3), "tan($angle) = $tand");
+ ok(equal(asind($sind), $angle, 3), "asin($sind) = $angle");
+ ok(equal(acosd($cosd), $angle, 3), "acos($cosd) = $angle");
+ ok(equal(atand($tand), $angle, 3), "atan($tand) = $angle");
+}
+for (@table2) {
+ my ($num, $den, $angle) = @$_;
+ ok(equal(atan2d($num, $den), $angle, 3), "atan($num/$den) = $angle");
+}
+
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+# -*- encoding: utf-8; indent-tabs-mode: nil -*-
+#
+# Test script for Astro::Sunrise
+# Copyright (C) 2015 Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+use strict;
+use warnings;
+use Astro::Sunrise(qw(:DEFAULT :constants));
+use Test::More;
+
+BEGIN {
+ eval "use DateTime;";
+ if ($@) {
+ plan skip_all => "DateTime needed";
+ exit;
+ }
+}
+plan(tests => 4);
+
+my $sunrise_5 = sun_rise({ lon => -118, lat => 33, time_zone =>'America/Los_Angeles', });
+my $sunrise_6 = sun_rise({ lon => -118, lat => 33, time_zone =>'America/Los_Angeles',
+ alt => DEFAULT, offset => 0, upper_limb => 0, precise => 0 });
+
+is( $sunrise_5, $sunrise_6 , "Comparing basic parameters with all parameters");
+
+my $sunset_5 = sun_set({ lon => -118, lat => 33, time_zone =>'America/Los_Angeles', });
+my $sunset_6 = sun_set({ lon => -118, lat => 33, time_zone =>'America/Los_Angeles',
+ alt => DEFAULT, offset => 0, upper_limb => 0, precise => 0 });
+
+is($sunset_5, $sunset_6, "Comparing basic parameters with all parameters");
+
+my $then = DateTime->today ( time_zone =>'America/Los_Angeles', );
+my $offset = ($then->offset) /60 /60;
+my ($sunrise, $sunset) = sunrise($then->year, $then->mon, $then->mday,
+ -118, 33, $offset, 0);
+is ($sunrise, $sunrise_6, "Test DateTime sunrise interface");
+is ($sunset, $sunset_6, "Test DateTime sunset interface");
+
+
@@ -0,0 +1,52 @@
+#!/usr/bin/perl -w
+# -*- perl -*-
+#
+# Test script for Astro::Sunrise
+# Author: Jean Forget, based on another test script by Slaven Rezic
+# Copyright (C) 2015 Slaven Rezic, Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+
+use strict;
+use warnings;
+use Test::More;
+
+BEGIN {
+ eval "use Time::Fake (1269738800);";
+ if ($@) {
+ plan skip_all => "Time::Fake needed";
+ exit;
+ }
+ eval "use DateTime;";
+ if ($@) {
+ plan skip_all => "DateTime needed";
+ exit;
+ }
+}
+use Astro::Sunrise;
+
+plan tests => 2;
+is(sun_rise({ lon => 13.5, lat => 52.5, time_zone => 'Europe/Berlin' }), '06:50', "Sunrise in Berlin on 2015-03-28");
+is(sun_set ({ lon => 13.5, lat => 52.5, time_zone => 'Europe/Berlin' }), '19:32', "Sunset in Berlin on 2015-03-28");
@@ -0,0 +1,52 @@
+#!/usr/bin/perl -w
+# -*- perl -*-
+#
+# Test script for Astro::Sunrise
+# Author: Jean Forget, based on another test script by Slaven Rezic
+# Copyright (C) 2015 Slaven Rezic, Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+
+use strict;
+use warnings;
+use Test::More;
+
+BEGIN {
+ eval "use Time::Fake (1288545834);";
+ if ($@) {
+ plan skip_all => "Time::Fake needed";
+ exit;
+ }
+ eval "use DateTime;";
+ if ($@) {
+ plan skip_all => "DateTime needed";
+ exit;
+ }
+}
+use Astro::Sunrise;
+
+plan tests => 2;
+is(sun_rise({ lon => 13.5, lat => 52.5, time_zone => 'Europe/Berlin' }), '07:00', "Sunrise in Berlin on 2010-10-31");
+is(sun_set ({ lon => 13.5, lat => 52.5, time_zone => 'Europe/Berlin' }), '16:39', "Sunset in Berlin on 2010-10-31");
@@ -0,0 +1,98 @@
+#!/usr/bin/perl
+# -*- encoding: utf-8; indent-tabs-mode: nil -*-
+#
+# Test script for Astro::Sunrise
+# Copyright (C) 2015 Ron Hill and Jean Forget
+#
+# This program is distributed under the same terms as Perl 5.16.3:
+# GNU Public License version 1 or later and Perl Artistic License
+#
+# You can find the text of the licenses in the F<LICENSE> file or at
+# L<http://www.perlfoundation.org/artistic_license_1_0>
+# and L<http://www.gnu.org/licenses/gpl-1.0.html>.
+#
+# Here is the summary of GPL:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 1, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., <http://www.fsf.org/>.
+#
+use strict;
+use warnings;
+use Test::More;
+
+my $datetime_ok;
+
+BEGIN {
+ eval "use Test::Fatal;";
+ if ($@) {
+ plan skip_all => "Test::Fatal needed";
+ exit;
+ }
+ eval "use DateTime;";
+ if ($@) {
+ $datetime_ok = 0;
+ }
+ else {
+ $datetime_ok = 1;
+ }
+}
+my @basic = ( [ { year => 2003, month => 6, day => 21, tz => 0, lon => 0, lat => 0, polar => 'whatever' },
+ qr/Wrong value of the 'polar' argument/,
+ "Wrong value of the 'polar' argument" ],
+ [ { month => 6, day => 21, tz => 0, lon => 0, lat => 0 },
+ qr/Year parameter is mandatory/,
+ "Year parameter is mandatory" ],
+ [ { year => 2003, day => 21, tz => 0, lon => 0, lat => 0 },
+ qr/Month parameter is mandatory/,
+ "Month parameter is mandatory" ],
+ [ { year => 2003, month => 6, tz => 0, lon => 0, lat => 0 },
+ qr/Day parameter is mandatory/,
+ "Day parameter is mandatory" ],
+ [ { year => 2003, month => 6, day => 21, tz => 0, lat => 0 },
+ qr/Longitude .* mandatory/,
+ "Longitude parameter is mandatory" ],
+ [ { year => 2003, month => 6, day => 21, tz => 0, lon => 0 },
+ qr/Latitude .* mandatory/,
+ "Latitude parameter is mandatory" ],
+ );
+my @dt = ( [ { lon => 0, lat => 0, polar => 'whatever' },
+ qr/Wrong value of the 'polar' argument/,
+ "Wrong value of the 'polar' argument" ],
+ [ { lat => 0 },
+ qr/Longitude .* mandatory/,
+ "Longitude parameter is mandatory" ],
+ [ { lon => 0 },
+ qr/Latitude .* mandatory/,
+ "Latitude parameter is mandatory" ],
+ );
+
+use Astro::Sunrise(qw(:DEFAULT :constants));
+plan(tests => @basic + $datetime_ok * @dt);
+
+for my $test (@basic) {
+ my ($arg_href, $regexp, $label) = @$test;
+ like ( exception { sunrise($arg_href) }, $regexp, $label);
+}
+
+if ($datetime_ok) {
+ for my $test (@dt) {
+ my ($arg_href, $regexp, $label) = @$test;
+ like ( exception { sun_rise($arg_href) }, $regexp, $label);
+ }
+ #like ( exception { sun_rise ( { year => 2003, month => 6, day => 21, tz => 0, lon => 0, lat => 0,
+ # polar => 'whatever' } ) },
+ # qr/Wrong value of the 'polar' argument/,
+ # "Wrong value of the 'polar' argument");
+
+}