TimeDate-2.35000755000765000024 015157412057 13062 5ustar00nicolasstaff000000000000README100644000765000024 55415157412057 14007 0ustar00nicolasstaff000000000000TimeDate-2.35This archive contains the distribution TimeDate, version 2.35: Date and time formatting subroutines This software is copyright (c) 2020 by Graham Barr. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. This README file was generated by Dist::Zilla::Plugin::Readme v6.033. LICENSE100644000765000024 4627615157412057 14207 0ustar00nicolasstaff000000000000TimeDate-2.35This software is copyright (c) 2020 by Graham Barr. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system 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" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2020 by Graham Barr. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 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. Copyright (C) 19yy 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, see . 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. , 1 April 1989 Moe Ghoul, President of Vice That's all there is to it! --- The Perl Artistic License 1.0 --- This software is Copyright (c) 2020 by Graham Barr. This is free software, licensed under: The Perl Artistic License 1.0 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End Changes100644000765000024 3545615157412057 14473 0ustar00nicolasstaff000000000000TimeDate-2.35Revision history for TimeDate distribution. 2.35 2026-03-20 21:44:45-06:00 America/Denver 2.34_03 2026-03-18 22:12:43-06:00 America/Denver (TRIAL RELEASE) * test: document and pin RT#84075/GH#12 fix in regression suite * fix: add NST, NFT, and NDT (Newfoundland) timezone support * fix: add ICT and PHT timezone support * fix: restore rebase regressions and clarify first-century limitation * fix: normalize two-digit years in str2time to avoid Time::Local windowing mismatch * fix: use standard 2-letter German weekday abbreviations * fix: detect timegm/timelocal overflow for far-future dates (RT#88777) * test: add regression tests for RT#88777 (negative epoch for far-future dates) * fix: use stored epoch in format_Z/format_z to fix DST fall-back timezone name * fix: document MSK timezone history and add regression test (RT#98949) * fix: strftime %s with timezone now returns correct epoch (RT#52387) * test: add POD validity regression test for RT#53557 * fix: include day in year-inference for dates without an explicit year * fix: document MSK timezone history and add regression test (RT#81350) * ci: install Pod::Checker via cpm in Linux CI * docs: add SECURITY.md with vulnerability reporting policy * test: add regression tests for RT#57800 / GH#3 (numeric m/d/yyyy pre-1970 dates) * fix: normalize year offset for dates before 1901 in strptime (RT#106105) * fix: reject timezone-only inputs in strptime (RT#70650) * test: add failing tests for RT#70650 (ludicrous date parsing) * fix: prevent negative month from strptime for 6-digit inputs like '199001' * test: add Portuguese format and round-trip tests from PR #61 * fix: treat number > 31 after month name as year, not day (GH#2) * fix: translate timezone abbreviations (%Z) in language-specific formatting * fix: tz_name() offset in seconds was treated as minutes (RT#59298) * docs: fix ISO-8601 example date in Date::Parse POD (issue #6) * feat: add optional LANGUAGE parameter to time2str() * feat: allow str2time() to accept a custom reference epoch (RT#64789) * docs: clarify strptime() return format for ISO 8601 dates (issue #44) * feat: add Portuguese language module * fix: prefer CEST over MEST as canonical Central European Summer Time name * fix: add ICT and PHT timezone abbreviations to Time::Zone (RT#123247) * fix: standardize Greek.pm to use native Unicode instead of \x{} escapes * test: add regression test for RT#105031 / GH#17 (1965-12-31 maps to 2065) * fix: declare Carp as runtime prerequisite in Makefile.PL * fix: infer current year for future months when no year given (RT#92611) * test: add regression tests for RT#53413 (4-digit year mangling) * fix: handle leap day in year-only date parsing test * fix: support IANA timezone names in tz2zone and tz_offset (RT#76968) * fix: preserve comma as ISO 8601 decimal separator in strptime * fix: add French day ordinal suffix in format_o * fix: make tz_name tests deterministic across DST transitions 2.34 2026-02-27 17:00:48-07:00 America/Denver * doc: Increase POD coverage * refactor: extract _build_lookups helper, remove hash-building duplication * fix: correct language data bugs and minor code review fixes * Fixup utf8 and add tests * Use Dist::Zilla for the distro * rebase: apply review feedback on #52 * fix: uncomment Indian Standard timezone (IST) * feat: support boost C++ timestamp format (%Y-%b-%d %H:%M:%S.%f) * fix: correct typos across documentation and comments * stop using use vars * rebase: apply review feedback on #49 * Remove limitation from Date::Parse * Create Arabic.pm 2.33 2020-05-19 11:34:00-06:00 America/Denver * Remove PAX Headers in tarball using GNU tar 2.32 2020-03-04 14:41:00-07:00 America/Denver * Fix t/date.t to run on leap years [arc] 2.31 2020-01-16 14:00:00-07:00 America/Denver * Fix year 2020 bug from t/getdate.t [Prajith] * Fix warnings from t/date.t * Fix pod issue in lib/Date/Parse.pm * Fix for French language using English day suffixes in %o [mitchjacksontech] * RT#84075: Fix Date::Parse::str2time century issue. [perlpilot] * Adds Occitan language. [Quenty31] * Migrate GitHub repo and bugtracker to atoomic/perl-TimeDate 2.30 2013-02-18 13:31:03-06:00 America/Chicago * Syncing distribution version number with Date::Parse, not functional changes 1.20 2009-12-12 06:38:14-06:00 America/Chicago * Typo => s/timezome/timezone/ [yanick] * RT#52387 Fix %s formating to use timelocal when no timezone is given * RT#51664 fix str2time('16 Oct 09') to not give a negative result 1.19 2009-09-25 13:59:41-05:00 America/Chicago * Replace Date::Language::Hungarian with version from CPAN by Lee Goddard 1.18 2009-09-24 17:43:28-05:00 America/Chicago * RT#49963 Skip pre 1970 date tests on Win32 * Added Date::Language::Hungarian (Konrad Lorinczi) 1.17 2009-09-19 10:56:12-05:00 America/Chicago Bugfixes * RT#45067: Date::Format with %z gives wrong results for half-hour timezones (Ernesto Hern?dez-Novich) * RT#48164: Date::Parse unable to set seconds correctly * RT#17396: Parse error for french date with 'mars' (march) as month Documentation * Fixed documentation for %e in Date::Format * Update documentation to remove Date::Format->language Enhancements * Add support for dates like Jul-13-1999 (Brett Warden) * Added Icelandic language (Tomas Edwardsson) * Added Romanian language (Doru Petrescu) * Added Russian language (Denis Poznyakov & Danil Pismenny) * Added Turkish language (Burak Gursoy) * Added Spanish language (Adrian Mugnolo) * Added Chinese language (Kang-min Liu) * Support parsing dates like 2002-02-26-10:37:21.141 as used by lpd * Support Z timezone when only the time is specified * Added METDST to Time::Zone * Added AKST/AKDT to Time::Zone Changes prior to 1.17 Change 814 on 2003/06/03 by (Graham Barr) Date::Parse - Time::Local in 5.8 does not support fractional seconds Change 813 on 2003/06/02 by (Graham Barr) Release 1.15 Change 812 on 2003/06/02 by (Graham Barr) Fix comments about Language implementation in Date::Parse (patch from Christian Hammers) Change 811 on 2003/06/02 by (Graham Barr) Fix short name for 'maart' to be 'mrt' as suggested by Frank Maas Change 810 on 2003/06/02 by (Graham Barr) Add %G format for GPS week (patch from Eric Richardson) Change 809 on 2003/06/02 by (Graham Barr) Language updates from Daniel Yacob Change 808 on 2003/06/02 by (Graham Barr) str2time("") should return undef Change 807 on 2003/06/02 by (Graham Barr) Added Swedish and Finnish languages from Matthew Musgrove Change 778 on 2003/03/03 by (Graham Barr) Added Chinese_GB language. Supplied by forehead (I don't even pretend tounderstand it) Change 777 on 2003/03/03 by (Graham Barr) Return fractional seconds when specified in an ISO date Change 776 on 2003/03/03 by (Graham Barr) New languages from Daniel Yacob Change 775 on 2003/03/03 by (Graham Barr) Fix UTC support on ISO dates Change 774 on 2003/03/03 by (Graham Barr) Allow a : in a timezone so the dates specified in RSS can be parsed (eg 2002-11-07T23:31:49-05:00) Patch from Kellan Change 773 on 2003/03/03 by (Graham Barr) Support parsing more formats Change 754 on 2002/11/03 by (Graham Barr) Release 1.14 Change 753 on 2002/11/03 by (Graham Barr) Fix bug parsing 2002-11-02 11pm Change 752 on 2002/11/03 by (Graham Barr) Add Greek language module from Matthew Musgrove Change 744 on 2002/09/16 by (Graham Barr) Add Date::Language::Brazilian and Date::Language::Danish to MANIFEST Change 743 on 2002/09/16 by (Graham Barr) Add Date::Language::Brazilian from Christian Tosta Add Date::Language::Danish from Lars Skj?lund Change 742 on 2002/09/16 by (Graham Barr) Time::Zone - Add some zones for Brazil Change 741 on 2002/09/16 by (Graham Barr) Time::Zone [cpan #1299] - Allow $ENV{TZ} to have zomes like EST5 Change 733 on 2002/06/13 by (Graham Barr) Date::Language::French - Fix missing ; Change 732 on 2002/06/06 by (Graham Barr) Release 1.13 Change 731 on 2002/06/06 by (Graham Barr) Fix pattern to allow single digits for month and day (eg '2002-6-1') Change 730 on 2002/06/03 by (Graham Barr) Release 1.12 Change 729 on 2002/06/03 by (Graham Barr) Fix month name abbreviations Change 720 on 2002/04/25 by (Graham Barr) Date::Parse - Make it work with 5.004 again Change 719 on 2002/04/25 by (Graham Barr) Prevent the ISO date pattern matching where it should not. ie there must not be a non-space character directly before the date string Change 718 on 2002/04/17 by (Graham Barr) Change French @Dsuf, from Peter Samuelson Change 712 on 2002/03/07 by (Graham Barr) Added %L format for month number as 1..12 from Adam Monsen Change 708 on 2002/02/28 by (Graham Barr) Release 1.11 Change 707 on 2002/02/28 by (Graham Barr) Fix format error in t/date.t Change 692 on 2002/01/09 by (Graham Barr) Be a bit more lenient on the ISO format Change 691 on 2002/01/02 by (Graham Barr) Fix typo in ISO-8601 formats in docs Change 690 on 2001/12/28 by (Graham Barr) Date::Format - Fix array dereference syntax typo Change 689 on 2001/12/28 by (Graham Barr) Date::Format - Fix doc typos Change 682 on 2001/11/20 by (Graham Barr) Date::Parse - Make the minutes and seconds parts of an ISO-8601 optional (patch from Christian Hammers) Change 681 on 2001/11/20 by (Graham Barr) Date::Parse - Allow AM/PM to be just A/P (eg Jul 13 1999 1:23P) as used by MySQL (patch from Drew Degentesh) Change 680 on 2001/11/20 by (Graham Barr) Time::Zone - Add CEST Central European Daylight Change 679 on 2001/11/20 by (Graham Barr) Date::Parse - Extract (but ignore) fractions of a second in an ISO8601 date string (patch from rayg at yahoo-inc.com) Change 678 on 2001/11/20 by (Graham Barr) Add %P to be am or pm Change 677 on 2001/11/20 by (Graham Barr) Date::Language::French - Um, the french have 7 days in the week just like everyone else Change 676 on 2001/11/20 by (Graham Barr) Date::Language::German - Fix abbrev for October (patch from Stefan Niederhauser) Change 634 on 2001/09/03 by (Graham Barr) Add a check for invalid years in format 1995-01-24 Change 580 on 2000/09/04 by (Graham Barr) Release 1.10 Change 579 on 2000/09/04 by (Graham Barr) Date::Parse - Support for more date formats Time::Zone - Added more zones Change 539 on 2000/06/14 by (Graham Barr) Documentation updates Change 536 on 2000/06/06 by (Graham Barr) Fix VERSION numbers Change 535 on 2000/06/06 by (Graham Barr) Date::Format - Added support for %O* to support output of roman numerals Change 443 on 2000/03/29 by (Graham Barr) Release 1.09 Change 442 on 2000/03/29 by (Graham Barr) Added PPD stuff to Makefile.PL Change 441 on 2000/03/29 by (Graham Barr) Date::Parse - Allow "s after the timezone Change 440 on 2000/03/29 by (Graham Barr) Date::Format - Fix doc for %c and %C Change 409 on 2000/03/28 by (Graham Barr) Moved .pm files into lib directory Change 408 on 2000/03/28 by (Graham Barr) str2time returns undef on error bit Time::Local returns -1. Check if the -1 is real or an error Change 407 on 2000/03/28 by (Graham Barr) Added Eastern European Summer Time EEST Change 268 on 1999/03/18 by (Graham Barr) Date::Format, Time::Zone - Fix problem with %z and %Z as suggested by Jason A Smith Change 267 on 1999/03/18 by (Graham Barr) - Make t/getdate.t more portable as suggested by Paul Schinder Change 250 on 1999/02/06 by (Graham Barr) Date::Format - Correct docs for %d and %e Change 249 on 1999/02/06 by (Graham Barr) Added Date::Language::Czech Change 180 on 1998/08/05 by (Graham Barr) Date::Language - Added Date::Language::French contributed by Emmanuel Bataille (bem@residents.frmug.org) - Split out the languages into .pm's Date::Parse - Added patch from Alan Burlison to Date::Parse to allow zone offests +7, +10 and +700 - Parse now supports GMT+0100 *** Release 1.08 Fri Jan 2 1998 (Graham Barr) Date::Format, Time::Zone - Fix for formatting %z and %Z all - Update Email address and year Tue Feb 17 1998 (Graham Barr) Date::Language - Added format_o to German Fri Sep 12 1997 (Graham Barr) Date::Parse - Added 'DST' to parser, it adjusts $zone by 3600 (but that may not be right in all cases) - Added a check to str2time to ensure valid values are passed to Time::Local, to avoid croak-ing - Fixed to treat AM and PM correctly when the hour is 12. (I hope :-) Time::Zone - Modified for Western Australia Tue 07 Jan 1996 o Release 1.07 o Fixed a problem in Time::Zone (had @l[8] instead of $l[8], doh! ) Thu 02 Jan 1996 o Release 1.06 o Fixed t/getdate.t o Date::Parse can now parse the date-format 960913, which apparently is fairly common in sweden. Wed 31 Jul 1996 o Release 1.05 o Modified Date::Format not to use single letter sub names, all format sub names are nore prefixed with format_ o Cleaned up Date/Format.pm so that AUTOLOAD is not required o Patched Date/Language.pm to add Norwegian. Thanks to Gisle Aas for the patch Thu 27 Jun 1996 o Added %z to Date::Format to output timezone in +/-0000 format o Added multi-language support via Date::Language,. Tue 25 Jun 1996 o Some code tidying up o added a new test, copied from Date::GetDate o improved performance Wed 22 May 1996 o Fixed a bug in the parser for dates in a default (local) timezone but a different dst Wed 15 May 1996 o Added support for mainframe type dates Fri 3 May 1996 o Added %s to date formatting at request of Josh Osborne . META.yml100644000765000024 4032415157412057 14437 0ustar00nicolasstaff000000000000TimeDate-2.35--- abstract: 'Date and time formatting subroutines' author: - 'Graham ' build_requires: ExtUtils::MakeMaker: '0' File::Spec: '0' Test::More: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'Dist::Zilla version 6.033, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: TimeDate provides: Date::Format: file: lib/Date/Format.pm version: '2.35' Date::Format::Generic: file: lib/Date/Format/Generic.pm version: '2.35' Date::Language: file: lib/Date/Language.pm version: '2.35' Date::Language::Afar: file: lib/Date/Language/Afar.pm version: '2.35' Date::Language::Amharic: file: lib/Date/Language/Amharic.pm version: '2.35' Date::Language::Arabic: file: lib/Date/Language/Arabic.pm version: '2.35' Date::Language::Austrian: file: lib/Date/Language/Austrian.pm version: '2.35' Date::Language::Brazilian: file: lib/Date/Language/Brazilian.pm version: '2.35' Date::Language::Bulgarian: file: lib/Date/Language/Bulgarian.pm version: '2.35' Date::Language::Chinese: file: lib/Date/Language/Chinese.pm version: '2.35' Date::Language::Chinese_GB: file: lib/Date/Language/Chinese_GB.pm version: '2.35' Date::Language::Czech: file: lib/Date/Language/Czech.pm version: '2.35' Date::Language::Danish: file: lib/Date/Language/Danish.pm version: '2.35' Date::Language::Dutch: file: lib/Date/Language/Dutch.pm version: '2.35' Date::Language::English: file: lib/Date/Language/English.pm version: '2.35' Date::Language::Finnish: file: lib/Date/Language/Finnish.pm version: '2.35' Date::Language::French: file: lib/Date/Language/French.pm version: '2.35' Date::Language::Gedeo: file: lib/Date/Language/Gedeo.pm version: '2.35' Date::Language::German: file: lib/Date/Language/German.pm version: '2.35' Date::Language::Greek: file: lib/Date/Language/Greek.pm version: '2.35' Date::Language::Hungarian: file: lib/Date/Language/Hungarian.pm version: '2.35' Date::Language::Icelandic: file: lib/Date/Language/Icelandic.pm version: '2.35' Date::Language::Italian: file: lib/Date/Language/Italian.pm version: '2.35' Date::Language::Norwegian: file: lib/Date/Language/Norwegian.pm version: '2.35' Date::Language::Occitan: file: lib/Date/Language/Occitan.pm version: '2.35' Date::Language::Oromo: file: lib/Date/Language/Oromo.pm version: '2.35' Date::Language::Portuguese: file: lib/Date/Language/Portuguese.pm version: '2.35' Date::Language::Romanian: file: lib/Date/Language/Romanian.pm version: '2.35' Date::Language::Russian: file: lib/Date/Language/Russian.pm version: '2.35' Date::Language::Russian_cp1251: file: lib/Date/Language/Russian_cp1251.pm version: '2.35' Date::Language::Russian_koi8r: file: lib/Date/Language/Russian_koi8r.pm version: '2.35' Date::Language::Sidama: file: lib/Date/Language/Sidama.pm version: '2.35' Date::Language::Somali: file: lib/Date/Language/Somali.pm version: '2.35' Date::Language::Spanish: file: lib/Date/Language/Spanish.pm version: '2.35' Date::Language::Swedish: file: lib/Date/Language/Swedish.pm version: '2.35' Date::Language::Tigrinya: file: lib/Date/Language/Tigrinya.pm version: '2.35' Date::Language::TigrinyaEritrean: file: lib/Date/Language/TigrinyaEritrean.pm version: '2.35' Date::Language::TigrinyaEthiopian: file: lib/Date/Language/TigrinyaEthiopian.pm version: '2.35' Date::Language::Turkish: file: lib/Date/Language/Turkish.pm version: '2.35' Date::Parse: file: lib/Date/Parse.pm version: '2.35' Time::Zone: file: lib/Time/Zone.pm version: '2.35' TimeDate: file: lib/TimeDate.pm version: '2.35' requires: Carp: '0' resources: bugtracker: https://github.com/cpan-authors/TimeDate/issues repository: https://github.com/cpan-authors/TimeDate.git version: '2.35' x_Dist_Zilla: perl: version: '5.038004' plugins: - class: Dist::Zilla::Plugin::OurPkgVersion name: OurPkgVersion version: '0.21' - class: Dist::Zilla::Plugin::Test::Compile config: Dist::Zilla::Plugin::Test::Compile: bail_out_on_fail: 0 fail_on_warning: author fake_home: 0 filename: xt/author/00-compile.t module_finder: - ':InstallModules' needs_display: 0 phase: develop script_finder: - ':PerlExecFiles' skips: [] switch: [] name: Test::Compile version: '2.058' - class: Dist::Zilla::Plugin::MetaTests name: MetaTests version: '6.033' - class: Dist::Zilla::Plugin::Test::NoTabs config: Dist::Zilla::Plugin::Test::NoTabs: filename: xt/author/no-tabs.t finder: - ':InstallModules' - ':ExecFiles' - ':TestFiles' name: Test::NoTabs version: '0.15' - class: Dist::Zilla::Plugin::PodSyntaxTests name: PodSyntaxTests version: '6.033' - class: Dist::Zilla::Plugin::Test::ReportPrereqs name: Test::ReportPrereqs version: '0.029' - class: Dist::Zilla::Plugin::PodWeaver config: Dist::Zilla::Plugin::PodWeaver: finder: - ':InstallModules' - ':PerlExecFiles' plugins: - class: Pod::Weaver::Plugin::EnsurePod5 name: '@CorePrep/EnsurePod5' version: '4.020' - class: Pod::Weaver::Plugin::H1Nester name: '@CorePrep/H1Nester' version: '4.020' - class: Pod::Weaver::Plugin::SingleEncoding name: '@Default/SingleEncoding' version: '4.020' - class: Pod::Weaver::Section::Name name: '@Default/Name' version: '4.020' - class: Pod::Weaver::Section::Version name: '@Default/Version' version: '4.020' - class: Pod::Weaver::Section::Region name: '@Default/prelude' version: '4.020' - class: Pod::Weaver::Section::Generic name: SYNOPSIS version: '4.020' - class: Pod::Weaver::Section::Generic name: DESCRIPTION version: '4.020' - class: Pod::Weaver::Section::Generic name: OVERVIEW version: '4.020' - class: Pod::Weaver::Section::Collect name: ATTRIBUTES version: '4.020' - class: Pod::Weaver::Section::Collect name: METHODS version: '4.020' - class: Pod::Weaver::Section::Collect name: FUNCTIONS version: '4.020' - class: Pod::Weaver::Section::Leftovers name: '@Default/Leftovers' version: '4.020' - class: Pod::Weaver::Section::Region name: '@Default/postlude' version: '4.020' - class: Pod::Weaver::Section::Authors name: '@Default/Authors' version: '4.020' - class: Pod::Weaver::Section::Legal name: '@Default/Legal' version: '4.020' name: PodWeaver version: '4.010' - class: Dist::Zilla::Plugin::RunExtraTests config: Dist::Zilla::Role::TestRunner: default_jobs: 1 name: RunExtraTests version: '0.029' - class: Dist::Zilla::Plugin::MetaJSON name: MetaJSON version: '6.033' - class: Dist::Zilla::Plugin::MetaConfig name: MetaConfig version: '6.033' - class: Dist::Zilla::Plugin::MetaProvides::Package config: Dist::Zilla::Plugin::MetaProvides::Package: finder_objects: - class: Dist::Zilla::Plugin::FinderCode name: MetaProvides::Package/AUTOVIV/:InstallModulesPM version: '6.033' include_underscores: 0 Dist::Zilla::Role::MetaProvider::Provider: $Dist::Zilla::Role::MetaProvider::Provider::VERSION: '2.002004' inherit_missing: 1 inherit_version: 1 meta_noindex: 1 Dist::Zilla::Role::ModuleMetadata: Module::Metadata: '1.000037' version: '0.006' name: MetaProvides::Package version: '2.004003' - class: Dist::Zilla::Plugin::NextRelease name: NextRelease version: '6.033' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: runtime type: requires name: RuntimeRequires version: '6.033' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: test type: requires name: TestRequires version: '6.033' - class: Dist::Zilla::Plugin::TestRelease name: TestRelease version: '6.033' - class: Dist::Zilla::Plugin::Test::MinimumVersion config: Dist::Zilla::Plugin::Test::MinimumVersion: max_target_perl: '5.010' name: Test::MinimumVersion version: '2.000011' - class: Dist::Zilla::Plugin::Git::Check config: Dist::Zilla::Plugin::Git::Check: untracked_files: die Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - Changes - README.md - dist.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: git_version: '2.50.1 (Apple Git-155)' repo_root: . name: '@Git/Check' version: '2.051' - class: Dist::Zilla::Plugin::Git::Commit config: Dist::Zilla::Plugin::Git::Commit: add_files_in: - Changes - README.md - dist.ini commit_msg: v%V%n%n%c signoff: 0 Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - Changes - README.md - dist.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: git_version: '2.50.1 (Apple Git-155)' repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@Git/Commit' version: '2.051' - class: Dist::Zilla::Plugin::Git::Tag config: Dist::Zilla::Plugin::Git::Tag: branch: ~ changelog: Changes signed: 0 tag: v2.35 tag_format: v%V tag_message: v%V Dist::Zilla::Role::Git::Repo: git_version: '2.50.1 (Apple Git-155)' repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@Git/Tag' version: '2.051' - class: Dist::Zilla::Plugin::Git::Push config: Dist::Zilla::Plugin::Git::Push: push_to: - origin - 'origin HEAD:refs/heads/released' remotes_must_exist: 1 Dist::Zilla::Role::Git::Repo: git_version: '2.50.1 (Apple Git-155)' repo_root: . name: '@Git/Push' version: '2.051' - class: Dist::Zilla::Plugin::Run::BeforeBuild config: Dist::Zilla::Plugin::Run::Role::Runner: fatal_errors: 1 quiet: 0 version: '0.050' name: Run::BeforeBuild version: '0.050' - class: Dist::Zilla::Plugin::Run::AfterBuild config: Dist::Zilla::Plugin::Run::Role::Runner: fatal_errors: 1 quiet: 0 run: - 'cp %d/Makefile.PL ./' - "git status --porcelain | grep 'M Makefile.PL' && git commit -m 'Makefile.PL auto-updated by dist.ini' Makefile.PL && echo \"# Makefile.PL auto-update\" || echo \"# Makefile.PL up to date\"" version: '0.050' name: Run::AfterBuild version: '0.050' - class: Dist::Zilla::Plugin::Git::NextVersion config: Dist::Zilla::Plugin::Git::NextVersion: first_version: '0.001' version_by_branch: 0 version_regexp: (?^:^v(.+)$) Dist::Zilla::Role::Git::Repo: git_version: '2.50.1 (Apple Git-155)' repo_root: . name: Git::NextVersion version: '2.051' - class: Dist::Zilla::Plugin::PruneCruft name: '@Filter/PruneCruft' version: '6.033' - class: Dist::Zilla::Plugin::ManifestSkip name: '@Filter/ManifestSkip' version: '6.033' - class: Dist::Zilla::Plugin::MetaYAML name: '@Filter/MetaYAML' version: '6.033' - class: Dist::Zilla::Plugin::License name: '@Filter/License' version: '6.033' - class: Dist::Zilla::Plugin::Readme name: '@Filter/Readme' version: '6.033' - class: Dist::Zilla::Plugin::ExecDir name: '@Filter/ExecDir' version: '6.033' - class: Dist::Zilla::Plugin::ShareDir name: '@Filter/ShareDir' version: '6.033' - class: Dist::Zilla::Plugin::MakeMaker config: Dist::Zilla::Role::TestRunner: default_jobs: 1 name: '@Filter/MakeMaker' version: '6.033' - class: Dist::Zilla::Plugin::Manifest name: '@Filter/Manifest' version: '6.033' - class: Dist::Zilla::Plugin::TestRelease name: '@Filter/TestRelease' version: '6.033' - class: Dist::Zilla::Plugin::ConfirmRelease name: '@Filter/ConfirmRelease' version: '6.033' - class: Dist::Zilla::Plugin::UploadToCPAN name: '@Filter/UploadToCPAN' version: '6.033' - class: Dist::Zilla::Plugin::GatherDir config: Dist::Zilla::Plugin::GatherDir: exclude_filename: - CLAUDE.md - Makefile.PL exclude_match: [] follow_symlinks: 0 include_dotfiles: 0 prefix: '' prune_directory: [] root: . name: GatherDir version: '6.033' - class: Dist::Zilla::Plugin::MetaResources name: MetaResources version: '6.033' - class: Dist::Zilla::Plugin::PruneFiles name: PruneFiles version: '6.033' - class: Dist::Zilla::Plugin::InsertExample name: InsertExample version: '0.15' - class: Dist::Zilla::Plugin::Test::Synopsis name: Test::Synopsis version: '2.000007' - class: Dist::Zilla::Plugin::ReadmeAnyFromPod config: Dist::Zilla::Role::FileWatcher: version: '0.006' name: ReadmeAnyFromPod version: '0.163250' - class: Dist::Zilla::Plugin::FinderCode name: ':InstallModules' version: '6.033' - class: Dist::Zilla::Plugin::FinderCode name: ':IncModules' version: '6.033' - class: Dist::Zilla::Plugin::FinderCode name: ':TestFiles' version: '6.033' - class: Dist::Zilla::Plugin::FinderCode name: ':ExtraTestFiles' version: '6.033' - class: Dist::Zilla::Plugin::FinderCode name: ':ExecFiles' version: '6.033' - class: Dist::Zilla::Plugin::FinderCode name: ':PerlExecFiles' version: '6.033' - class: Dist::Zilla::Plugin::FinderCode name: ':ShareFiles' version: '6.033' - class: Dist::Zilla::Plugin::FinderCode name: ':MainModule' version: '6.033' - class: Dist::Zilla::Plugin::FinderCode name: ':AllFiles' version: '6.033' - class: Dist::Zilla::Plugin::FinderCode name: ':NoFiles' version: '6.033' - class: Dist::Zilla::Plugin::FinderCode name: MetaProvides::Package/AUTOVIV/:InstallModulesPM version: '6.033' zilla: class: Dist::Zilla::Dist::Builder config: is_trial: 0 version: '6.033' x_generated_by_perl: v5.38.4 x_serialization_backend: 'YAML::Tiny version 1.76' x_spdx_expression: 'Artistic-1.0-Perl OR GPL-1.0-or-later' MANIFEST100644000765000024 360115157412057 14274 0ustar00nicolasstaff000000000000TimeDate-2.35# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.033. Changes LICENSE MANIFEST META.json META.yml Makefile.PL README SECURITY.md dist.ini lib/Date/Format.pm lib/Date/Format/Generic.pm lib/Date/Language.pm lib/Date/Language/Afar.pm lib/Date/Language/Amharic.pm lib/Date/Language/Arabic.pm lib/Date/Language/Austrian.pm lib/Date/Language/Brazilian.pm lib/Date/Language/Bulgarian.pm lib/Date/Language/Chinese.pm lib/Date/Language/Chinese_GB.pm lib/Date/Language/Czech.pm lib/Date/Language/Danish.pm lib/Date/Language/Dutch.pm lib/Date/Language/English.pm lib/Date/Language/Finnish.pm lib/Date/Language/French.pm lib/Date/Language/Gedeo.pm lib/Date/Language/German.pm lib/Date/Language/Greek.pm lib/Date/Language/Hungarian.pm lib/Date/Language/Icelandic.pm lib/Date/Language/Italian.pm lib/Date/Language/Norwegian.pm lib/Date/Language/Occitan.pm lib/Date/Language/Oromo.pm lib/Date/Language/Portuguese.pm lib/Date/Language/Romanian.pm lib/Date/Language/Russian.pm lib/Date/Language/Russian_cp1251.pm lib/Date/Language/Russian_koi8r.pm lib/Date/Language/Sidama.pm lib/Date/Language/Somali.pm lib/Date/Language/Spanish.pm lib/Date/Language/Swedish.pm lib/Date/Language/Tigrinya.pm lib/Date/Language/TigrinyaEritrean.pm lib/Date/Language/TigrinyaEthiopian.pm lib/Date/Language/Turkish.pm lib/Date/Parse.pm lib/Time/Zone.pm lib/TimeDate.pm t/00-report-prereqs.dd t/00-report-prereqs.t t/cpanrt-format.t t/cpanrt-language.t t/cpanrt-overflow.t t/cpanrt-parse.t t/cpanrt-zone.t t/date.t t/edge-cases.t t/format.t t/getdate.t t/gh10.t t/gh12.t t/lang-data.t t/lang-encoding.t t/lang.t t/msk-tz.t t/pod-valid.t t/rt-format.t t/rt-parse.t t/rt-timezone.t t/rt106105.t t/rt52387.t t/rt57800.t t/str2time-epoch.t t/strptime-iso8601.t t/time2str-lang.t t/tz-lang.t t/zone.t xt/author/00-compile.t xt/author/distmeta.t xt/author/minimum-version.t xt/author/no-tabs.t xt/author/pod-syntax.t xt/author/synopsis.t dist.ini100644000765000024 441115157412057 14607 0ustar00nicolasstaff000000000000TimeDate-2.35name = TimeDate author = Graham license = Perl_5 copyright_holder = Graham Barr copyright_year = 2020 ;[PPPort] ;[PkgVersion] [OurPkgVersion] [Test::Compile] xt_mode = 1 [MetaTests] [Test::NoTabs] [PodSyntaxTests] [Test::ReportPrereqs] [PodWeaver] [RunExtraTests] [MetaJSON] ;[MinimumPerlFast] ;min = 5.010 ; undocumented config! ;max = 5.010 ; undocumented config! [MetaConfig] [MetaProvides::Package] [NextRelease] filename = Changes ;[Prereqs::FromCPANfile] ;[Prereqs / RuntimeRecommends] [Prereqs / RuntimeRequires] Carp = 0 ;[Prereqs / TestRecommends] [Prereqs / TestRequires] ;Test2::Bundle::Extended = 0 ;Test2::Tools::Explain = 0 ;Test2::Plugin::NoWarnings = 0 ;Devel::Peek = 0 [TestRelease] [Test::MinimumVersion] max_target_perl = 5.010 [@Git] allow_dirty = Changes allow_dirty = dist.ini allow_dirty = README.md add_files_in = Changes add_files_in = dist.ini add_files_in = README.md push_to = origin push_to = origin HEAD:refs/heads/released ; also push to released branch [Run::BeforeBuild] ; force to refresh Makefile.PL for every build [not really necessary as we have one exclude_filename] ; run = ( test -f Makefile.PL && rm Makefile.PL ) ||: [Run::AfterBuild] ; provide a friendly Makefile.PL in our repo ; very useful so Travis CI can use it without installing Dist::Zilla::* run = cp %d/Makefile.PL ./ run = git status --porcelain | grep 'M Makefile.PL' && git commit -m 'Makefile.PL auto-updated by dist.ini' Makefile.PL && echo "# Makefile.PL auto-update" || echo "# Makefile.PL up to date" [Git::NextVersion] [@Filter] -bundle = @Basic ;-remove = AutoPrereqs -remove = ExtraTests -remove = GatherDir [GatherDir] exclude_filename = Makefile.PL exclude_filename = CLAUDE.md ;exclude_filename = ppport.h ; -- static meta-information [MetaResources] bugtracker.web = https://github.com/cpan-authors/TimeDate/issues repository.url = https://github.com/cpan-authors/TimeDate.git repository.web = https://github.com/cpan-authors/TimeDate repository.type = git [PruneFiles] match = ~$ ; emacs backup files ;[PodCoverageTests] ;[Test::EOL] ; still a work in progress ;[Test::TidyAll] ;minimum_perl = 5.010 ;jobs = 1 ;verbose = 1 [InsertExample] [Test::Synopsis] [ReadmeAnyFromPod] type = gfm filename = README.md location = root t000755000765000024 015157412057 13246 5ustar00nicolasstaff000000000000TimeDate-2.35zone.t100644000765000024 740315157412057 14552 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More; use Time::Zone; # tz_offset: standard timezone abbreviations is(tz_offset("GMT"), 0, "tz_offset GMT = 0"); is(tz_offset("UTC"), 0, "tz_offset UTC = 0"); is(tz_offset("EST"), -18000, "tz_offset EST = -18000"); is(tz_offset("CST"), -21600, "tz_offset CST = -21600"); is(tz_offset("MST"), -25200, "tz_offset MST = -25200"); is(tz_offset("PST"), -28800, "tz_offset PST = -28800"); is(tz_offset("CET"), 3600, "tz_offset CET = 3600"); is(tz_offset("JST"), 32400, "tz_offset JST = 32400"); is(tz_offset("IST"), 19800, "tz_offset IST = 19800"); is(tz_offset("NST"), -12600, "tz_offset NST = -12600 (Newfoundland Standard)"); is(tz_offset("NFT"), -12600, "tz_offset NFT = -12600 (Newfoundland)"); # tz_offset: Newfoundland Daylight (half-hour DST) is(tz_offset("NDT"), -9000, "tz_offset NDT = -9000 (Newfoundland Daylight)"); # tz_offset: DST timezone abbreviations is(tz_offset("EDT"), -14400, "tz_offset EDT = -14400"); is(tz_offset("CDT"), -18000, "tz_offset CDT = -18000"); is(tz_offset("MDT"), -21600, "tz_offset MDT = -21600"); is(tz_offset("PDT"), -25200, "tz_offset PDT = -25200"); is(tz_offset("BST"), 3600, "tz_offset BST = 3600"); is(tz_offset("CEST"), 7200, "tz_offset CEST = 7200"); # tz_offset: numeric offsets is(tz_offset("+0000"), 0, "tz_offset +0000 = 0"); is(tz_offset("-0500"), -18000, "tz_offset -0500 = -18000"); is(tz_offset("+0530"), 19800, "tz_offset +0530 = 19800"); is(tz_offset("+0900"), 32400, "tz_offset +0900 = 32400"); is(tz_offset("-0800"), -28800, "tz_offset -0800 = -28800"); # tz_offset: Southeast Asian timezones (RT#123247) is(tz_offset("ICT"), 25200, "tz_offset ICT = 25200 (Indochina Time, UTC+7)"); is(tz_offset("PHT"), 28800, "tz_offset PHT = 28800 (Philippine Time, UTC+8)"); is(tz_offset("ict"), 25200, "tz_offset ict case insensitive"); is(tz_offset("pht"), 28800, "tz_offset pht case insensitive"); # tz_offset: unknown zone returns undef is(tz_offset("BOGUS"), undef, "tz_offset unknown zone returns undef"); # tz_offset: case insensitivity is(tz_offset("gmt"), 0, "tz_offset case insensitive: gmt"); is(tz_offset("est"), -18000, "tz_offset case insensitive: est"); # tz_name: with explicit $dst parameter (deterministic, no system-time dependency) # When $dst=0, offset -18000 (-5h) should resolve to a standard timezone (EST) # When $dst=1, offset -18000 (-5h) should resolve to a DST timezone (CDT) is(tz_name(-18000, 0), "est", "tz_name(-18000, dst=0) is est"); is(tz_name(-18000, 1), "cdt", "tz_name(-18000, dst=1) is cdt"); # tz_name: offset 0 is always GMT/UTC regardless of DST flag like(tz_name(0, 0), qr/^(?:gmt|utc)$/i, "tz_name(0, dst=0) is GMT or UTC"); like(tz_name(0, 1), qr/^(?:gmt|utc)$/i, "tz_name(0, dst=1) is GMT or UTC"); # tz_name: offsets with only standard or only DST entries is(tz_name(32400, 0), "jst", "tz_name(32400, dst=0) is jst (Japan Standard)"); is(tz_name(-25200, 1), "pdt", "tz_name(-25200, dst=1) is pdt (Pacific Daylight)"); is(tz_name(-28800, 0), "pst", "tz_name(-28800, dst=0) is pst (Pacific Standard)"); # tz_name: unknown offset returns correct +HHMM numeric string (RT#59298) # 5400s = 90 minutes = UTC+1:30 → "+0130" (not "+9000" which the buggy code produced) is(tz_name(5400, 0), "+0130", "tz_name(5400) returns +0130 (UTC+1:30)"); # Negative fractional-hour offset: -5400s = UTC-1:30 → "-0130" # (Note: -9000 is now NDT/Newfoundland Daylight, so use -5400 instead) is(tz_name(-5400, 0), "-0130", "tz_name(-5400) returns -0130 (UTC-1:30)"); # tz_local_offset: returns a sane value { my $offset = tz_local_offset(); ok(defined $offset, "tz_local_offset returns defined value"); cmp_ok($offset, '>=', -12 * 3600, "tz_local_offset >= -12 hours"); cmp_ok($offset, '<=', 14 * 3600, "tz_local_offset <= 14 hours"); } done_testing; gh12.t100644000765000024 220415157412057 14332 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 3; use Date::Parse qw(strptime str2time); # GH#12 / RT#84075: Date::Parse::str2time maps date in 1963 to 2063 # Root cause: str2time passed a 2-digit year to timegm, triggering its 50-year # sliding window. The fix: strptime extracts the century and returns year as # offset-from-1900; str2time reconstructs the full 4-digit year before calling # timegm, bypassing the windowing entirely. { my $this_year = 1900 + (gmtime(time))[5]; my $target_year = $this_year - 50; my $date = "$target_year-01-01 00:00:00 UTC"; my $time = str2time($date); my $year_parsed_as = 1900 + (gmtime($time))[5]; is($year_parsed_as, $target_year, "GH#12: year $target_year not mapped to future"); # Canonical example from the original bug report (year 1963) my $t1963 = str2time("1963-12-31 23:59:59 UTC"); my $got1963 = 1900 + (gmtime($t1963))[5]; is($got1963, 1963, "GH#12: 1963-12-31 not mapped to 2063"); # strptime must capture the century for 4-digit years my @t = strptime("1963-12-31 23:59:59 UTC"); is($t[7], 19, "GH#12: strptime century field is 19 for 1963"); } date.t100644000765000024 1177715157412057 14545 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More; use Date::Parse; use Date::Format qw(time2str); my @data = split /\n/, <<'DATA'; 1995-01-24 1995-01-24T09:08:17.1823213 - 1935-01-24T09:08:17 - Fri Dec 17 00:00:00 1901 GMT Tue Jan 16 23:59:59 2038 GMT 2001-02-02 00:00:00 GMT 2035-02-02 00:00:00 GMT - 16 Jun 33 07:29:35 CST 2002-02-26-10:37:21.141 GMT Wed, 16 Jun 94 07:29:35 CST Wed, 16 Nov 94 07:29:35 CST Mon, 21 Nov 94 07:42:23 CST Mon, 21 Nov 94 04:28:18 CST Tue, 15 Nov 94 09:15:10 GMT Wed, 16 Nov 94 09:39:49 GMT Wed, 16 Nov 94 09:23:17 GMT Wed, 16 Nov 94 12:39:49 GMT Wed, 16 Nov 94 14:03:06 GMT Wed, 16 Nov 94 05:30:51 CST Thu, 17 Nov 94 03:19:30 CST Mon, 21 Nov 94 14:05:32 GMT Mon, 14 Nov 94 15:08:49 CST Wed, 16 Nov 94 14:48:06 GMT Thu, 17 Nov 94 14:22:03 GMT Wed, 16 Nov 94 14:36:00 GMT Wed, 16 Nov 94 09:23:17 GMT Wed, 16 Nov 94 10:01:43 GMT Wed, 16 Nov 94 15:03:35 GMT Mon, 21 Nov 94 13:55:19 GMT Wed, 16 Nov 94 08:46:11 CST 21 dec 17:05 21-dec 17:05 21/dec 17:05 21/dec/93 17:05 dec/21/93 17:05 Dec/21/1993 17:05:00 dec-21-1993 17:05 Dec-21-93 17:05:00 dec 21 1994 17:05 dec 21 94 17:05 dec 21 94 17:05 GMT dec 21 94 17:05 BST dec 21 94 00:05 -1700 dec 21 94 17:05 -1700 Wed, 9 Nov 1994 09:50:32 -0500 (EST) Thu, 13 Oct 94 10:13:13 -0700 Sat, 19 Nov 1994 16:59:14 +0100 Thu, 3 Nov 94 14:10:47 EST Thu, 3 Nov 94 21:51:09 EST Fri, 4 Nov 94 9:24:52 EST Wed, 9 Nov 94 09:38:54 EST Mon, 14 Nov 94 13:20:12 EST Wed, 16 Nov 94 17:09:13 EST Tue, 15 Nov 94 12:27:01 PST Fri, 18 Nov 1994 07:34:05 -0600 Mon, 21 Nov 94 14:34:28 -0500 Fri, 18 Nov 1994 12:05:47 -0800 (PST) Fri, 18 Nov 1994 12:36:26 -0800 (PST) Wed, 16 Nov 1994 15:58:58 GMT 2000 10:02:18 "GMT" Sun, 06 Nov 94 14:27:40 -0500 Mon, 07 Nov 94 08:20:13 -0500 Mon, 07 Nov 94 16:48:42 -0500 Wed, 09 Nov 94 15:46:16 -0500 Fri, 4 Nov 94 16:17:40 "PST Wed, 16 Nov 94 12:43:37 "PST Sun, 6 Nov 1994 02:38:17 -0800 Tue, 1 Nov 1994 13:53:49 -0500 Tue, 15 Nov 94 08:31:59 +0100 Sun, 6 Nov 1994 11:09:12 -0500 (IST) Fri, 4 Nov 94 12:52:10 EST Mon, 31 Oct 1994 14:17:39 -0500 (EST) Mon, 14 Nov 94 11:25:00 CST Mon, 14 Nov 94 13:26:29 CST Fri, 18 Nov 94 8:42:47 CST Thu, 17 Nov 94 14:32:01 +0900 Wed, 2 Nov 94 18:16:31 +0100 Fri, 18 Nov 94 10:46:26 +0100 Tue, 8 Nov 1994 22:39:28 +0200 Wed, 16 Nov 1994 10:01:08 -0500 (EST) Wed, 2 Nov 1994 16:59:42 -0800 Wed, 9 Nov 94 10:00:23 PST Fri, 18 Nov 94 17:01:43 PST Mon, 14 Nov 1994 14:47:46 -0500 Mon, 21 Nov 1994 04:56:04 -0500 (EST) Mon, 21 Nov 1994 11:50:12 -0800 Sat, 5 Nov 1994 14:04:16 -0600 (CST) Sat, 05 Nov 94 13:10:13 MST Wed, 02 Nov 94 10:47:48 -0800 Wed, 02 Nov 94 13:19:15 -0800 Thu, 03 Nov 94 15:27:07 -0800 Fri, 04 Nov 94 09:12:12 -0800 Wed, 9 Nov 1994 10:13:03 +0000 (GMT) Wed, 9 Nov 1994 15:28:37 +0000 (GMT) Wed, 2 Nov 1994 17:37:41 +0100 (MET) 05 Nov 94 14:22:19 PST 16 Nov 94 22:28:20 PST Tue, 1 Nov 1994 19:51:15 -0800 Wed, 2 Nov 94 12:21:23 GMT Fri, 18 Nov 94 18:07:03 GMT Wed, 16 Nov 1994 11:26:27 -0500 Sun, 6 Nov 1994 13:48:49 -0500 Tue, 8 Nov 1994 13:19:37 -0800 Fri, 18 Nov 1994 11:01:12 -0800 Mon, 21 Nov 1994 00:47:58 -0500 Mon, 7 Nov 1994 14:22:48 -0800 (PST) Wed, 16 Nov 1994 15:56:45 -0800 (PST) Thu, 3 Nov 1994 13:17:47 +0000 Wed, 9 Nov 1994 17:32:50 -0500 (EST) Wed, 9 Nov 94 16:31:52 PST Wed, 09 Nov 94 10:41:10 -0800 Wed, 9 Nov 94 08:42:22 MST Mon, 14 Nov 1994 08:32:13 -0800 Mon, 14 Nov 1994 11:34:32 -0500 (EST) Mon, 14 Nov 94 16:48:09 GMT Tue, 15 Nov 1994 10:27:33 +0000 Wed, 02 Nov 94 13:56:54 MST Thu, 03 Nov 94 15:24:45 MST Thu, 3 Nov 1994 15:13:53 -0700 (MST) Fri, 04 Nov 94 08:15:13 MST Thu, 3 Nov 94 18:15:47 EST Tue, 08 Nov 94 07:02:33 MST Thu, 3 Nov 94 18:15:47 EST Tue, 15 Nov 94 07:26:05 MST Wed, 2 Nov 1994 00:00:55 -0600 (CST) Sun, 6 Nov 1994 01:19:13 -0600 (CST) Mon, 7 Nov 1994 23:16:57 -0600 (CST) Tue, 08 Nov 1994 13:21:21 -0600 Mon, 07 Nov 94 13:47:37 PST Tue, 08 Nov 94 11:23:19 PST Tue, 01 Nov 1994 11:28:25 -0800 Tue, 15 Nov 1994 13:11:47 -0800 Tue, 15 Nov 1994 13:18:38 -0800 Tue, 15 Nov 1994 0:18:38 -0800 10:00:00Z 10:00:00 10:00 10:00 +100 10:00 +0100 20020722T100000Z Jul 22 10:00:00 UTC 2002 2002-07-22 10:00:00Z 2002-07-22 10:00:00 Z 2002-07-22 10:00 Z 2002-07-22 10:00Z 2002-07-22 10:00 +100 2002-07-22 10:00 +0100 2002-Jul-22 10:00:00.000000 2002-July-22 10:00:00.000000 DATA ok(!defined(str2time("")), "empty string returns undef"); # NOTE: the "2000 10:02:18 GMT" entry above uses a leap year (2000) deliberately. # When only a year is given, str2time fills in the current month/day. On Feb 29 # the year must be a leap year or the date is invalid and the test fails. # See: https://github.com/atoomic/perl-TimeDate/issues/28 for my $date (@data) { my $pre_1970 = ($date =~ s/^-\s*//); SKIP: { skip "pre-1970 dates on Win32", 1 if $pre_1970 && $^O eq "MSWin32"; my $time = str2time($date); if (defined $time) { $time = int $time; my $formatted = time2str("%a %b %e %T %Y %Z", $time, 'GMT'); my $reparsed = str2time($formatted); is($reparsed, $time, "round-trip: $date"); } else { fail("parse failed: $date"); } } } done_testing; lang.t100644000765000024 73715157412057 14503 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More; use Date::Language; my $time = time; my @lang = qw( English German Italian Bulgarian French Spanish Swedish Norwegian Danish Dutch Romanian Czech Hungarian Finnish Austrian Brazilian Portuguese Turkish ); for my $lang (@lang) { my $l = Date::Language->new($lang); my $str = $l->ctime($time); my $parsed = $l->str2time($str); is($parsed, $time, "$lang: round-trip ctime/str2time"); } done_testing; gh10.t100644000765000024 454115157412057 14336 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; # GH#10 / RT#80649: Wrong timezone abbreviation during DST fall-back # # format_Z was calling timelocal() to reconstruct the original epoch from # broken-down time. During the "fall-back" hour, the broken-down time is # ambiguous (1:xx AM occurs twice: once in PDT and once in PST). timelocal() # resolves the ambiguity to the first occurrence (PDT), returning the PDT # epoch (offset -25200). tz_name(-25200, dst=0) then finds -25200 in %zoneOff # as "mst" (Mountain Standard), yielding MST instead of PST. # # Fix: use the original epoch stored in $_[0]->[9] instead of timelocal(). # # The TZ is set in a BEGIN block so the C library timezone is initialised # before any module loads and before any localtime/tzset calls happen. # Using a runtime $ENV{TZ} assignment after `use` statements is unreliable # because `use` executes at compile time, and on some platforms restoring a # `local $ENV{TZ}` automatically resets the C library timezone, which a later # POSIX::tzset() call may not fully undo. BEGIN { $ENV{TZ} = 'America/Los_Angeles'; require POSIX; eval { POSIX::tzset() }; } use POSIX qw(); use Test::More; use Date::Format qw(time2str); # Skip the whole file if the platform does not support IANA timezone names. # Use epoch 1352019262 (2012-11-04 01:04:22 PDT): DST=1 in America/Los_Angeles # but DST=0 in UTC, so this check actually distinguishes the two and won't # produce a false-positive on a UTC-only system. my $has_la_tz = eval { my @lt = localtime(1352019262); # 2012-11-04 01:04:22 PDT (before fall-back) $lt[8] == 1; # Expect DST flag = 1 in PDT }; plan( skip_all => "system does not support America/Los_Angeles timezone" ) unless $has_la_tz; plan tests => 3; # 2012-11-04 01:25:05 PST — the second occurrence of 01:xx AM after fall-back # This is the timestamp from the original bug report that returned MST. is( time2str("%Z", 1352021105), "PST", "GH#10/RT#80649: repeated hour after fall-back formats as PST, not MST" ); # 2012-11-04 01:54:22 PDT — before the fall-back (first occurrence of 01:xx AM) is( time2str("%Z", 1352019262), "PDT", "GH#10/RT#80649: pre-fall-back timestamp formats as PDT" ); # 2012-11-04 02:25:05 PST — after the repeated hour, clearly PST is( time2str("%Z", 1352024705), "PST", "GH#10/RT#80649: post-repeated-hour timestamp formats as PST" ); META.json100644000765000024 6242715157412057 14617 0ustar00nicolasstaff000000000000TimeDate-2.35{ "abstract" : "Date and time formatting subroutines", "author" : [ "Graham " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 6.033, CPAN::Meta::Converter version 2.150010", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "TimeDate", "prereqs" : { "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "develop" : { "requires" : { "File::Spec" : "0", "IO::Handle" : "0", "IPC::Open3" : "0", "Test::CPAN::Meta" : "0", "Test::MinimumVersion" : "0", "Test::More" : "0.88", "Test::NoTabs" : "0", "Test::Pod" : "1.41", "Test::Synopsis" : "0" } }, "runtime" : { "requires" : { "Carp" : "0" } }, "test" : { "recommends" : { "CPAN::Meta" : "2.120900" }, "requires" : { "ExtUtils::MakeMaker" : "0", "File::Spec" : "0", "Test::More" : "0" } } }, "provides" : { "Date::Format" : { "file" : "lib/Date/Format.pm", "version" : "2.35" }, "Date::Format::Generic" : { "file" : "lib/Date/Format/Generic.pm", "version" : "2.35" }, "Date::Language" : { "file" : "lib/Date/Language.pm", "version" : "2.35" }, "Date::Language::Afar" : { "file" : "lib/Date/Language/Afar.pm", "version" : "2.35" }, "Date::Language::Amharic" : { "file" : "lib/Date/Language/Amharic.pm", "version" : "2.35" }, "Date::Language::Arabic" : { "file" : "lib/Date/Language/Arabic.pm", "version" : "2.35" }, "Date::Language::Austrian" : { "file" : "lib/Date/Language/Austrian.pm", "version" : "2.35" }, "Date::Language::Brazilian" : { "file" : "lib/Date/Language/Brazilian.pm", "version" : "2.35" }, "Date::Language::Bulgarian" : { "file" : "lib/Date/Language/Bulgarian.pm", "version" : "2.35" }, "Date::Language::Chinese" : { "file" : "lib/Date/Language/Chinese.pm", "version" : "2.35" }, "Date::Language::Chinese_GB" : { "file" : "lib/Date/Language/Chinese_GB.pm", "version" : "2.35" }, "Date::Language::Czech" : { "file" : "lib/Date/Language/Czech.pm", "version" : "2.35" }, "Date::Language::Danish" : { "file" : "lib/Date/Language/Danish.pm", "version" : "2.35" }, "Date::Language::Dutch" : { "file" : "lib/Date/Language/Dutch.pm", "version" : "2.35" }, "Date::Language::English" : { "file" : "lib/Date/Language/English.pm", "version" : "2.35" }, "Date::Language::Finnish" : { "file" : "lib/Date/Language/Finnish.pm", "version" : "2.35" }, "Date::Language::French" : { "file" : "lib/Date/Language/French.pm", "version" : "2.35" }, "Date::Language::Gedeo" : { "file" : "lib/Date/Language/Gedeo.pm", "version" : "2.35" }, "Date::Language::German" : { "file" : "lib/Date/Language/German.pm", "version" : "2.35" }, "Date::Language::Greek" : { "file" : "lib/Date/Language/Greek.pm", "version" : "2.35" }, "Date::Language::Hungarian" : { "file" : "lib/Date/Language/Hungarian.pm", "version" : "2.35" }, "Date::Language::Icelandic" : { "file" : "lib/Date/Language/Icelandic.pm", "version" : "2.35" }, "Date::Language::Italian" : { "file" : "lib/Date/Language/Italian.pm", "version" : "2.35" }, "Date::Language::Norwegian" : { "file" : "lib/Date/Language/Norwegian.pm", "version" : "2.35" }, "Date::Language::Occitan" : { "file" : "lib/Date/Language/Occitan.pm", "version" : "2.35" }, "Date::Language::Oromo" : { "file" : "lib/Date/Language/Oromo.pm", "version" : "2.35" }, "Date::Language::Portuguese" : { "file" : "lib/Date/Language/Portuguese.pm", "version" : "2.35" }, "Date::Language::Romanian" : { "file" : "lib/Date/Language/Romanian.pm", "version" : "2.35" }, "Date::Language::Russian" : { "file" : "lib/Date/Language/Russian.pm", "version" : "2.35" }, "Date::Language::Russian_cp1251" : { "file" : "lib/Date/Language/Russian_cp1251.pm", "version" : "2.35" }, "Date::Language::Russian_koi8r" : { "file" : "lib/Date/Language/Russian_koi8r.pm", "version" : "2.35" }, "Date::Language::Sidama" : { "file" : "lib/Date/Language/Sidama.pm", "version" : "2.35" }, "Date::Language::Somali" : { "file" : "lib/Date/Language/Somali.pm", "version" : "2.35" }, "Date::Language::Spanish" : { "file" : "lib/Date/Language/Spanish.pm", "version" : "2.35" }, "Date::Language::Swedish" : { "file" : "lib/Date/Language/Swedish.pm", "version" : "2.35" }, "Date::Language::Tigrinya" : { "file" : "lib/Date/Language/Tigrinya.pm", "version" : "2.35" }, "Date::Language::TigrinyaEritrean" : { "file" : "lib/Date/Language/TigrinyaEritrean.pm", "version" : "2.35" }, "Date::Language::TigrinyaEthiopian" : { "file" : "lib/Date/Language/TigrinyaEthiopian.pm", "version" : "2.35" }, "Date::Language::Turkish" : { "file" : "lib/Date/Language/Turkish.pm", "version" : "2.35" }, "Date::Parse" : { "file" : "lib/Date/Parse.pm", "version" : "2.35" }, "Time::Zone" : { "file" : "lib/Time/Zone.pm", "version" : "2.35" }, "TimeDate" : { "file" : "lib/TimeDate.pm", "version" : "2.35" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/cpan-authors/TimeDate/issues" }, "repository" : { "type" : "git", "url" : "https://github.com/cpan-authors/TimeDate.git", "web" : "https://github.com/cpan-authors/TimeDate" } }, "version" : "2.35", "x_Dist_Zilla" : { "perl" : { "version" : "5.038004" }, "plugins" : [ { "class" : "Dist::Zilla::Plugin::OurPkgVersion", "name" : "OurPkgVersion", "version" : "0.21" }, { "class" : "Dist::Zilla::Plugin::Test::Compile", "config" : { "Dist::Zilla::Plugin::Test::Compile" : { "bail_out_on_fail" : 0, "fail_on_warning" : "author", "fake_home" : 0, "filename" : "xt/author/00-compile.t", "module_finder" : [ ":InstallModules" ], "needs_display" : 0, "phase" : "develop", "script_finder" : [ ":PerlExecFiles" ], "skips" : [], "switch" : [] } }, "name" : "Test::Compile", "version" : "2.058" }, { "class" : "Dist::Zilla::Plugin::MetaTests", "name" : "MetaTests", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::Test::NoTabs", "config" : { "Dist::Zilla::Plugin::Test::NoTabs" : { "filename" : "xt/author/no-tabs.t", "finder" : [ ":InstallModules", ":ExecFiles", ":TestFiles" ] } }, "name" : "Test::NoTabs", "version" : "0.15" }, { "class" : "Dist::Zilla::Plugin::PodSyntaxTests", "name" : "PodSyntaxTests", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs", "name" : "Test::ReportPrereqs", "version" : "0.029" }, { "class" : "Dist::Zilla::Plugin::PodWeaver", "config" : { "Dist::Zilla::Plugin::PodWeaver" : { "finder" : [ ":InstallModules", ":PerlExecFiles" ], "plugins" : [ { "class" : "Pod::Weaver::Plugin::EnsurePod5", "name" : "@CorePrep/EnsurePod5", "version" : "4.020" }, { "class" : "Pod::Weaver::Plugin::H1Nester", "name" : "@CorePrep/H1Nester", "version" : "4.020" }, { "class" : "Pod::Weaver::Plugin::SingleEncoding", "name" : "@Default/SingleEncoding", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Name", "name" : "@Default/Name", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Version", "name" : "@Default/Version", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@Default/prelude", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "SYNOPSIS", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "DESCRIPTION", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "OVERVIEW", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "ATTRIBUTES", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "METHODS", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Collect", "name" : "FUNCTIONS", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Leftovers", "name" : "@Default/Leftovers", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Region", "name" : "@Default/postlude", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Authors", "name" : "@Default/Authors", "version" : "4.020" }, { "class" : "Pod::Weaver::Section::Legal", "name" : "@Default/Legal", "version" : "4.020" } ] } }, "name" : "PodWeaver", "version" : "4.010" }, { "class" : "Dist::Zilla::Plugin::RunExtraTests", "config" : { "Dist::Zilla::Role::TestRunner" : { "default_jobs" : 1 } }, "name" : "RunExtraTests", "version" : "0.029" }, { "class" : "Dist::Zilla::Plugin::MetaJSON", "name" : "MetaJSON", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::MetaConfig", "name" : "MetaConfig", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::MetaProvides::Package", "config" : { "Dist::Zilla::Plugin::MetaProvides::Package" : { "finder_objects" : [ { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "MetaProvides::Package/AUTOVIV/:InstallModulesPM", "version" : "6.033" } ], "include_underscores" : 0 }, "Dist::Zilla::Role::MetaProvider::Provider" : { "$Dist::Zilla::Role::MetaProvider::Provider::VERSION" : "2.002004", "inherit_missing" : 1, "inherit_version" : 1, "meta_noindex" : 1 }, "Dist::Zilla::Role::ModuleMetadata" : { "Module::Metadata" : "1.000037", "version" : "0.006" } }, "name" : "MetaProvides::Package", "version" : "2.004003" }, { "class" : "Dist::Zilla::Plugin::NextRelease", "name" : "NextRelease", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "runtime", "type" : "requires" } }, "name" : "RuntimeRequires", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::Prereqs", "config" : { "Dist::Zilla::Plugin::Prereqs" : { "phase" : "test", "type" : "requires" } }, "name" : "TestRequires", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::TestRelease", "name" : "TestRelease", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::Test::MinimumVersion", "config" : { "Dist::Zilla::Plugin::Test::MinimumVersion" : { "max_target_perl" : "5.010" } }, "name" : "Test::MinimumVersion", "version" : "2.000011" }, { "class" : "Dist::Zilla::Plugin::Git::Check", "config" : { "Dist::Zilla::Plugin::Git::Check" : { "untracked_files" : "die" }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "Changes", "README.md", "dist.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.50.1 (Apple Git-155)", "repo_root" : "." } }, "name" : "@Git/Check", "version" : "2.051" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", "config" : { "Dist::Zilla::Plugin::Git::Commit" : { "add_files_in" : [ "Changes", "README.md", "dist.ini" ], "commit_msg" : "v%V%n%n%c", "signoff" : 0 }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ "Changes", "README.md", "dist.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.50.1 (Apple Git-155)", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "@Git/Commit", "version" : "2.051" }, { "class" : "Dist::Zilla::Plugin::Git::Tag", "config" : { "Dist::Zilla::Plugin::Git::Tag" : { "branch" : null, "changelog" : "Changes", "signed" : 0, "tag" : "v2.35", "tag_format" : "v%V", "tag_message" : "v%V" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.50.1 (Apple Git-155)", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, "name" : "@Git/Tag", "version" : "2.051" }, { "class" : "Dist::Zilla::Plugin::Git::Push", "config" : { "Dist::Zilla::Plugin::Git::Push" : { "push_to" : [ "origin", "origin HEAD:refs/heads/released" ], "remotes_must_exist" : 1 }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.50.1 (Apple Git-155)", "repo_root" : "." } }, "name" : "@Git/Push", "version" : "2.051" }, { "class" : "Dist::Zilla::Plugin::Run::BeforeBuild", "config" : { "Dist::Zilla::Plugin::Run::Role::Runner" : { "fatal_errors" : 1, "quiet" : 0, "version" : "0.050" } }, "name" : "Run::BeforeBuild", "version" : "0.050" }, { "class" : "Dist::Zilla::Plugin::Run::AfterBuild", "config" : { "Dist::Zilla::Plugin::Run::Role::Runner" : { "fatal_errors" : 1, "quiet" : 0, "run" : [ "cp %d/Makefile.PL ./", "git status --porcelain | grep 'M Makefile.PL' && git commit -m 'Makefile.PL auto-updated by dist.ini' Makefile.PL && echo \"# Makefile.PL auto-update\" || echo \"# Makefile.PL up to date\"" ], "version" : "0.050" } }, "name" : "Run::AfterBuild", "version" : "0.050" }, { "class" : "Dist::Zilla::Plugin::Git::NextVersion", "config" : { "Dist::Zilla::Plugin::Git::NextVersion" : { "first_version" : "0.001", "version_by_branch" : 0, "version_regexp" : "(?^:^v(.+)$)" }, "Dist::Zilla::Role::Git::Repo" : { "git_version" : "2.50.1 (Apple Git-155)", "repo_root" : "." } }, "name" : "Git::NextVersion", "version" : "2.051" }, { "class" : "Dist::Zilla::Plugin::PruneCruft", "name" : "@Filter/PruneCruft", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::ManifestSkip", "name" : "@Filter/ManifestSkip", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::MetaYAML", "name" : "@Filter/MetaYAML", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::License", "name" : "@Filter/License", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::Readme", "name" : "@Filter/Readme", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::ExecDir", "name" : "@Filter/ExecDir", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::ShareDir", "name" : "@Filter/ShareDir", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::MakeMaker", "config" : { "Dist::Zilla::Role::TestRunner" : { "default_jobs" : 1 } }, "name" : "@Filter/MakeMaker", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::Manifest", "name" : "@Filter/Manifest", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::TestRelease", "name" : "@Filter/TestRelease", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::ConfirmRelease", "name" : "@Filter/ConfirmRelease", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::UploadToCPAN", "name" : "@Filter/UploadToCPAN", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::GatherDir", "config" : { "Dist::Zilla::Plugin::GatherDir" : { "exclude_filename" : [ "CLAUDE.md", "Makefile.PL" ], "exclude_match" : [], "follow_symlinks" : 0, "include_dotfiles" : 0, "prefix" : "", "prune_directory" : [], "root" : "." } }, "name" : "GatherDir", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::MetaResources", "name" : "MetaResources", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::PruneFiles", "name" : "PruneFiles", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::InsertExample", "name" : "InsertExample", "version" : "0.15" }, { "class" : "Dist::Zilla::Plugin::Test::Synopsis", "name" : "Test::Synopsis", "version" : "2.000007" }, { "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", "config" : { "Dist::Zilla::Role::FileWatcher" : { "version" : "0.006" } }, "name" : "ReadmeAnyFromPod", "version" : "0.163250" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":InstallModules", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":IncModules", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":TestFiles", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExtraTestFiles", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExecFiles", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":PerlExecFiles", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ShareFiles", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":MainModule", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":AllFiles", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":NoFiles", "version" : "6.033" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "MetaProvides::Package/AUTOVIV/:InstallModulesPM", "version" : "6.033" } ], "zilla" : { "class" : "Dist::Zilla::Dist::Builder", "config" : { "is_trial" : 0 }, "version" : "6.033" } }, "x_generated_by_perl" : "v5.38.4", "x_serialization_backend" : "Cpanel::JSON::XS version 4.39", "x_spdx_expression" : "Artistic-1.0-Perl OR GPL-1.0-or-later" } format.t100644000765000024 641115157412057 15065 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse Test::More tests => 292; use Date::Format qw(ctime time2str); use Date::Language; use utf8; my ($pkg, $t,$language); $pkg = 'Date::Format::Generic'; while() { chomp; if (/^(\d+)/) { $t = $1; next; } elsif (/^(\w+)/) { $language = $1; $pkg = Date::Language->new($language); next; } my($fmt,$res) = split(/\t+/,$_); my $str = $pkg->time2str($fmt,$t,'GMT'); is($str, $res,"$fmt"); } __DATA__ 936709362 # Tue Sep 7 11:22:42 1999 GMT %y 99 %Y 1999 %% % %a Tue %A Tuesday %b Sep %B September %c 09/07/99 13:02:42 %C Tue Sep 7 13:02:42 GMT 1999 %d 07 %e 7 %D 09/07/99 %G 1026 %h Sep %H 13 %I 01 %j 250 %k 13 %l 1 %L 9 %m 09 %M 02 %o 7th %p PM %q 3 %r 01:02:42 PM %R 13:02 %s 936709362 %S 42 %T 13:02:42 %U 36 %w 2 %W 36 %x 09/07/99 %X 13:02:42 %y 99 %Y 1999 %Z GMT %z +0000 %Od VII %Oe VII %OH XIII %OI I %Oj CCL %Ok XIII %Ol I %Om IX %OM II %Oq III %OY MCMXCIX %Oy XCIX German %y 99 %Y 1999 %% % %a Di %A Dienstag %b Sep %B September %c 09/07/99 13:02:42 %C Di Sep 7 13:02:42 GMT 1999 %d 07 %e 7 %D 09/07/99 %h Sep %H 13 %I 01 %j 250 %k 13 %l 1 %L 9 %m 09 %M 02 %o 7. %p PM %q 3 %r 01:02:42 PM %R 13:02 %s 936709362 %S 42 %T 13:02:42 %U 36 %w 2 %W 36 %x 09/07/99 %X 13:02:42 %y 99 %Y 1999 %Z GMT %z +0000 %Od VII %Oe VII %OH XIII %OI I %Oj CCL %Ok XIII %Ol I %Om IX %OM II %Oq III %OY MCMXCIX %Oy XCIX French %y 99 %Y 1999 %% % %a mar %A mardi %b sep %B septembre %c 09/07/99 13:02:42 %C mar sep 7 13:02:42 GMT 1999 %d 07 %e 7 %D 09/07/99 %h sep %H 13 %I 01 %j 250 %k 13 %l 1 %L 9 %m 09 %M 02 %o 7e %p PM %q 3 %r 01:02:42 PM %R 13:02 %s 936709362 %S 42 %T 13:02:42 %U 36 %w 2 %W 36 %x 09/07/99 %X 13:02:42 %y 99 %Y 1999 %Z GMT %z +0000 915192000 # Fri Jan 1 12:00:00 1999 GMT %o 1er %A vendredi 936709362 # Tue Sep 7 11:22:42 1999 GMT Italian %y 99 %Y 1999 %% % %a Mar %A Martedi %b Set %B Settembre %c 09/07/99 13:02:42 %C Mar Set 7 13:02:42 GMT 1999 %d 07 %e 7 %D 09/07/99 %h Set %H 13 %I 01 %j 250 %k 13 %l 1 %L 9 %m 09 %M 02 %o 7th %p PM %q 3 %r 01:02:42 PM %R 13:02 %s 936709362 %S 42 %T 13:02:42 %U 36 %w 2 %W 36 %x 09/07/99 %X 13:02:42 %y 99 %Y 1999 %Z GMT %z +0000 %Od VII %Oe VII %OH XIII %OI I %Oj CCL %Ok XIII %Ol I %Om IX %OM II %Oq III %OY MCMXCIX %Oy XCIX 316648800 # Wed Jan 14 00:00:00 1980 %G 1 #0 is interpreted as empty string Bulgarian 1283926923 # ср сеп 8 09:22:03 EET 2010 /Tue Sep 06:22:03 GMT 2010 %y 10 %Y 2010 %% % %a ср %A сряда %b сеп %B септември %c 09/08/10 06:22:03 %C ср сеп 8 06:22:03 GMT 2010 %d 08 %e 8 %D 09/08/10 %G 1600 %h сеп %H 06 %I 06 %j 251 %k 6 %l 6 %L 9 %m 09 %M 22 %o 8ми %p AM %q 3 %r 06:22:03 AM %R 06:22 %s 1283926923 %S 03 %T 06:22:03 %U 36 %w 3 %W 36 %x 09/08/10 %X 06:22:03 %Z GMT %z +0000 %z +0000 %Od VIII %Oe VIII %OH VI %OI VI %Oj CCLI %Ok VI %Ol VI %Om IX %OM XXII %Oq III %OY MMX %Oy X 936709362 # Tue Sep 7 13:02:42 1999 GMT Portuguese %y 99 %Y 1999 %% % %a ter %A terça-feira %b set %B setembro %c 09/07/99 13:02:42 %C ter set 7 13:02:42 GMT 1999 %d 07 %e 7 %D 09/07/99 %h set %H 13 %I 01 %j 250 %k 13 %l 1 %L 9 %m 09 %M 02 %o 7º %p PM %q 3 %r 01:02:42 PM %R 13:02 %s 936709362 %S 42 %T 13:02:42 %U 36 %w 2 %W 36 %x 09/07/99 %X 13:02:42 %y 99 %Y 1999 %Z GMT %z +0000 %Od VII %Oe VII %OH XIII %OI I %Oj CCL %Ok XIII %Ol I %Om IX %OM II %Oq III %OY MCMXCIX %Oy XCIX msk-tz.t100644000765000024 112215157412057 15014 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 2; use Date::Parse qw(str2time); use Time::Zone; # RT#81350: MSK (Moscow Standard Time) offset # Russia was UTC+4 in 2011-2014 (permanent DST), but reverted to UTC+3 in October 2014. # The correct current offset is UTC+3 = 10800 seconds. { my $offset = tz_offset("MSK"); is($offset, 10800, "RT#81350: tz_offset('MSK') returns 10800 (UTC+3)"); my $time = str2time("2024-01-15 12:00:00 MSK"); my $time_utc = str2time("2024-01-15 09:00:00 UTC"); is($time, $time_utc, "RT#81350: MSK date parses to correct UTC equivalent"); } Makefile.PL100644000765000024 205715157412057 15121 0ustar00nicolasstaff000000000000TimeDate-2.35# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.033. use strict; use warnings; use ExtUtils::MakeMaker; my %WriteMakefileArgs = ( "ABSTRACT" => "Date and time formatting subroutines", "AUTHOR" => "Graham ", "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => 0 }, "DISTNAME" => "TimeDate", "LICENSE" => "perl", "NAME" => "TimeDate", "PREREQ_PM" => { "Carp" => 0 }, "TEST_REQUIRES" => { "ExtUtils::MakeMaker" => 0, "File::Spec" => 0, "Test::More" => 0 }, "VERSION" => "2.35", "test" => { "TESTS" => "t/*.t" } ); my %FallbackPrereqs = ( "Carp" => 0, "ExtUtils::MakeMaker" => 0, "File::Spec" => 0, "Test::More" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); SECURITY.md100644000765000024 247015157412057 14737 0ustar00nicolasstaff000000000000TimeDate-2.35# Security Policy ## Supported Versions Only the latest released version of TimeDate receives security fixes. | Version | Supported | | ------- | --------- | | latest | Yes | | older | No | ## Reporting a Vulnerability TimeDate handles date/time string parsing and may be used to process untrusted input. If you discover a security vulnerability, **please do not report it publicly** via a GitHub issue. Instead, report it privately using one of these methods: - **GitHub private vulnerability reporting**: use the [Security Advisory](https://github.com/cpan-authors/TimeDate/security/advisories/new) form on GitHub (preferred). - **Email**: contact the maintainer directly. You can find contact details on the [CPAN author page for ATOOMIC](https://metacpan.org/author/ATOOMIC). Please include as much detail as possible: - A description of the vulnerability - Steps to reproduce or a minimal proof-of-concept - The potential impact ## Disclosure Policy - We will acknowledge receipt of your report within **5 business days**. - We aim to provide an assessment and a fix timeline within **14 days**. - We will coordinate public disclosure with you after a fix is available. This project follows the guidelines described at . rt52387.t100644000765000024 141615157412057 14633 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 5; use Date::Format qw(time2str strftime); # RT#52387: seconds since the Epoch, UCT { my $time = time; my @lt = localtime($time); is(strftime("%s", @lt), $time, "RT#52387: strftime %s returns epoch"); is(time2str("%s", $time), $time, "RT#52387: time2str %s returns epoch"); # strftime %s with explicit timezone must still return the same epoch — # %s is timezone-agnostic (Unix timestamp is always UTC-based). is(strftime("%s", @lt, "UTC"), $time, "RT#52387: strftime %s with UTC tz returns epoch"); is(strftime("%s", @lt, "+0000"), $time, "RT#52387: strftime %s with +0000 tz returns epoch"); is(strftime("%s", @lt, "+0100"), $time, "RT#52387: strftime %s with +0100 tz returns epoch"); } tz-lang.t100644000765000024 302315157412057 15145 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse Test::More tests => 10; use Date::Language; # Tests for language-specific timezone abbreviation translation (issue #1 / RT#52878) # When using %Z format with a language object, timezone abbreviations should be # translated to the language's local equivalents if the language defines a %TZ mapping. my $german = Date::Language->new('German'); my $english = Date::Language->new('English'); # Fixed timestamp: 2009-01-01 00:00:00 UTC (standard time, no DST) my $t = 1230768000; # English should return standard English abbreviations unchanged is( $english->time2str('%Z', $t, 'CET'), 'CET', 'English: CET stays CET' ); is( $english->time2str('%Z', $t, 'CEST'), 'CEST', 'English: CEST stays CEST' ); is( $english->time2str('%Z', $t, 'GMT'), 'GMT', 'English: GMT stays GMT' ); # German should translate CET → MEZ and CEST → MESZ is( $german->time2str('%Z', $t, 'CET'), 'MEZ', 'German: CET → MEZ' ); is( $german->time2str('%Z', $t, 'CEST'), 'MESZ', 'German: CEST → MESZ' ); # German: timezones without a translation should pass through unchanged is( $german->time2str('%Z', $t, 'GMT'), 'GMT', 'German: GMT passes through (no translation defined)' ); is( $german->time2str('%Z', $t, 'UTC'), 'UTC', 'German: UTC passes through (no translation defined)' ); # German: other European timezone translations is( $german->time2str('%Z', $t, 'EET'), 'OEZ', 'German: EET → OEZ' ); is( $german->time2str('%Z', $t, 'EEST'), 'OESZ', 'German: EEST → OESZ' ); is( $german->time2str('%Z', $t, 'WET'), 'WEZ', 'German: WET → WEZ' ); rt57800.t100644000765000024 245515157412057 14632 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 4; use Date::Parse qw(str2time); # RT#57800 (GH#3): str2time fails on numeric m/d/yyyy dates before 1970 # str2time('5/1/1960') was returning undef with "Day too big" errors on # 32-bit systems. Root cause: strptime extracts the 2-digit year (60) and # stores century (19) separately. str2time must reconstruct the full 4-digit # year before calling Time::Local to avoid the 2-digit year windowing heuristic # mapping year 60 to 2060 instead of 1960. { my @cases = ( [ '5/1/1960', 1960, 5, 1, "m/d/yyyy May 1 1960" ], [ '1/5/1960', 1960, 1, 5, "m/d/yyyy Jan 5 1960" ], [ '12/31/1960', 1960, 12, 31, "m/d/yyyy Dec 31 1960" ], [ '5/1/1901', 1901, 5, 1, "m/d/yyyy May 1 1901" ], ); for my $c (@cases) { my ($date, $expected_year, $expected_mon, $expected_day, $desc) = @$c; SKIP: { skip "pre-1970 dates on Win32", 1 if $^O eq 'MSWin32'; my $t = str2time($date); if (!defined $t) { fail("RT#57800: str2time('$date') returned undef"); next; } my @gm = gmtime($t); my $got_year = 1900 + $gm[5]; is($got_year, $expected_year, "RT#57800: $desc parses to year $expected_year"); } } } getdate.t100644000765000024 1717015157412057 15236 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More; use Date::Parse; my @data = split /\n/, <<'DATA'; 1995-01-24 ;790905600 1995-06-24 ;803952000 92/01/02 12:01 ;694353660 92/01/02 12:01 AM ;694310460 92/01/02 12:01 PM ;694353660 2002-11-02 11pm GMT ;1036278000 2002-11-02 11 pm GMT ;1036278000 1995-01-24 GMT ;790905600 1995-01-24 BST ;790902000 1995-06-24 GMT ;803952000 1995-06-24 BST ;803948400 1992-1-2 12:01 GMT ;694353660 1992-1-2-12:01:00 GMT ;694353660 Wed, 16 Jun 94 07:29:35 CST ;771773375 Wed,16 Jun 94 07:29:35 CST ;771773375 Wed, 16 Nov 94 07:29:35 CST ;784992575 Mon, 21 Nov 94 07:42:23 CST ;785425343 Mon, 21 Nov 94 04:28:18 CST ;785413698 Tue, 15 Nov 94 09:15:10 GMT ;784890910 Wed, 16 Nov 94 09:39:49 GMT ;784978789 Wed, 16 Nov 94 09:23:17 GMT ;784977797 Wed, 16 Nov 94 12:39:49 GMT ;784989589 Wed, 16 Nov 94 14:03:06 GMT ;784994586 Wed, 16 Nov 94 05:30:51 CST ;784985451 Thu, 17 Nov 94 03:19:30 CST ;785063970 1994:11:21T14:05:32+0000 ;785426732 Mon, 21 Nov 94 14:05:32 GMT ;785426732 Mon, 14 Nov 94 15:08:49 CST ;784847329 Wed, 16 Nov 94 14:48:06 GMT ;784997286 Thu, 17 Nov 94 14:22:03 GMT ;785082123 Wed, 16 Nov 94 14:36:00 GMT ;784996560 Wed, 16 Nov 94 09:23:17 GMT ;784977797 Wed, 16 Nov 94 10:01:43 GMT ;784980103 Wed, 16 Nov 94 15:03:35 GMT ;784998215 Mon, 21 Nov 94 13:55:19 GMT ;785426119 Wed, 16 Nov 94 08:46:11 CST ;784997171 Wed, 9 Nov 1994 09:50:32 -0500 (EST) ;784392632 Thu, 13 Oct 94 10:13:13 -0700 ;782068393 Sat, 19 Nov 1994 16:59:14 +0100 ;785260754 Thu, 3 Nov 94 14:10:47 EST ;783889847 Thu, 3 Nov 94 21:51:09 EST ;783917469 Fri, 4 Nov 94 9:24:52 EST ;783959092 Wed, 9 Nov 94 09:38:54 EST ;784391934 Mon, 14 Nov 94 13:20:12 EST ;784837212 Wed, 16 Nov 94 17:09:13 EST ;785023753 Tue, 15 Nov 94 12:27:01 PST ;784931221 Fri, 18 Nov 1994 07:34:05 -0600 ;785165645 Mon, 21 Nov 94 14:34:28 -0500 ;785446468 Fri, 18 Nov 1994 12:05:47 -0800 (PST);785189147 Fri, 18 Nov 1994 12:36:26 -0800 (PST);785190986 Wed, 16 Nov 1994 15:58:58 GMT ;785001538 Sun, 06 Nov 94 14:27:40 -0500 ;784150060 Mon, 07 Nov 94 08:20:13 -0500 ;784214413 Mon, 07 Nov 94 16:48:42 -0500 ;784244922 Wed, 09 Nov 94 15:46:16 -0500 ;784413976 Sun, 6 Nov 1994 02:38:17 -0800 ;784118297 Tue, 1 Nov 1994 13:53:49 -0500 ;783716029 Tue, 15 Nov 94 08:31:59 +0100 ;784884719 Sun, 6 Nov 1994 11:09:12 -0500 (IST) ;784138152 Fri, 4 Nov 94 12:52:10 EST ;783971530 Mon, 31 Oct 1994 14:17:39 -0500 (EST);783631059 Mon, 14 Nov 94 11:25:00 CST ;784833900 Mon, 14 Nov 94 13:26:29 CST ;784841189 Fri, 18 Nov 94 8:42:47 CST ;785169767 Thu, 17 Nov 94 14:32:01 +0900 ;785050321 Wed, 2 Nov 94 18:16:31 +0100 ;783796591 Fri, 18 Nov 94 10:46:26 +0100 ;785151986 Tue, 8 Nov 1994 22:39:28 +0200 ;784327168 Wed, 16 Nov 1994 10:01:08 -0500 (EST);784998068 Wed, 2 Nov 1994 16:59:42 -0800 ;783824382 Wed, 9 Nov 94 10:00:23 PST ;784404023 Fri, 18 Nov 94 17:01:43 PST ;785206903 Mon, 14 Nov 1994 14:47:46 -0500 ;784842466 Mon, 21 Nov 1994 04:56:04 -0500 (EST);785411764 Mon, 21 Nov 1994 11:50:12 -0800 ;785447412 Sat, 5 Nov 1994 14:04:16 -0600 (CST) ;784065856 Sat, 05 Nov 94 13:10:13 MST ;784066213 Wed, 02 Nov 94 10:47:48 -0800 ;783802068 Wed, 02 Nov 94 13:19:15 -0800 ;783811155 Thu, 03 Nov 94 15:27:07 -0800 ;783905227 Fri, 04 Nov 94 09:12:12 -0800 ;783969132 Wed, 9 Nov 1994 10:13:03 +0000 (GMT) ;784375983 Wed, 9 Nov 1994 15:28:37 +0000 (GMT) ;784394917 Wed, 2 Nov 1994 17:37:41 +0100 (MET) ;783794261 05 Nov 94 14:22:19 PST ;784074139 16 Nov 94 22:28:20 PST ;785053700 Tue, 1 Nov 1994 19:51:15 -0800 ;783748275 Wed, 2 Nov 94 12:21:23 GMT ;783778883 Fri, 18 Nov 94 18:07:03 GMT ;785182023 Wed, 16 Nov 1994 11:26:27 -0500 ;785003187 Sun, 6 Nov 1994 13:48:49 -0500 ;784147729 Tue, 8 Nov 1994 13:19:37 -0800 ;784329577 Fri, 18 Nov 1994 11:01:12 -0800 ;785185272 Mon, 21 Nov 1994 00:47:58 -0500 ;785396878 Mon, 7 Nov 1994 14:22:48 -0800 (PST) ;784246968 Wed, 16 Nov 1994 15:56:45 -0800 (PST);785030205 Thu, 3 Nov 1994 13:17:47 +0000 ;783868667 Wed, 9 Nov 1994 17:32:50 -0500 (EST) ;784420370 Wed, 9 Nov 94 16:31:52 PST ;784427512 Wed, 09 Nov 94 10:41:10 -0800 ;784406470 Wed, 9 Nov 94 08:42:22 MST ;784395742 Mon, 14 Nov 1994 08:32:13 -0800 ;784830733 Mon, 14 Nov 1994 11:34:32 -0500 (EST);784830872 Mon, 14 Nov 94 16:48:09 GMT ;784831689 Tue, 15 Nov 1994 10:27:33 +0000 ;784895253 Wed, 02 Nov 94 13:56:54 MST ;783809814 Thu, 03 Nov 94 15:24:45 MST ;783901485 Thu, 3 Nov 1994 15:13:53 -0700 (MST) ;783900833 Fri, 04 Nov 94 08:15:13 MST ;783962113 Thu, 3 Nov 94 18:15:47 EST ;783904547 Tue, 08 Nov 94 07:02:33 MST ;784303353 Thu, 3 Nov 94 18:15:47 EST ;783904547 Tue, 15 Nov 94 07:26:05 MST ;784909565 Wed, 2 Nov 1994 00:00:55 -0600 (CST) ;783756055 Sun, 6 Nov 1994 01:19:13 -0600 (CST) ;784106353 Mon, 7 Nov 1994 23:16:57 -0600 (CST) ;784271817 Tue, 08 Nov 1994 13:21:21 -0600 ;784322481 Mon, 07 Nov 94 13:47:37 PST ;784244857 Tue, 08 Nov 94 11:23:19 PST ;784322599 Tue, 01 Nov 1994 11:28:25 -0800 ;783718105 Tue, 15 Nov 1994 13:11:47 -0800 ;784933907 Tue, 15 Nov 1994 13:18:38 -0800 ;784934318 Tue, 15 Nov 1994 0:18:38 -0800 ;784887518 Jul 13 1999 1:23P GMT ;931872180 Jul 13 1999 1:23P.M GMT ;931872180 Jul 13 1999 1:23P.M. GMT ;931872180 Jul-13-1999 1:23P.M GMT ;931872180 Jul/13/1999 1:23P.M. GMT ;931872180 2001-02-26T13:44:12-0700 ;983220252 2001-02-26T13:44-0700 ;983220240 2001-02-26T13-0700 ;983217600 2001-02-26T13-44-12-0700 ;983220252 2001-02-26T13-44-0700 ;983220240 2001-02-26T13-0700 ;983217600 07/Nov/2000:16:45:56 +0100 ;973611956 2002-11-07T23:31:49-05:00 ;1036729909 2003-02-17T07:45:56Z ;1045467956 2003-02-17T08:14:07.198189+0000 ;1045469647.198189 20020722T100000Z ;1027332000 Jul 22 10:00:00 UTC 2002 ;1027332000 2002-07-22 10:00:00Z ;1027332000 2002-07-22 10:00:00 Z ;1027332000 2002-07-22 10:00 Z ;1027332000 2002-07-22 10:00Z ;1027332000 2002-07-22 10:00 +100 ;1027328400 2002-07-22 10:00 +0100 ;1027328400 DATA require Time::Local; my $offset = Time::Local::timegm(0, 0, 0, 1, 0, 1970); my $loop = 0; for my $line (@data) { $loop++; my ($str, $time_expect) = split ';', $line; my $time = Date::Parse::str2time($str); if ($loop < 6) { # The first five tests are parsed in the current time zone # But the check number is in GMT my @lt = localtime($time_expect); my @gt = gmtime($time_expect); my $tzsec = ($gt[1] - $lt[1]) * 60 + ($gt[2] - $lt[2]) * 3600; my ($lday, $gday) = ($lt[7], $gt[7]); if ($lt[5] > $gt[5]) { $tzsec -= 24 * 3600; } elsif ($gt[5] > $lt[5]) { $tzsec += 24 * 3600; } else { $tzsec += ($gt[7] - $lt[7]) * (24 * 3600); } $time -= $tzsec; } $time_expect += $offset; is($time, $time_expect, "parse: $str"); } done_testing; rt106105.t100644000765000024 222315157412057 14674 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 6; use Date::Parse qw(strptime); # RT#106105: Date::Parse inconsistent year handling for years before 1901 # strptime() must return year as offset from 1900 consistently, regardless of # whether the year is before or after 1900. Previously, years <= 1900 were # returned as the full 4-digit year rather than (year - 1900). { # 1901: already worked — year=1, century=19 my @t1901 = strptime('1 Jan 1901 12:00'); is($t1901[5], 1, "RT#106105: strptime year field is 1 for 1901 (offset from 1900)"); is($t1901[7], 19, "RT#106105: strptime century field is 19 for 1901"); # 1900: boundary — year=0, century=19 my @t1900 = strptime('1 Jan 1900 12:00'); is($t1900[5], 0, "RT#106105: strptime year field is 0 for 1900 (offset from 1900)"); is($t1900[7], 19, "RT#106105: strptime century field is 19 for 1900"); # 1899: previously broken — returned 1899 instead of -1 my @t1899 = strptime('1 Jan 1899 12:00'); is($t1899[5], -1, "RT#106105: strptime year field is -1 for 1899 (offset from 1900)"); is($t1899[7], 18, "RT#106105: strptime century field is 18 for 1899"); } rt-parse.t100644000765000024 251115157412057 15327 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 5; use Date::Parse qw(strptime str2time); # RT#48164: Date::Parse unable to set seconds correctly { for my $str ("2008.11.30 22:35 CET", "2008-11-30 22:35 CET") { my @t = strptime($str); my $t = join ":", map { defined($_) ? $_ : "-" } @t; is($t, "-:35:22:30:10:108:3600:20", "RT#48164: seconds parsing for '$str'"); } } # RT#17396: Parse error for french date with 'mars' (march) as month { use Date::Language; my $dateP = Date::Language->new('French'); my $timestamp = $dateP->str2time('4 mars 2005'); my ($ss, $mm, $hh, $day, $month, $year, $zone) = localtime $timestamp; $month++; $year += 1900; my $date = "$day/$month/$year"; is($date, "4/3/2005", "RT#17396: French 'mars' parsed correctly"); } # RT#51664: Change in str2time behaviour between 1.16 and 1.19 { ok(str2time('16 Oct 09') >= 0, "RT#51664: '16 Oct 09' parses to non-negative time"); } # RT#84075: Date::Parse::str2time maps date in 1963 to 2063 { my $this_year = 1900 + (gmtime(time))[5]; my $target_year = $this_year - 50; my $date = "$target_year-01-01 00:00:00 UTC"; my $time = str2time($date); my $year_parsed_as = 1900 + (gmtime($time))[5]; is($year_parsed_as, $target_year, "RT#84075: year $target_year not mapped to future"); } pod-valid.t100644000765000024 66415157412057 15440 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More; BEGIN { eval { require Pod::Checker; 1 } or plan skip_all => 'Pod::Checker not available'; } plan tests => 1; # RT#53557: Missing =back in Date::Parse POD before =head1 MULTI-LANGUAGE SUPPORT { my $checker = Pod::Checker->new; $checker->parse_from_file('lib/Date/Parse.pm'); is($checker->num_errors, 0, "RT#53557: Date::Parse.pm has valid POD (no missing =back)"); } rt-format.t100644000765000024 52415157412057 15467 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 2; use Date::Format qw(time2str); # RT#45067: Date::Format with %z gives wrong results for half-hour timezones { for my $zone (qw(-0430 -0745)) { my $zone_str = time2str("%Z %z", time, $zone); is($zone_str, "$zone $zone", "RT#45067: half-hour timezone $zone"); } } lang-data.t100644000765000024 2444515157412057 15454 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More; use Date::Language; # Tue Sep 7 13:02:42 1999 GMT # wday=2 (Tuesday), mon=8 (September, 0-indexed) my $time = 936709362; # Expected values for %A (full day), %a (short day), %B (full month), %b (short month) # extracted from each language module's @DoW[2], @DoWs[2], @MoY[8], @MoYs[8] my %expected = ( Afar => { A => "Talaata", a => "Tal", B => "Waysu", b => "Way" }, Amharic => { A => "\x{121b}\x{12ad}\x{1230}\x{129e}", a => "\x{121b}\x{12ad}\x{1230}", B => "\x{1234}\x{1355}\x{1274}\x{121d}\x{1260}\x{122d}", b => "\x{1234}\x{1355}\x{1274}" }, Arabic => { A => "\x{627}\x{644}\x{62b}\x{644}\x{627}\x{62b}\x{627}\x{621}", a => "\x{627}\x{644}\x{62b}", B => "\x{633}\x{628}\x{62a}\x{645}\x{628}\x{631}", b => "\x{633}\x{628}\x{62a}" }, Austrian => { A => "Dienstag", a => "Di", B => "September", b => "Sep" }, Brazilian => { A => "Ter\x{e7}a", a => "Ter", B => "Setembro", b => "Set" }, Bulgarian => { A => "\x{432}\x{442}\x{43e}\x{440}\x{43d}\x{438}\x{43a}", a => "\x{432}\x{442}", B => "\x{441}\x{435}\x{43f}\x{442}\x{435}\x{43c}\x{432}\x{440}\x{438}", b => "\x{441}\x{435}\x{43f}" }, Chinese => { A => "\x{661f}\x{671f}\x{4e8c}", a => "\x{661f}\x{671f}\x{4e8c}", B => "\x{4e5d}\x{6708}", b => "\x{4e5d}\x{6708}" }, Chinese_GB => { A => "\x{d0}\x{c7}\x{c6}\x{da}\x{b6}\x{fe}", a => "\x{d0}\x{c7}\x{c6}\x{da}\x{b6}\x{fe}", B => "\x{be}\x{c5}\x{d4}\x{c2}", b => "\x{be}\x{c5}\x{d4}\x{c2}" }, Czech => { A => "\x{fa}ter\x{fd}", a => "\x{da}t", B => "z\x{e1}\x{f8}\x{ed}", b => "z\x{e1}\x{f8}\x{ed}" }, Danish => { A => "Tirsdag", a => "Tir", B => "September", b => "Sep" }, Dutch => { A => "dinsdag", a => "di", B => "september", b => "sep" }, English => { A => "Tuesday", a => "Tue", B => "September", b => "Sep" }, Finnish => { A => "tiistai", a => "tiistai", B => "syyskuu", b => "syyskuu" }, French => { A => "mardi", a => "mar", B => "septembre", b => "sep" }, Gedeo => { A => "Masano", a => "Mas", B => "Canissa", b => "Can" }, German => { A => "Dienstag", a => "Di", B => "September", b => "Sep" }, Greek => { A => "\x{3a4}\x{3c1}\x{3af}\x{3c4}\x{3b7}", a => "\x{3a4}\x{3c1}", B => "\x{3a3}\x{3b5}\x{3c0}\x{3c4}\x{3b5}\x{3bc}\x{3c4}\x{3bf}\x{3c5}", b => "\x{3a3}\x{3b5}\x{3c0}" }, Hungarian => { A => "Kedd", a => "Ked", B => "Szeptember", b => "Sze" }, Icelandic => { A => "\x{de}ri\x{f0}judagur", a => "\x{de}ri", B => "September", b => "Sep" }, Italian => { A => "Martedi", a => "Mar", B => "Settembre", b => "Set" }, Norwegian => { A => "Tirsdag", a => "Tir", B => "September", b => "Sep" }, Occitan => { A => "dimars", a => "dim", B => "setembre", b => "set" }, Portuguese => { A => "ter\x{e7}a-feira", a => "ter", B => "setembro", b => "set" }, Oromo => { A => "Qibxata", a => "Qib", B => "Fuulbana", b => "Fuu" }, Romanian => { A => "marti", a => "mar", B => "septembrie", b => "sep" }, Russian => { A => "\x{f3}\x{d2}\x{c5}\x{c4}\x{c1}", a => "\x{f3}\x{d2}", B => "\x{f3}\x{c5}\x{ce}\x{d4}\x{d1}\x{c2}\x{d2}\x{d1}", b => "\x{f3}\x{c5}\x{ce}" }, Russian_cp1251 => { A => "\x{c2}\x{f2}\x{ee}\x{f0}\x{ed}\x{e8}\x{ea}", a => "\x{c2}\x{f2}\x{f0}", B => "\x{d1}\x{e5}\x{ed}\x{f2}\x{ff}\x{e1}\x{f0}\x{fc}", b => "\x{d1}\x{e5}\x{ed}" }, Russian_koi8r => { A => "\x{f7}\x{d4}\x{cf}\x{d2}\x{ce}\x{c9}\x{cb}", a => "\x{f7}\x{d4}\x{d2}", B => "\x{f3}\x{c5}\x{ce}\x{d4}\x{d1}\x{c2}\x{d2}\x{d8}", b => "\x{f3}\x{c5}\x{ce}" }, Sidama => { A => "Maakisanyo", a => "Maa", B => "September", b => "Sep" }, Somali => { A => "Salaaso", a => "Sal", B => "Bisha Sagaalaad", b => "Sag" }, Spanish => { A => "martes", a => "mar", B => "septiembre", b => "sep" }, Swedish => { A => "tisdagen", a => "ti", B => "september", b => "sep" }, Tigrinya => { A => "\x{1230}\x{1209}\x{1235}", a => "\x{1230}\x{1209}\x{1235}", B => "\x{1234}\x{1355}\x{1274}\x{121d}\x{1260}\x{122d}", b => "\x{1234}\x{1355}\x{1274}" }, TigrinyaEritrean => { A => "\x{1230}\x{1209}\x{1235}", a => "\x{1230}\x{1209}\x{1235}", B => "\x{1234}\x{1355}\x{1274}\x{121d}\x{1260}\x{122d}", b => "\x{1234}\x{1355}\x{1274}" }, TigrinyaEthiopian => { A => "\x{1230}\x{1209}\x{1235}", a => "\x{1230}\x{1209}\x{1235}", B => "\x{1234}\x{1355}\x{1274}\x{121d}\x{1260}\x{122d}", b => "\x{1234}\x{1355}\x{1274}" }, Turkish => { A => "Sal\x{131}", a => "Sal", B => "Eyl\x{fc}l", b => "Eyl" }, ); for my $lang (sort keys %expected) { my $l = Date::Language->new($lang); my $e = $expected{$lang}; # Content checks is($l->time2str('%A', $time, 'GMT'), $e->{A}, "$lang: full day name (%A)"); is($l->time2str('%a', $time, 'GMT'), $e->{a}, "$lang: short day name (%a)"); is($l->time2str('%B', $time, 'GMT'), $e->{B}, "$lang: full month name (%B)"); is($l->time2str('%b', $time, 'GMT'), $e->{b}, "$lang: short month name (%b)"); # Structural checks no strict 'refs'; my $pkg = "Date::Language::$lang"; is(scalar @{"${pkg}::DoW"}, 7, "$lang: 7 day names"); is(scalar @{"${pkg}::DoWs"}, 7, "$lang: 7 short day names"); is(scalar @{"${pkg}::MoY"}, 12, "$lang: 12 month names"); is(scalar @{"${pkg}::MoYs"}, 12, "$lang: 12 short month names"); is(scalar @{"${pkg}::AMPM"}, 2, "$lang: 2 AM/PM entries"); } done_testing; edge-cases.t100644000765000024 2166615157412057 15626 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More; use Date::Parse qw(str2time strptime); use Date::Language; # --- Undef / empty / garbage inputs --- ok(!defined str2time(undef), "str2time(undef) returns undef"); ok(!defined str2time(""), "str2time('') returns undef"); ok(!defined str2time("garbage"), "str2time('garbage') returns undef"); ok(!defined str2time("not a date at all"), "str2time('not a date at all') returns undef"); # --- ISO 8601 variants --- { my $t1 = str2time("2002-07-22T10:00:00Z"); ok(defined $t1, "ISO 8601 with T separator and Z"); is($t1, 1027332000, "ISO 8601 basic format parses correctly"); my $t2 = str2time("2002-07-22 10:00:00Z"); is($t2, 1027332000, "ISO 8601 with space separator and Z"); my $t3 = str2time("20020722T100000Z"); is($t3, 1027332000, "ISO 8601 compact format"); my $t4 = str2time("2001-02-26T13:44:12-0700"); is($t4, 983220252, "ISO 8601 with negative offset"); my $t5 = str2time("2002-11-07T23:31:49-05:00"); is($t5, 1036729909, "RFC 3339 with colon in offset"); } # --- AM/PM parsing --- { my $base = str2time("Jul 13 1999 13:23:00 GMT"); is(str2time("Jul 13 1999 1:23P GMT"), $base, "1:23P parses as PM"); is(str2time("Jul 13 1999 1:23P.M GMT"), $base, "1:23P.M parses as PM"); is(str2time("Jul 13 1999 1:23P.M. GMT"), $base, "1:23P.M. parses as PM"); my $am = str2time("92/01/02 12:01 AM"); my $pm = str2time("92/01/02 12:01 PM"); ok(defined $am && defined $pm, "AM/PM dates parse"); cmp_ok($pm - $am, '==', 12 * 3600, "PM is 12 hours after AM"); } # --- Fractional seconds --- { my $t = str2time("2003-02-17T08:14:07.198189+0000"); ok(defined $t, "fractional seconds parse"); cmp_ok(abs($t - 1045469647.198189), '<', 0.001, "fractional seconds preserved"); my $t2 = str2time("1995-01-24T09:08:17.1823213"); ok(defined $t2, "high-precision fractional seconds parse"); } # --- Apache-style dates --- { my $t = str2time("07/Nov/2000:16:45:56 +0100"); is($t, 973611956, "Apache log date format"); } # --- RFC 2822 / email dates --- { my $t = str2time("Wed, 9 Nov 1994 09:50:32 -0500 (EST)"); is($t, 784392632, "RFC 2822 date with comment"); my $t2 = str2time("Sat, 19 Nov 1994 16:59:14 +0100"); is($t2, 785260754, "RFC 2822 date with positive offset"); } # --- Date::Language error handling --- { eval { Date::Language->new('NonexistentLanguage') }; ok($@, "Date::Language->new with invalid language dies"); my $fr = Date::Language->new('French'); ok(defined $fr, "Date::Language->new('French') succeeds"); my $ts = $fr->str2time('15 janvier 2010'); ok(defined $ts, "French 'janvier' parses"); } # --- French month parsing --- { my $fr = Date::Language->new('French'); my @months = ( ['janvier', 1], ['mars', 3], ['juin', 6], ['octobre', 10], ['novembre', 11], ); for my $pair (@months) { my ($month_name, $month_num) = @$pair; my $ts = $fr->str2time("15 $month_name 2010"); if (defined $ts) { my @lt = localtime($ts); is($lt[4] + 1, $month_num, "French '$month_name' -> month $month_num"); } else { fail("French '$month_name' failed to parse"); } } } # --- Two-digit year handling --- # Two-digit years: 69-99 -> 1969-1999, 0-68 -> 2000-2068 (POSIX convention) { my $t = str2time("16 Oct 09"); ok(defined $t, "two-digit year '09' parses"); cmp_ok($t, '>=', 0, "two-digit year '09' gives non-negative time"); my @gm = gmtime($t); is($gm[5] + 1900, 2009, "two-digit year '09' maps to 2009"); } # --- Two-digit years for 1970s/1980s dates (GH issue #47) --- { my $t74 = str2time("01 Jan 74 00:00:00 GMT"); ok(defined $t74, "two-digit year '74' parses"); is($t74, 126230400, "two-digit year '74' gives 1974-01-01 not 2074"); my $t73 = str2time("15 Jun 73 12:00:00 GMT"); ok(defined $t73, "two-digit year '73' parses"); my @gm73 = gmtime($t73); is($gm73[5] + 1900, 1973, "two-digit year '73' maps to 1973"); my $t72 = str2time("01 Jan 72 00:00:00 GMT"); ok(defined $t72, "two-digit year '72' parses"); my @gm72 = gmtime($t72); is($gm72[5] + 1900, 1972, "two-digit year '72' maps to 1972"); # Boundary: 69 -> 1969, 68 -> 2068 my $t69 = str2time("01 Jan 69 00:00:00 GMT"); ok(defined $t69, "two-digit year '69' parses"); my @gm69 = gmtime($t69); is($gm69[5] + 1900, 1969, "two-digit year '69' maps to 1969 (boundary)"); } # --- Time-only formats --- { my $t = str2time("10:00:00Z"); ok(defined $t, "time-only with Z parses"); my $t2 = str2time("10:00:00"); ok(defined $t2, "time-only without zone parses"); my $t3 = str2time("10:00"); ok(defined $t3, "time-only HH:MM parses"); } # --- Various date separator styles --- { my $t1 = str2time("21 dec 17:05"); my $t2 = str2time("21-dec 17:05"); my $t3 = str2time("21/dec 17:05"); ok(defined $t1, "space-separated day month"); is($t1, $t2, "dash separator matches space separator"); is($t1, $t3, "slash separator matches space separator"); } # --- Boost C++ timestamp format --- { my $t = str2time("2024-May-15 14:30:00.123456"); ok(defined $t, "boost format YYYY-Mon-DD HH:MM:SS.f parses"); } # --- Leap day (Feb 29) handling --- # When only a year is given, str2time fills in the current month/day. # On Feb 29 the year must be a leap year or str2time returns undef. # See: https://github.com/atoomic/perl-TimeDate/issues/28 { # Explicit Feb 29 on a leap year must succeed my $t1 = str2time("29 Feb 2000 10:02:18 GMT"); ok(defined $t1, "Feb 29 of leap year 2000 parses"); is($t1, 951818538, "Feb 29 2000 10:02:18 GMT matches expected epoch"); # Explicit Feb 29 on a non-leap year must fail my $t2 = str2time("29 Feb 1999 10:02:18 GMT"); ok(!defined $t2, "Feb 29 of non-leap year 1999 returns undef"); } # --- Comma as decimal separator in fractional seconds (ISO 8601) --- { my $dot = str2time("2016-01-28 23:27:13.995 UTC"); my $comma = str2time("2016-01-28 23:27:13,995 UTC"); ok(defined $dot, "dot decimal fractional seconds parse"); ok(defined $comma, "comma decimal fractional seconds parse"); cmp_ok(abs($dot - $comma), '<', 0.01, "comma decimal gives same result as dot decimal"); my $t1 = str2time("2016-01-28 23:27:13,995 UTC"); my $t2 = str2time("2016-01-28 23:27:13,996 UTC"); cmp_ok($t2, '>', $t1, "comma decimal: ,996 is later than ,995"); cmp_ok(abs($t2 - $t1 - 0.001), '<', 0.0001, "comma decimal: difference is ~1ms"); # RFC 2822 commas still work my $rfc = str2time("Wed, 16 Jun 94 07:29:35 CST"); is($rfc, 771773375, "RFC 2822 comma after day name still works"); } # --- Year inference for dates without an explicit year (GH #46) --- # When no year is given, str2time should assume the most recent occurrence: # a date in the future (month > now, OR same month but day > today) gets # previous year; a date in the past (or today) gets current year. { my @lt = localtime(); my ($cur_day, $cur_month, $cur_year) = @lt[3, 4, 5]; $cur_year += 1900; my @mon_names = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); # A future month (strictly > current month): should infer previous year. if ($cur_month < 11) { my $future_mon = $mon_names[$cur_month + 1]; my $t = str2time("$future_mon 4 01:04:16"); ok(defined $t, "future month '$future_mon 4': parses"); my @res = localtime($t); is($res[5] + 1900, $cur_year - 1, "future month ($future_mon) → previous year (GH#46)"); } # A past month (strictly < current month): should infer current year. if ($cur_month > 0) { my $past_mon = $mon_names[$cur_month - 1]; my $t = str2time("$past_mon 4 01:04:16"); ok(defined $t, "past month '$past_mon 4': parses"); my @res = localtime($t); is($res[5] + 1900, $cur_year, "past month ($past_mon) → current year (GH#46)"); } # Same month, day strictly in the future → previous year. if ($cur_day <= 27) { my $future_day = $cur_day + 1; my $mon = $mon_names[$cur_month]; my $t = str2time(sprintf("%s %d 01:04:16", $mon, $future_day)); ok(defined $t, "future day same month '$mon $future_day': parses"); my @res = localtime($t); is($res[5] + 1900, $cur_year - 1, "same month, future day ($mon $future_day) → previous year (GH#46)"); } # Same month, day strictly in the past → current year. if ($cur_day >= 2) { my $past_day = $cur_day - 1; my $mon = $mon_names[$cur_month]; my $t = str2time(sprintf("%s %d 01:04:16", $mon, $past_day)); ok(defined $t, "past day same month '$mon $past_day': parses"); my @res = localtime($t); is($res[5] + 1900, $cur_year, "same month, past day ($mon $past_day) → current year (GH#46)"); } } done_testing; cpanrt-zone.t100644000765000024 1004115157412057 16047 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 15; use Date::Parse qw(str2time); use Time::Zone; # IST (Indian Standard Time) should resolve to UTC+5:30 { my $offset = tz_offset("ist"); is($offset, 19800, "tz_offset('ist') returns 19800 (UTC+5:30)"); my $time = str2time("2024-01-15 12:00:00 IST"); my $time_utc = str2time("2024-01-15 06:30:00 UTC"); is($time, $time_utc, "IST date parses to correct UTC equivalent"); } # RT#76968: tz2zone("America/Chicago") doesn't work # IANA timezone names like "America/Chicago" should be usable with tz_offset { use POSIX qw(); SKIP: { # Verify that the system supports IANA timezone names my $has_iana = eval { local $ENV{TZ} = "Etc/UTC"; POSIX::tzset(); my ($std) = POSIX::tzname(); defined $std && $std =~ /UTC|GMT/i; }; skip "system does not support IANA timezone names", 6 unless $has_iana; # tz_offset with IANA name "Etc/UTC" must return 0 (deterministic) my $utc_offset = tz_offset("Etc/UTC"); is($utc_offset, 0, "RT#76968: tz_offset('Etc/UTC') returns 0"); # tz2zone with IANA name "Etc/UTC" must return a valid abbreviation my $utc_name = tz2zone("Etc/UTC", undef, 0); ok(defined $utc_name && length($utc_name) > 0, "RT#76968: tz2zone('Etc/UTC') returns a defined non-empty name"); # tz_offset(tz2zone(IANA_name)) must return defined — the key failure in the bug my $chicago_abbr = tz2zone("America/New_York", undef, 0); ok(defined $chicago_abbr, "RT#76968: tz2zone('America/New_York', dst=0) returns defined"); my $chicago_offset = tz_offset($chicago_abbr); ok(defined $chicago_offset, "RT#76968: tz_offset(tz2zone('America/New_York')) returns defined"); # tz_offset of IANA name directly must return defined my $ny_offset = tz_offset("America/New_York"); ok(defined $ny_offset, "RT#76968: tz_offset('America/New_York') returns defined"); # tz_offset("Etc/UTC") via tz2zone round-trip my $utc_abbr = tz2zone("Etc/UTC", undef, 0); my $utc_offset2 = tz_offset($utc_abbr); is($utc_offset2, 0, "RT#76968: tz_offset(tz2zone('Etc/UTC')) returns 0"); } } # RT#59298: tz_name() reports incorrect offset for unknown timezone names # The offset passed is in seconds, but the old code treated it as minutes, # producing e.g. "+33000" for IST (+5:30) instead of "+0530". # Also: negative fractional-hour offsets must format correctly. { # UTC+5:30 = 19800s — not in the Zone table when the bug was filed is(tz_name(19800, 0), "ist", "RT#59298: tz_name(19800) returns ist (UTC+5:30 is now in table)"); # An offset not in the table: UTC+1:30 = 5400s → "+0130" (was "+9000" before fix) is(tz_name(5400, 0), "+0130", "RT#59298: tz_name(5400) returns +0130, not +9000"); # Negative fractional offset: UTC-1:30 = -5400s → "-0130" # (Note: -9000 is now NDT/Newfoundland Daylight, so use -5400 instead) is(tz_name(-5400, 0), "-0130", "RT#59298: tz_name(-5400) returns -0130 (UTC-1:30)"); } # RT#82271: tz_name should return CEST (not MEST) for Central European Summer Time # CEST (Central European Summer Time) is the standard/preferred abbreviation; # MEST (Middle European Summer Time) is a German-influenced variant. { is(tz_name(7200, 1), "cest", "RT#82271: tz_name(+2h, dst=1) returns cest not mest"); is(tz_offset("MEST"), 7200, "RT#82271: tz_offset(MEST) still works for backward compat"); } # RT#98949: Moscow Time Change in October 2014 # MSK (Moscow Standard Time) is UTC+3 permanently since 25 Oct 2014. # Russia eliminated DST in 2011 (UTC+4 year-round), then reverted to UTC+3 in Oct 2014. { my $offset = tz_offset("msk"); is($offset, 10800, "RT#98949: tz_offset('msk') returns 10800 (UTC+3)"); my $time = str2time("2014-10-27 00:00:00 MSK"); my $time_utc = str2time("2014-10-26 21:00:00 UTC"); is($time, $time_utc, "RT#98949: MSK date after 2014 change parses to correct UTC"); } rt-timezone.t100644000765000024 543315157412057 16055 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 10; use Date::Parse qw(str2time); use Time::Zone; use POSIX qw(); # IST (Indian Standard Time) should resolve to UTC+5:30 { my $offset = tz_offset("ist"); is($offset, 19800, "tz_offset('ist') returns 19800 (UTC+5:30)"); my $time = str2time("2024-01-15 12:00:00 IST"); my $time_utc = str2time("2024-01-15 06:30:00 UTC"); is($time, $time_utc, "IST date parses to correct UTC equivalent"); } # RT#76968: tz2zone("America/Chicago") doesn't work # IANA timezone names like "America/Chicago" should be usable with tz_offset { SKIP: { # Verify that the system supports IANA timezone names my $has_iana = eval { local $ENV{TZ} = "Etc/UTC"; POSIX::tzset(); my ($std) = POSIX::tzname(); defined $std && $std =~ /UTC|GMT/i; }; skip "system does not support IANA timezone names", 6 unless $has_iana; # tz_offset with IANA name "Etc/UTC" must return 0 (deterministic) my $utc_offset = tz_offset("Etc/UTC"); is($utc_offset, 0, "RT#76968: tz_offset('Etc/UTC') returns 0"); # tz2zone with IANA name "Etc/UTC" must return a valid abbreviation my $utc_name = tz2zone("Etc/UTC", undef, 0); ok(defined $utc_name && length($utc_name) > 0, "RT#76968: tz2zone('Etc/UTC') returns a defined non-empty name"); # tz_offset(tz2zone(IANA_name)) must return defined — the key failure in the bug my $chicago_abbr = tz2zone("America/New_York", undef, 0); ok(defined $chicago_abbr, "RT#76968: tz2zone('America/New_York', dst=0) returns defined"); my $chicago_offset = tz_offset($chicago_abbr); ok(defined $chicago_offset, "RT#76968: tz_offset(tz2zone('America/New_York')) returns defined"); # tz_offset of IANA name directly must return defined my $ny_offset = tz_offset("America/New_York"); ok(defined $ny_offset, "RT#76968: tz_offset('America/New_York') returns defined"); # tz_offset("Etc/UTC") via tz2zone round-trip my $utc_abbr = tz2zone("Etc/UTC", undef, 0); my $utc_offset2 = tz_offset($utc_abbr); is($utc_offset2, 0, "RT#76968: tz_offset(tz2zone('Etc/UTC')) returns 0"); } } # RT#98949: Moscow Time Change in October 2014 # MSK (Moscow Standard Time) is UTC+3 permanently since 25 Oct 2014. # Russia eliminated DST in 2011 (UTC+4 year-round), then reverted to UTC+3 in Oct 2014. { my $offset = tz_offset("msk"); is($offset, 10800, "RT#98949: tz_offset('msk') returns 10800 (UTC+3)"); my $time = str2time("2014-10-27 00:00:00 MSK"); my $time_utc = str2time("2014-10-26 21:00:00 UTC"); is($time, $time_utc, "RT#98949: MSK date after 2014 change parses to correct UTC"); } lib000755000765000024 015157412057 13551 5ustar00nicolasstaff000000000000TimeDate-2.35TimeDate.pm100644000765000024 327615157412057 15753 0ustar00nicolasstaff000000000000TimeDate-2.35/libpackage TimeDate; our $VERSION = '2.35'; # VERSION: generated # ABSTRACT: Date and time formatting subroutines 1; __END__ =pod =encoding UTF-8 =head1 NAME TimeDate - Date and time formatting subroutines =head1 VERSION version 2.35 =head1 SYNOPSIS use Date::Format; use Date::Parse; # Formatting print time2str("%Y-%m-%d %T", time); # 2024-01-15 14:30:00 print time2str("%a %b %e %T %Y\n", time); # Mon Jan 15 14:30:00 2024 # Parsing my $time = str2time("Wed, 16 Jun 94 07:29:35 CST"); my ($ss,$mm,$hh,$day,$month,$year,$zone) = strptime("2024-01-15T14:30:00Z"); # Multi-language support use Date::Language; my $lang = Date::Language->new('German'); print $lang->time2str("%a %b %e %T %Y\n", time); =head1 DESCRIPTION The TimeDate distribution provides date parsing, formatting, and timezone handling for Perl. =over 4 =item L Parse date strings in a wide variety of formats into Unix timestamps or component values. =item L Format Unix timestamps or localtime arrays into strings using C-style conversion specifications. =item L Format and parse dates in over 30 languages including French, German, Spanish, Chinese, Russian, Arabic, and many more. =item L Timezone offset lookups and conversions for named timezones. =back =head1 SEE ALSO L, L, L, L =head1 AUTHOR Graham =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2020 by Graham Barr. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut cpanrt-parse.t100644000765000024 1211215157412057 16207 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 26; use Date::Parse qw(strptime str2time); # RT#48164: Date::Parse unable to set seconds correctly { for my $str ("2008.11.30 22:35 CET", "2008-11-30 22:35 CET") { my @t = strptime($str); my $t = join ":", map { defined($_) ? $_ : "-" } @t; is($t, "-:35:22:30:10:108:3600:20", "RT#48164: seconds parsing for '$str'"); } } # RT#51664: Change in str2time behaviour between 1.16 and 1.19 { ok(str2time('16 Oct 09') >= 0, "RT#51664: '16 Oct 09' parses to non-negative time"); } # RT#84075: Date::Parse::str2time maps date in 1963 to 2063 { my $this_year = 1900 + (gmtime(time))[5]; my $target_year = $this_year - 50; my $date = "$target_year-01-01 00:00:00 UTC"; my $time = str2time($date); my $year_parsed_as = 1900 + (gmtime($time))[5]; is($year_parsed_as, $target_year, "RT#84075: year $target_year not mapped to future"); } # RT#70650: Date::Parse should not parse ludicrous strings like bare numbers { ok(!defined str2time('1'), "RT#70650: str2time('1') returns undef"); ok(!defined str2time('+01'), "RT#70650: str2time('+01') returns undef"); ok(!defined str2time('+0500'), "RT#70650: str2time('+0500') returns undef"); } # RT#53413 / RT#105031 (GH#17): Date::Parse mangling 4-digit year dates # str2time() must not map 4-digit pre-1970 years to future dates. # The root cause: strptime() extracts a 2-digit year (subtracting 1900 from # the 4-digit value) and stores the century separately. str2time() must # reconstruct the full 4-digit year before calling Time::Local, whose # 2-digit-year windowing would otherwise map e.g. year 24 (from 1924) to 2024, # or year 65 (from 1965) to 2065. { my @cases = ( [ "1924-01-15 00:00:00 UTC", 1924, "year 1924 does not map to 2024" ], [ "1963-06-16 00:00:00 UTC", 1963, "year 1963 does not map to 2063" ], [ "1965-12-31 00:00:00 UTC", 1965, "year 1965 does not map to 2065" ], [ "1966-01-01 00:00:00 UTC", 1966, "year 1966 does not map to future" ], [ "1901-12-17 00:00:00 UTC", 1901, "year 1901 parses correctly" ], [ "1935-01-24 00:00:00 UTC", 1935, "year 1935 does not map to future" ], ); for my $c (@cases) { my ($date, $expected_year, $desc) = @$c; my $t = str2time($date); if (!defined $t) { fail("RT#53413: str2time('$date') returned undef"); next; } my $parsed_year = 1900 + (gmtime($t))[5]; is($parsed_year, $expected_year, "RT#53413: $desc"); } # strptime() must return year as offset from 1900 with century captured separately my @t = strptime("1924-01-15 00:00:00 UTC"); is($t[5], 24, "RT#53413: strptime year field is 24 for 1924 (offset from 1900)"); is($t[7], 19, "RT#53413: strptime century field is 19 for 1924"); } # RT#92611: str2time should pick the most recent occurrence when no year given. # A future month means the most recent occurrence was last year. { my @lt = localtime(time); my $cur_month = $lt[4]; # 0-11 my $cur_year = 1900 + $lt[5]; my @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); SKIP: { # December → January crosses a year boundary; the heuristic is ambiguous there. skip "RT#92611: skipping in December (year-boundary edge case)", 1 if $cur_month == 11; my $future_month = $cur_month + 1; # guaranteed valid (0-10 → 1-11) my $future_name = $months[$future_month]; my $t = str2time("15 $future_name"); my $got_year = 1900 + (localtime($t))[5]; is($got_year, $cur_year - 1, "RT#92611: '15 $future_name' with no year resolves to previous year (most recent occurrence)"); } } # RT#53267 / GH#2: strptime('MONTH YEAR') puts year into $day # 'December 2009' should give month=11, year=109 (2009-1900), day=undef # not month=11, day=2009, year=undef { my ($ss,$mm,$hh,$day,$month,$year,$zone) = strptime('December 2009'); is($month, 11, "RT#53267: 'December 2009' gives month=11 (December)"); ok(!defined($day), "RT#53267: 'December 2009' gives day=undef (not 2009)"); is($year, 109, "RT#53267: 'December 2009' gives year=109 (2009-1900)"); # 4-digit year in same position ($ss,$mm,$hh,$day,$month,$year,$zone) = strptime('Jan 1995'); is($month, 0, "RT#53267: 'Jan 1995' gives month=0 (January)"); ok(!defined($day), "RT#53267: 'Jan 1995' gives day=undef"); is($year, 95, "RT#53267: 'Jan 1995' gives year=95 (1995-1900)"); # normal 'MONTH DAY' must still work ($ss,$mm,$hh,$day,$month,$year,$zone) = strptime('December 25'); is($month, 11, "RT#53267: 'December 25' still gives month=11"); is($day, 25, "RT#53267: 'December 25' still gives day=25"); } # RT#125949: strptime returns negative month for certain inputs { my @t = strptime("199001"); my $month = $t[4]; ok(!defined($month) || $month >= 0, "RT#125949: strptime('199001') month is not negative"); my $t = str2time("199001"); ok(!defined($t), "RT#125949: str2time('199001') returns undef for ambiguous 6-digit input"); } Time000755000765000024 015157412057 14447 5ustar00nicolasstaff000000000000TimeDate-2.35/libZone.pm100644000765000024 2631615157412057 16110 0ustar00nicolasstaff000000000000TimeDate-2.35/lib/Time package Time::Zone; require 5.006; require Exporter; use Carp; use strict; use POSIX qw(tzset tzname); our $VERSION = '2.35'; # VERSION: generated # ABSTRACT: miscellaneous timezone manipulations routines our @ISA = qw(Exporter); our @EXPORT = qw(tz2zone tz_local_offset tz_offset tz_name); # Parts stolen from code by Paul Foley my %tzn_cache; sub tz2zone (;$$$) { my($TZ, $time, $isdst) = @_; $TZ = defined($ENV{'TZ'}) ? ( $ENV{'TZ'} ? $ENV{'TZ'} : 'GMT' ) : '' unless $TZ; # Hack to deal with 'PST8PDT' format of TZ # Note that this can't deal with all the esoteric forms, but it # does recognize the most common: [:]STDoff[DST[off][,rule]] if (! defined $isdst) { my $j; $time = time() unless $time; ($j, $j, $j, $j, $j, $j, $j, $j, $isdst) = localtime($time); } if (defined $tzn_cache{$TZ}->[$isdst]) { return $tzn_cache{$TZ}->[$isdst]; } # Handle IANA timezone names (e.g., "America/Chicago", "Europe/Paris") if ($TZ =~ m{/}) { my ($std, $dst_name) = _iana_tzname($TZ); $tzn_cache{$TZ} = [ $std, $dst_name ]; return $isdst ? $dst_name : $std; } if ($TZ =~ /^ ( [^:\d+\-,] {3,} ) ( [+-] ? \d {1,2} ( : \d {1,2} ) {0,2} ) ( [^\d+\-,] {3,} )? /x ) { my $dsttz = defined($4) ? $4 : $1; $TZ = $isdst ? $dsttz : $1; $tzn_cache{$TZ} = [ $1, $dsttz ]; } else { $tzn_cache{$TZ} = [ $TZ, $TZ ]; } return $TZ; } my @tz_local; sub tz_local_offset (;$) { my ($time) = @_; $time = time() unless $time; my (@l) = localtime($time); my $isdst = $l[8]; if (defined($tz_local[$isdst])) { return $tz_local[$isdst]; } $tz_local[$isdst] = &calc_off($time); return $tz_local[$isdst]; } sub calc_off { my ($time) = @_; my (@l) = localtime($time); my (@g) = gmtime($time); my $off; $off = $l[0] - $g[0] + ($l[1] - $g[1]) * 60 + ($l[2] - $g[2]) * 3600; # subscript 7 is yday. if ($l[7] == $g[7]) { # done } elsif ($l[7] == $g[7] + 1) { $off += 86400; } elsif ($l[7] == $g[7] - 1) { $off -= 86400; } elsif ($l[7] < $g[7]) { # crossed over a year boundary! # localtime is beginning of year, gmt is end # therefore local is ahead $off += 86400; } else { $off -= 86400; } return $off; } # Helper: temporarily set TZ to an IANA name, run a block, restore original TZ. sub _with_iana_tz (&$) { my ($code, $tz) = @_; my $had_tz = exists $ENV{TZ}; my $saved = $ENV{TZ}; $ENV{TZ} = $tz; tzset(); my @result = $code->(); if ($had_tz) { $ENV{TZ} = $saved } else { delete $ENV{TZ} } tzset(); return @result; } # Return (std_name, dst_name) for an IANA timezone string. sub _iana_tzname { my ($tz) = @_; my ($std, $dst) = _with_iana_tz { tzname() } $tz; $dst = $std unless defined $dst; return ($std, $dst); } # Return the UTC offset in seconds for an IANA timezone string at a given time. sub _iana_offset { my ($tz, $time) = @_; $time = time() unless $time; my ($off) = _with_iana_tz { calc_off($time) } $tz; return $off; } # constants my (%dstZone, %zoneOff, %dstZoneOff, %Zone); CONFIG: { my @dstZone = ( "ndt" => -2*3600-1800, # Newfoundland Daylight "brst" => -2*3600, # Brazil Summer Time (East Daylight) "adt" => -3*3600, # Atlantic Daylight "edt" => -4*3600, # Eastern Daylight "cdt" => -5*3600, # Central Daylight "mdt" => -6*3600, # Mountain Daylight "pdt" => -7*3600, # Pacific Daylight "akdt" => -8*3600, # Alaska Daylight "ydt" => -8*3600, # Yukon Daylight "hdt" => -9*3600, # Hawaii Daylight "bst" => +1*3600, # British Summer "cest" => +2*3600, # Central European Summer (preferred) "mest" => +2*3600, # Middle European Summer (alias, kept for compat) "metdst" => +2*3600, # Middle European DST "sst" => +2*3600, # Swedish Summer "fst" => +2*3600, # French Summer "eest" => +3*3600, # Eastern European Summer "msd" => +4*3600, # Moscow Daylight (historical; Russia abolished DST permanently in Oct 2014) "wadt" => +8*3600, # West Australian Daylight "kdt" => +10*3600, # Korean Daylight # "cadt" => +10*3600+1800, # Central Australian Daylight "aedt" => +11*3600, # Eastern Australian Daylight "eadt" => +11*3600, # Eastern Australian Daylight "nzd" => +13*3600, # New Zealand Daylight "nzdt" => +13*3600, # New Zealand Daylight ); my @Zone = ( "gmt" => 0, # Greenwich Mean "ut" => 0, # Universal (Coordinated) "utc" => 0, "wet" => 0, # Western European "wat" => -1*3600, # West Africa "at" => -2*3600, # Azores "fnt" => -2*3600, # Brazil Time (Extreme East - Fernando Noronha) "brt" => -3*3600, # Brazil Time (East Standard - Brasilia) # For completeness. BST is also British Summer, and GST is also Guam Standard. # "bst" => -3*3600, # Brazil Standard # "gst" => -3*3600, # Greenland Standard "nft" => -3*3600-1800,# Newfoundland "nst" => -3*3600-1800,# Newfoundland Standard "mnt" => -4*3600, # Brazil Time (West Standard - Manaus) "ewt" => -4*3600, # U.S. Eastern War Time "ast" => -4*3600, # Atlantic Standard "est" => -5*3600, # Eastern Standard "act" => -5*3600, # Brazil Time (Extreme West - Acre) "cst" => -6*3600, # Central Standard "mst" => -7*3600, # Mountain Standard "pst" => -8*3600, # Pacific Standard "akst" => -9*3600, # Alaska Standard "yst" => -9*3600, # Yukon Standard "hst" => -10*3600, # Hawaii Standard "cat" => -10*3600, # Central Alaska "ahst" => -10*3600, # Alaska-Hawaii Standard "nt" => -11*3600, # Nome "idlw" => -12*3600, # International Date Line West "cet" => +1*3600, # Central European "mez" => +1*3600, # Central European (German) "ect" => +1*3600, # Central European (French) "met" => +1*3600, # Middle European "mewt" => +1*3600, # Middle European Winter "swt" => +1*3600, # Swedish Winter "set" => +1*3600, # Seychelles "fwt" => +1*3600, # French Winter "eet" => +2*3600, # Eastern Europe, USSR Zone 1 "ukr" => +2*3600, # Ukraine "bt" => +3*3600, # Baghdad, USSR Zone 2 "msk" => +3*3600, # Moscow (UTC+3; was UTC+4 in 2011-2014 when Russia used permanent DST, reverted Oct 2014) # "it" => +3*3600+1800,# Iran "zp4" => +4*3600, # USSR Zone 3 "zp5" => +5*3600, # USSR Zone 4 "ist" => +5*3600+1800,# Indian Standard "zp6" => +6*3600, # USSR Zone 5 # For completeness. NST is also Newfoundland Stanard, and SST is also Swedish Summer. # "nst" => +6*3600+1800,# North Sumatra # "sst" => +7*3600, # South Sumatra, USSR Zone 6 "ict" => +7*3600, # Indochina # "jt" => +7*3600+1800,# Java (3pm in Cronusland!) "ict" => +7*3600, # Indochina Time "wst" => +8*3600, # West Australian Standard "pht" => +8*3600, # Philippine "hkt" => +8*3600, # Hong Kong "pht" => +8*3600, # Philippine Time "cct" => +8*3600, # China Coast, USSR Zone 7 "jst" => +9*3600, # Japan Standard, USSR Zone 8 "kst" => +9*3600, # Korean Standard # "cast" => +9*3600+1800,# Central Australian Standard "aest" => +10*3600, # Eastern Australian Standard "east" => +10*3600, # Eastern Australian Standard "gst" => +10*3600, # Guam Standard, USSR Zone 9 "nzt" => +12*3600, # New Zealand "nzst" => +12*3600, # New Zealand Standard "idle" => +12*3600, # International Date Line East ); %Zone = @Zone; %dstZone = @dstZone; %zoneOff = reverse(@Zone); %dstZoneOff = reverse(@dstZone); } sub tz_offset (;$$) { my ($zone, $time) = @_; return &tz_local_offset($time) unless($zone); $time = time() unless $time; my(@l) = localtime($time); my $dst = $l[8]; # Handle IANA timezone names (e.g., "America/Chicago") before lowercasing if ($zone =~ m{/}) { return _iana_offset($zone, $time); } $zone = lc $zone; if($zone =~ /^(([\-\+])\d\d?)(\d\d)$/) { my $v = $2 . $3; return $1 * 3600 + $v * 60; } elsif (exists $dstZone{$zone} && ($dst || !exists $Zone{$zone})) { return $dstZone{$zone}; } elsif(exists $Zone{$zone}) { return $Zone{$zone}; } undef; } sub tz_name (;$$) { my ($off, $dst) = @_; $off = tz_offset() unless(defined $off); $dst = (localtime(time))[8] unless(defined $dst); if (exists $dstZoneOff{$off} && ($dst || !exists $zoneOff{$off})) { return $dstZoneOff{$off}; } elsif (exists $zoneOff{$off}) { return $zoneOff{$off}; } # $off is in seconds; format as +HHMM / -HHMM. # Using abs() for the minutes component handles negative fractional-hour # offsets correctly (e.g. -9000s = -2h30m → "-0230", not "-02-30"). sprintf("%+03d%02d", int($off / 3600), abs(int($off / 60)) % 60); } 1; __END__ =pod =encoding UTF-8 =head1 NAME Time::Zone - miscellaneous timezone manipulations routines =head1 VERSION version 2.35 =head1 SYNOPSIS use Time::Zone; print tz2zone(); print tz2zone($ENV{'TZ'}); print tz2zone($ENV{'TZ'}, time()); my $isdst = 0; print tz2zone($ENV{'TZ'}, undef, $isdst); my $offset = tz_local_offset(); my $TZ = "EST"; $offset = tz_offset($TZ); =head1 DESCRIPTION This is a collection of miscellaneous timezone manipulation routines. C parses the TZ environment variable and returns a timezone string suitable for inclusion in L-like output. It optionally takes a timezone string, a time, and a is-dst flag. C determines the offset from GMT time in seconds. It only does the calculation once. C determines the offset from GMT in seconds of a specified timezone. C determines the name of the timezone based on its offset =head1 NAME Time::Zone -- miscellaneous timezone manipulations routines =head1 AUTHORS Graham Barr David Muir Sharnoff Paul Foley =head1 AUTHOR Graham =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2020 by Graham Barr. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut lang-encoding.t100644000765000024 230715157412057 16302 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More; use Date::Language; # RT#113419 / GH#19: Language modules must return Unicode strings (UTF-8 flagged), # not raw byte strings in legacy encodings. # # Legacy encoding modules (Chinese_GB, Russian, Russian_koi8r, Russian_cp1251) # intentionally return byte strings and are excluded from this check. my @unicode_langs = qw( Afar Amharic Arabic Austrian Brazilian Bulgarian Chinese Czech Danish Dutch English Finnish French Gedeo German Greek Hungarian Icelandic Italian Norwegian Occitan Oromo Romanian Sidama Somali Spanish Swedish Tigrinya TigrinyaEritrean TigrinyaEthiopian Turkish ); # Tue Sep 7 13:02:42 1999 GMT my $time = 936709362; for my $lang (@unicode_langs) { my $l = Date::Language->new($lang); for my $fmt (qw(%A %a %B %b)) { my $str = $l->time2str($fmt, $time, 'GMT'); # Pure-ASCII strings don't get the UTF-8 flag; skip them. next unless $str =~ /[^\x00-\x7f]/; ok( utf8::is_utf8($str), "$lang $fmt: non-ASCII result has UTF-8 flag set" ); } } done_testing; time2str-lang.t100644000765000024 156615157412057 16273 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 8; use Date::Format qw(time2str); # Unix timestamp for Tue Sep 7 11:22:42 1999 GMT (used in format.t) my $t = 936709362; # Baseline: English (default) is( time2str('%A', $t, 'GMT'), 'Tuesday', 'English day (no lang arg)' ); is( time2str('%B', $t, 'GMT'), 'September', 'English month (no lang arg)'); # Explicit English via language argument is( time2str('%A', $t, 'GMT', 'English'), 'Tuesday', 'English day (explicit)' ); is( time2str('%B', $t, 'GMT', 'English'), 'September', 'English month (explicit)'); # German is( time2str('%A', $t, 'GMT', 'German'), 'Dienstag', 'German day' ); is( time2str('%B', $t, 'GMT', 'German'), 'September', 'German month'); # French is( time2str('%A', $t, 'GMT', 'French'), 'mardi', 'French day' ); is( time2str('%B', $t, 'GMT', 'French'), 'septembre', 'French month'); cpanrt-format.t100644000765000024 112715157412057 16351 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 4; use Date::Format qw(time2str strftime); # RT#45067: Date::Format with %z gives wrong results for half-hour timezones { for my $zone (qw(-0430 -0445)) { my $zone_str = time2str("%Z %z", time, $zone); is($zone_str, "$zone $zone", "RT#45067: half-hour timezone $zone"); } } # RT#52387: seconds since the Epoch, UCT { my $time = time; my @lt = localtime($time); is(strftime("%s", @lt), $time, "RT#52387: strftime %s returns epoch"); is(time2str("%s", $time), $time, "RT#52387: time2str %s returns epoch"); } Date000755000765000024 015157412057 14426 5ustar00nicolasstaff000000000000TimeDate-2.35/libParse.pm100644000765000024 3114615157412057 16223 0ustar00nicolasstaff000000000000TimeDate-2.35/lib/Date# Copyright (c) 1995-2009 Graham Barr. This program is free # software; you can redistribute it and/or modify it under the same terms # as Perl itself. package Date::Parse; require 5.000; use strict; use Time::Local; use Carp; use Time::Zone; use Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(&strtotime &str2time &strptime); our $VERSION = '2.35'; # VERSION: generated # ABSTRACT: Parse date strings into time values my %month = ( january => 0, february => 1, march => 2, april => 3, may => 4, june => 5, july => 6, august => 7, september => 8, sept => 8, october => 9, november => 10, december => 11, ); my %day = ( sunday => 0, monday => 1, tuesday => 2, tues => 2, wednesday => 3, wednes => 3, thursday => 4, thur => 4, thurs => 4, friday => 5, saturday => 6, ); my @suf = (qw(th st nd rd th th th th th th)) x 3; @suf[11,12,13] = qw(th th th); #Abbreviations map { $month{substr($_,0,3)} = $month{$_} } keys %month; map { $day{substr($_,0,3)} = $day{$_} } keys %day; my $strptime = <<'ESQ'; my %month = map { lc $_ } %$mon_ref; my $daypat = join("|", map { lc $_ } reverse sort keys %$day_ref); my $monpat = join("|", reverse sort keys %month); my $sufpat = join("|", reverse sort map { lc $_ } @$suf_ref); my %ampm = ( 'a' => 0, # AM 'p' => 12, # PM ); my($AM, $PM) = (0,12); sub { my $dtstr = lc shift; my $merid = 24; my($century,$year,$month,$day,$hh,$mm,$ss,$zone,$dst,$frac); $zone = tz_offset(shift) if @_; 1 while $dtstr =~ s#\([^\(\)]*\)# #o; $dtstr =~ s#(\A|\n|\Z)# #sog; # ignore day names $dtstr =~ s#([\d\w\s])[\.\,]\s#$1 #sog; $dtstr =~ s/(? 12; return if length($year) > 2 and $year < 1901; } } elsif ($dtstr =~ s#\s(\d+)\s*($sufpat)?\s*($monpat)# #o) { ($month,$day) = ($month{$3},$1); } elsif ($dtstr =~ s#($monpat)\s*(\d+)\s*($sufpat)?\s# #o) { $month = $month{$1}; if ($2 > 31) { $year = $2 } else { $day = $2 } } elsif ($dtstr =~ s#($monpat)([\/-])(\d+)[\/-]# #o) { ($month,$day) = ($month{$1},$3); } # Date: 961212 (YYMMDD — only consume if month is in range 1-12) elsif ($dtstr =~ /\s(\d\d)(\d\d)(\d\d)\s/o && $2 >= 1 && $2 <= 12) { $dtstr =~ s/\s(\d\d)(\d\d)(\d\d)\s/ /; ($year,$month,$day) = ($1,$2-1,$3); } $year = $1 if !defined($year) and $dtstr =~ s#\s(\d{2}(\d{2})?)[\s\.,]# #o; } # Zone $dst = 1 if $dtstr =~ s#\bdst\b##o; if ($dtstr =~ s#\s"?([a-z]{3,4})(dst|\d+[a-z]*|_[a-z]+)?"?\s# #o) { $dst = 1 if $2 and $2 eq 'dst'; $zone = tz_offset($1); return unless defined $zone; } elsif ($dtstr =~ s#\s([a-z]{3,4})?([\-\+]?)-?(\d\d?):?(\d\d)?(00)?\s# #o) { my $m = defined($4) ? "$2$4" : 0; my $h = "$2$3"; $zone = defined($1) ? tz_offset($1) : 0; return unless defined $zone; $zone += 60 * ($m + (60 * $h)); } if ($dtstr =~ /\S/) { # now for some dumb dates if ($dtstr =~ s/^\s*(ut?|z)\s*$//) { $zone = 0; } elsif ($dtstr =~ s#\s([a-z]{3,4})?([\-\+]?)-?(\d\d?)(\d\d)?(00)?\s# #o) { my $m = defined($4) ? "$2$4" : 0; my $h = "$2$3"; $zone = defined($1) ? tz_offset($1) : 0; return unless defined $zone; $zone += 60 * ($m + (60 * $h)); } return if $dtstr =~ /\S/o; } if (defined $hh) { if ($hh == 12) { $hh = 0 if $merid == $AM; } elsif ($merid == $PM) { $hh += 12; } } if (defined $year && $year >= 100) { $century = int($year / 100); $year -= 1900; } $zone += 3600 if defined $zone && $dst; $ss += "0.$frac" if $frac; # Reject inputs that produced only a timezone with no date/time components. # A bare number like '1' or '+0500' gets consumed by the timezone regex, # leaving no meaningful date or time information — these are not valid dates. return unless defined $hh || defined $mm || defined $ss || defined $day || defined $month || defined $year; return ($ss,$mm,$hh,$day,$month,$year,$zone,$century); } ESQ our ($day_ref, $mon_ref, $suf_ref, $obj); sub gen_parser { local($day_ref,$mon_ref,$suf_ref,$obj) = @_; if($obj) { my $obj_strptime = $strptime; substr($obj_strptime,index($strptime,"sub")+6,0) = <<'ESQ'; shift; # package ESQ my $sub = eval "$obj_strptime" or die $@; return $sub; } eval "$strptime" or die $@; } *strptime = gen_parser(\%day,\%month,\@suf); sub str2time { my $now = @_ > 2 ? splice(@_, 2, 1) : time; my @t = strptime(@_); return undef unless @t; my($ss,$mm,$hh,$day,$month,$year,$zone, $century) = @t; my @lt = localtime($now); $hh ||= 0; $mm ||= 0; $ss ||= 0; my $frac = $ss - int($ss); $ss = int $ss; $month = $lt[4] unless(defined $month); $day = $lt[3] unless(defined $day); unless (defined $year) { my $is_future = $month > $lt[4] || ($month == $lt[4] && $day > $lt[3]); $year = $is_future ? ($lt[5] - 1) : $lt[5]; } # we were given a 4 digit year, so let's keep using those $year += 1900 if defined $century; # Normalize two-digit years to 4-digit before passing to Time::Local. # Time::Local's own windowing varies across versions, so we do it ourselves. # Convention: 69-99 -> 1969-1999, 0-68 -> 2000-2068 (POSIX strptime behavior). # Note: first-century dates (years 1-99 AD) are not representable through # str2time — same limitation as POSIX strptime. $year += ($year >= 69 ? 1900 : 2000) if $year < 100; return undef unless($month <= 11 && $day >= 1 && $day <= 31 && $hh <= 23 && $mm <= 59 && $ss <= 59); my $result; if (defined $zone) { $result = eval { local $SIG{__DIE__} = sub {}; # Ick! timegm($ss,$mm,$hh,$day,$month,$year); }; return undef if !defined $result or $result == -1 && join("",$ss,$mm,$hh,$day,$month,$year) ne "595923311169"; # Detect integer overflow: post-1970 dates must produce a non-negative epoch return undef if $result < 0 && $year >= 1970; $result -= $zone; } else { $result = eval { local $SIG{__DIE__} = sub {}; # Ick! timelocal($ss,$mm,$hh,$day,$month,$year); }; return undef if !defined $result or $result == -1 && join("",$ss,$mm,$hh,$day,$month,$year) ne join("",(localtime(-1))[0..5]); # Detect integer overflow: post-1970 dates must produce a non-negative epoch # Use 1971 to avoid false positives from timezone offsets near epoch 0 return undef if $result < 0 && $year >= 1971; } return $result + $frac; } 1; __END__ =pod =encoding UTF-8 =head1 NAME Date::Parse - Parse date strings into time values =head1 VERSION version 2.35 =head1 SYNOPSIS use Date::Parse; my $date = "Wed, 16 Jun 94 07:29:35 CST"; my $time = str2time($date); my ($ss,$mm,$hh,$day,$month,$year,$zone) = strptime($date); =head1 DESCRIPTION C provides two routines for parsing date strings into time values. =over 4 =item str2time(DATE [, ZONE [, EPOCH]]) C parses C and returns a unix time value, or undef upon failure. C, if given, specifies the timezone to assume when parsing if the date string does not specify a timezone. C, if given, is a unix epoch value used as the reference time when filling in missing date components (month, day, or year). Defaults to C. Useful when the current system clock cannot be trusted or when parsing dates relative to a known reference point. =item strptime(DATE [, ZONE]) C takes the same arguments as str2time but returns an array of values C<($ss,$mm,$hh,$day,$month,$year,$zone,$century)>. Elements are only defined if they could be extracted from the date string. An empty array is returned upon failure. The return values follow the same conventions as Perl's built-in C and C functions: =over 4 =item C<$month> 0-indexed: 0 = January, 1 = February, ..., 11 = December. =item C<$year> Years since 1900. For example, the year 2015 is returned as C<115>, and 1995 is returned as C<95>. To recover the full 4-digit year: C<$year + 1900>. =item C<$zone> Timezone offset in seconds from UTC, or C if no timezone was specified in the input string. =item C<$century> Defined only when a 4-digit year was present in the input. Its value is C (e.g. C<20> for the year 2015). When C<$century> is defined, C<$year + 1900> gives the original 4-digit year. =back For example, C returns: ($ss, $mm, $hh, $day, $month, $year, $zone, $century) ( 17, 8, 9, 24, 0, 115, undef, 20 ) # ^--- January (0-indexed) # ^--- 2015 - 1900 # ^--- not in input # ^--- int(2015/100) =back =head1 NAME Date::Parse - Parse date strings into time values =head1 MULTI-LANGUAGE SUPPORT Date::Parse is capable of parsing dates in several languages, these include English, French, German and Italian. $lang = Date::Language->new('German'); $lang->str2time("25 Jun 1996 21:09:55 +0100"); =head1 EXAMPLE DATES Below is a sample list of dates that are known to be parsable with Date::Parse 1995-01-24T09:08:17.1823213 ISO-8601 Wed, 16 Jun 94 07:29:35 CST Comma and day name are optional Thu, 13 Oct 94 10:13:13 -0700 Wed, 9 Nov 1994 09:50:32 -0500 (EST) Text in ()'s will be ignored. 21 dec 17:05 Will be parsed in the current time zone 21-dec 17:05 21/dec 17:05 21/dec/93 17:05 1999 10:02:18 "GMT" 16 Nov 94 22:28:20 PST =head1 BUGS When both the month and the date are specified in the date as numbers they are always parsed assuming that the month number comes before the date. This is the usual format used in American dates. The reason why it is like this and not dynamic is that it must be deterministic. Several people have suggested using the current locale, but this will not work as the date being parsed may not be in the format of the current locale. My plans to address this, which will be in a future release, is to allow the programmer to state what order they want these values parsed in. =head1 AUTHOR Graham Barr =head1 COPYRIGHT Copyright (c) 1995-2009 Graham Barr. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR Graham =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2020 by Graham Barr. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut str2time-epoch.t100644000765000024 243315157412057 16442 0ustar00nicolasstaff000000000000TimeDate-2.35/tuse strict; use warnings; use Test::More tests => 5; use Date::Parse qw(str2time); # RT#64789: str2time() should accept an optional epoch as third argument # to use as the reference time instead of time() when filling in missing # date components (month, day, year). { # Use a known fixed epoch as the reference time: # 2010-06-15 12:00:00 UTC = 1276603200 my $ref_epoch = 1276603200; # 2010-06-15 12:00:00 UTC # Parsing "21 feb" with no year: February (month 1) < June (month 5), # so February is in the past — most recent occurrence is current year (2010). my $t = str2time("21 feb 17:05 UTC", undef, $ref_epoch); ok(defined $t, "RT#64789: str2time with epoch arg returns defined"); my $parsed_year = 1900 + (gmtime($t))[5]; is($parsed_year, 2010, "RT#64789: 'feb' with epoch 2010-06 stays in 2010 (most recent occurrence)"); # Parsing a time-only string: "10:30:00 UTC" # With ref_epoch (2010-06-15), the date portion should come from ref_epoch my $t2 = str2time("10:30:00 UTC", undef, $ref_epoch); ok(defined $t2, "RT#64789: time-only str2time with epoch arg returns defined"); my @gm2 = gmtime($t2); is($gm2[3], 15, "RT#64789: time-only: day from ref_epoch"); is(1900 + $gm2[5], 2010, "RT#64789: time-only: year from ref_epoch"); } Format.pm100644000765000024 1216015157412057 16374 0ustar00nicolasstaff000000000000TimeDate-2.35/lib/Date# Copyright (c) 1995-2009 Graham Barr. This program is free # software; you can redistribute it and/or modify it under the same terms # as Perl itself. package Date::Format; use strict; require Exporter; our $VERSION = '2.35'; # VERSION: generated # ABSTRACT: Date formatting subroutines use Date::Format::Generic; our @ISA = qw(Exporter); our @EXPORT = qw(time2str strftime ctime asctime); sub time2str ($;$$$) { my ($fmt, $time, $zone, $lang) = @_; my $pkg = defined $lang ? do { require Date::Language; Date::Language->new($lang) } : 'Date::Format::Generic'; $pkg->time2str($fmt, $time, $zone); } sub strftime ($\@;$) { Date::Format::Generic->strftime(@_); } sub ctime ($;$) { my ($t,$tz) = @_; Date::Format::Generic->time2str("%a %b %e %T %Y\n", $t, $tz); } sub asctime (\@;$) { my ($t,$tz) = @_; Date::Format::Generic->strftime("%a %b %e %T %Y\n", $t, $tz); } 1; __END__ =pod =encoding UTF-8 =head1 NAME Date::Format - Date formatting subroutines =head1 VERSION version 2.35 =head1 SYNOPSIS use Date::Format; my @lt = localtime(time); my $template = "...."; print time2str($template, time); print strftime($template, @lt); my $zone; print time2str($template, time, $zone); print strftime($template, @lt, $zone); print ctime(time); print asctime(@lt); print ctime(time, $zone); print asctime(@lt, $zone); =head1 DESCRIPTION This module provides routines to format dates into ASCII strings. They correspond to the C library routines C and C. =over 4 =item time2str(TEMPLATE, TIME [, ZONE [, LANGUAGE]]) C converts C