The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 5586
LICENSE 0391
MANIFEST 921
META.json 045
META.yml 2025
Makefile.PL 868
README 20466
Sunrise.pm 7840
TODO 021
lib/Astro/Sunrise.pm 01089
t/00load.t 838
t/01basic.t 199196
t/02constants.t 1343
t/03dst.t 076
t/04basic.t 0434
t/05polar.t 0345
t/06datetime.t 085
t/07trig.t 066
t/08timezone.t 063
t/09springforward.t 052
t/10fallback.t 052
t/11fatal.t 098
22 files changed (This is a version diff) 13003360
@@ -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");
+
+}