File Coverage

blib/lib/DateTime/Calendar/FrenchRevolutionary.pm
Criterion Covered Total %
statement 258 280 92.1
branch 61 68 89.7
condition 23 27 85.1
subroutine 76 80 95.0
pod 42 51 82.3
total 460 506 90.9


line stmt bran cond sub pod time code
1             # -*- encoding: utf-8; indent-tabs-mode: nil -*-
2             #
3             # Perl DateTime extension for converting to/from the French Revolutionary calendar
4             # Copyright (c) 2003, 2004, 2010, 2011, 2012, 2014, 2016 Jean Forget. All rights reserved.
5             #
6             # See the license in the embedded documentation below.
7             #
8              
9             package DateTime::Calendar::FrenchRevolutionary;
10              
11 17     17   23658 use utf8;
  17         176  
  17         81  
12 17     17   556 use strict;
  17         22  
  17         412  
13 17     17   71 use warnings;
  17         25  
  17         599  
14              
15 17     17   74 use vars qw($VERSION);
  17         22  
  17         1328  
16             $VERSION = '0.14';
17              
18 17     17   10329 use Params::Validate qw(validate SCALAR BOOLEAN OBJECT);
  17         161522  
  17         1780  
19 17     17   9014 use Roman;
  17         13392  
  17         1143  
20 17     17   18511 use DateTime;
  17         7100365  
  17         916  
21 17     17   11351 use DateTime::Calendar::FrenchRevolutionary::Locale;
  17         36  
  17         19688  
22              
23             my $BasicValidate =
24             { year => { type => SCALAR },
25             month => { type => SCALAR, default => 1,
26             callbacks =>
27             { 'is between 1 and 13' =>
28             sub { $_[0] >= 1 && $_[0] <= 13 }
29             },
30             },
31             day => { type => SCALAR, default => 1,
32             callbacks =>
33             { 'is between 1 and 30' =>
34             sub { $_[0] >= 1 && $_[0] <= 30 },
35             },
36             },
37             hour => { type => SCALAR, default => 0,
38             callbacks =>
39             { 'is between 0 and 9' =>
40             sub { $_[0] >= 0 && $_[0] <= 9 },
41             },
42             },
43             minute => { type => SCALAR, default => 0,
44             callbacks =>
45             { 'is between 0 and 99' =>
46             sub { $_[0] >= 0 && $_[0] <= 99 },
47             },
48             },
49             second => { type => SCALAR, default => 0,
50             callbacks =>
51             { 'is between 0 and 99' =>
52             sub { $_[0] >= 0 && $_[0] <= 99 },
53             },
54             },
55             abt_hour => { type => SCALAR, default => 0,
56             callbacks =>
57             { 'is between 0 and 23' =>
58             sub { $_[0] >= 0 && $_[0] <= 23 },
59             },
60             },
61             abt_minute => { type => SCALAR, default => 0,
62             callbacks =>
63             { 'is between 0 and 59' =>
64             sub { $_[0] >= 0 && $_[0] <= 59 },
65             },
66             },
67             abt_second => { type => SCALAR, default => 0,
68             callbacks =>
69             { 'is between 0 and 61' =>
70             sub { $_[0] >= 0 && $_[0] <= 61 },
71             },
72             },
73             nanosecond => { type => SCALAR, default => 0,
74             callbacks =>
75             { 'cannot be negative' =>
76             sub { $_[0] >= 0 },
77             }
78             },
79             locale => { type => SCALAR | OBJECT,
80             callbacks =>
81             { "only 'fr' and 'en' possible" =>
82             sub { ($_[0] eq 'fr') or ($_[0] eq 'en') or ref($_[0]) =~ /(?:en|fr)$/ },
83             },
84             default => DefaultLocale() },
85             };
86              
87             my $NewValidate =
88             { %$BasicValidate,
89             time_zone => { type => SCALAR | OBJECT,
90             callbacks =>
91             { "only 'floating' possible" =>
92             sub { ($_[0] eq 'floating') or ref($_[0]) and $_[0]->is_floating },
93             },
94             default => 'floating' },
95             };
96             my $Lastday_validate = { %$BasicValidate };
97             delete $Lastday_validate->{day};
98              
99             # Constructors
100             sub new {
101 1359     1359 1 86716 my $class = shift;
102 1359         19731 my %args = validate( @_, $NewValidate );
103              
104 1356         8286 my $self = {};
105              
106 1356         13899 $self->{tz} = DateTime::TimeZone->new(name => 'floating');
107 1356 100       78290 if ( ref $args{locale} )
108 2         4 { $self->{locale} = $args{locale} }
109             else
110 1354         4914 { $self->{locale} = DateTime::Calendar::FrenchRevolutionary::Locale->load( $args{locale} ) }
111              
112 1356         3848 $self->{local_rd_days} = $class->_ymd2rd(@args{qw(year month day)});
113 1356         3360 my $abtsecs = $class->_time_as_abt_seconds(@args{qw(abt_hour abt_minute abt_second)});
114 1356         2961 my $decsecs = $class->_time_as_seconds(@args{qw(hour minute second)});
115 1356 0 33     3891 warn("You cannot specify both 24x60x60 time and 10x100x100 time when initializing a date")
      33        
116             if $^W && $abtsecs && $decsecs;
117             # We prefer decimal time over Anglo-Babylonian time when initializing a date
118 1356 100       2363 $self->{local_rd_secs} = $decsecs ? $decsecs : $abtsecs;
119 1356         1720 $self->{rd_nano} = $args{nanosecond};
120              
121 1356         1704 bless $self, $class;
122 1356         2574 $self->_calc_local_components;
123 1356         2570 $self->_calc_utc_rd;
124              
125 1356         5719 return $self;
126             }
127              
128             sub from_epoch {
129 3     3 1 35 my $class = shift;
130 3         24 my %args = validate( @_,
131             { epoch => { type => SCALAR },
132             locale => { type => SCALAR | OBJECT,
133             default => $class->DefaultLocale },
134              
135             }
136             );
137              
138 3         30 my $date = DateTime->from_epoch(%args);
139 3         2471 return $class->from_object(object => $date);
140             }
141              
142             # use scalar time in case someone's loaded Time::Piece
143 1     1 1 748 sub now { shift->from_epoch(epoch => (scalar time), @_) }
144              
145             sub from_object {
146 147     147 1 73300 my $class = shift;
147 147         747 my %args = validate(@_,
148             { object => { type => OBJECT,
149             can => 'utc_rd_values',
150             },
151             locale => { type => SCALAR | OBJECT,
152             default => $class->DefaultLocale },
153             },
154             );
155              
156 147         767 my $object = delete $args{object};
157 147 50       877 $object = $object->clone->set_time_zone('floating')
158             if $object->can('set_time_zone');
159              
160 147         4427 my ($rd_days, $rd_secs, $rd_nano) = $object->utc_rd_values;
161              
162 147         789 my %p;
163 147         366 @p{ qw(year month day) } = $class->_rd2ymd($rd_days);
164             # ABT seconds preferred over decimal seconds, because of precision loss
165 147         410 @p{ qw(abt_hour abt_minute abt_second) } = $class->_abt_seconds_as_components($rd_secs);
166             # nanoseconds are copied, never converted ABT to decimal or reverse
167 147   100     582 $p{nanosecond} = $rd_nano || 0;
168             #@p{ qw(hour minute second) } = $class->_seconds_as_components($rd_secs);
169              
170 147         600 my $new = $class->new(%p, %args, time_zone => 'floating');
171              
172 147         939 return $new;
173             }
174              
175             sub last_day_of_month {
176 33     33 1 553 my $class = shift;
177 33         495 my %p = validate( @_, $Lastday_validate);
178 33 100       236 my $day = $p{month} <= 12 ? 30 : $class->_is_leap_year($p{year}) ? 6 : 5;
    100          
179 33         147 return $class->new(%p, day => $day);
180             }
181              
182 1     1 1 8 sub clone { bless { %{ $_[0] } }, ref $_[0] }
  1         7  
183              
184             # Many of the same parameters as new() but all of them are optional,
185             # and there are no defaults.
186             my $SetValidate =
187             { map { my %copy = %{ $BasicValidate->{$_} };
188             delete $copy{default};
189             $copy{optional} = 1;
190             $_ => \%copy }
191             keys %$BasicValidate };
192             sub set
193             {
194 16     16 1 18 my $self = shift;
195 16         199 my %p = validate( @_, $SetValidate );
196              
197             my %old_p =
198 16         58 ( map { $_ => $self->$_() }
  128         203  
199             qw( year month day hour minute second nanosecond locale )
200             );
201              
202 16         73 my $new_dt = (ref $self)->new( %old_p, %p );
203              
204 16         111 %$self = %$new_dt;
205              
206 16         97 return $self;
207             }
208              
209       1 0   sub set_time_zone { } # do nothing, only 'floating' allowed
210              
211             # Internal functions
212 17     17   125 use constant REV_BEGINNING => 654415; # RD value for 1 Vendémiaire I in the Revolutionary calendar
  17         32  
  17         1600  
213 17     17   89 use constant NORMAL_YEAR => 365;
  17         24  
  17         881  
214 17     17   74 use constant LEAP_YEAR => 366;
  17         39  
  17         936  
215 17     17   74 use constant FOUR_YEARS => 4 * NORMAL_YEAR + 1; # one leap year every four years
  17         42  
  17         897  
216 17     17   74 use constant CENTURY => 25 * FOUR_YEARS - 1; # centuries aren't leap years...
  17         33  
  17         856  
217 17     17   67 use constant FOUR_CENTURIES => 4 * CENTURY + 1; # ...except every four centuries that are.
  17         42  
  17         1218  
218 17     17   85 use constant FOUR_MILLENIA => 10 * FOUR_CENTURIES - 1; # ...except every four millenia that are not.
  17         48  
  17         67377  
219              
220             # number of days between the start of the revolutionary calendar, and the
221             # beginning of year n - 1 as long as the equinox rule is in effect
222             my @YEARS_BEGINS= (0, 365, 730, 1096, 1461, 1826, 2191, 2557, 2922, 3287, 3652,
223             4018, 4383, 4748, 5113, 5479, 5844);
224             sub _is_leap_year {
225 69     69   91 my ($self, $year) = @_;
226              
227             # Autumn equinox from I to XIX
228 69 100 100     590 return 1 if ($year == 3) or ($year == 7) or ($year == 11) or ($year == 15);
      100        
      100        
229 61 100       184 return 0 if ($year < 20);
230              
231             # Romme rule from XX on
232 41 100       148 return 0 if $year % 4; # not a multiple of 4 -> normal year
233 26 100       65 return 1 if $year % 100; # a multiple of 4 but not of 100 is a leap year
234 21 100       63 return 0 if $year % 400; # a multiple of 100 but not of 400 is a normal year
235 8 100       78 return 1 if $year % 4000; # a multiple of 400 but not of 4000 is leap
236 3         11 return 0; # a multiple of 4000 is a normal year
237             }
238              
239             sub _calc_utc_rd {
240 1356     1356   1220 my $self = shift;
241              
242 1356         1487 delete $self->{utc_c};
243              
244 1356 50       4284 if ($self->{tz}->is_utc)
245             {
246 0         0 $self->{utc_rd_days} = $self->{local_rd_days};
247 0         0 $self->{utc_rd_secs} = $self->{local_rd_secs};
248 0         0 return;
249             }
250              
251 1356         4902 $self->{utc_rd_days} = $self->{local_rd_days};
252 1356         2357 $self->{utc_rd_secs} = $self->{local_rd_secs} - $self->_offset_from_local_time;
253 1356         6409 _normalize_seconds($self->{utc_rd_days}, $self->{utc_rd_secs}, $self->{rd_nano});
254             }
255              
256             sub _calc_local_rd {
257 0     0   0 my $self = shift;
258              
259 0         0 delete $self->{local_c};
260              
261             # We must short circuit for UTC times or else we could end up with
262             # loops between DateTime.pm and DateTime::TimeZone
263 0 0       0 if ($self->{tz}->is_utc)
264             {
265 0         0 $self->{local_rd_days} = $self->{utc_rd_days};
266 0         0 $self->{local_rd_secs} = $self->{utc_rd_secs};
267             }
268             else
269             {
270 0         0 $self->{local_rd_days} = $self->{utc_rd_days};
271 0         0 $self->{local_rd_secs} = $self->{utc_rd_secs} + $self->offset;
272 0         0 _normalize_seconds($self->{local_rd_days}, $self->{local_rd_secs});
273             }
274              
275 0         0 $self->_calc_local_components;
276             }
277              
278             sub _normalize_seconds {
279 1356     1356   1565 my ($d, $s) = @_;
280 1356         1187 my $adj;
281 1356 50       2171 if ($s < 0)
282 0         0 { $adj = int(($s - 86399) / 86400) }
283             else
284 1356         1586 { $adj = int($s / 86400) }
285 1356         1290 $_[0] += $adj;
286 1356         1940 $_[1] -= $adj * 86400;
287             }
288              
289             sub _calc_local_components {
290 1356     1356   1425 my $self = shift;
291 1356         5045 @{ $self->{local_c} }{ qw(year month day day_of_decade day_of_year) }
292 1356         2589 = $self->_rd2ymd($self->{local_rd_days}, 1);
293 1356         3885 @{ $self->{local_c} }{ qw(abt_hour abt_minute abt_second) }
294 1356         2945 = $self->_abt_seconds_as_components($self->{local_rd_secs});
295 1356         2958 @{ $self->{local_c} }{ qw(hour minute second) }
296 1356         2711 = $self->_seconds_as_components($self->{local_rd_secs});
297             }
298              
299             sub _calc_utc_components {
300 0     0   0 my $self = shift;
301 0         0 @{ $self->{utc_c} }{ qw(year month day) } = $self->_rd2ymd($self->{utc_rd_days});
  0         0  
302 0         0 @{ $self->{utc_c} }{ qw(abt_hour abt_minute abt_second) }
303 0         0 = $self->_abt_seconds_as_components($self->{utc_rd_secs});
304 0         0 @{ $self->{utc_c} }{ qw(hour minute second) }
305 0         0 = $self->_seconds_as_components($self->{utc_rd_secs});
306             }
307              
308             sub _ymd2rd {
309 1356     1356   2000 my ($self, $y, $m, $d) = @_;
310 1356         1307 my $rd = REV_BEGINNING - 1; # minus 1 for the zeroth Vendémiaire
311 1356         1327 $y --; #get years *before* this year. Makes math easier. :)
312             # first, convert year into days. . .
313 1356 100 100     6107 if ($y < 0 || $y >= 16) # Romme rule in effect, or nearly so
314             {
315 219         529 my $x = int($y/4000);
316 219 100       458 --$x if $y <= 0;
317 219         326 $rd += $x * FOUR_MILLENIA;
318 219         263 $y %= 4000;
319 219         318 $rd += int($y/400)* FOUR_CENTURIES;
320 219         224 $y %= 400;
321 219         299 $rd += int($y/100)* CENTURY;
322 219         214 $y %= 100;
323 219         286 $rd += int($y/4)* FOUR_YEARS;
324 219         215 $y %= 4;
325 219         283 $rd += $y * NORMAL_YEAR;
326             }
327             else # table look-up for the programmer-hostile equinox rule
328 1137         1539 { $rd += $YEARS_BEGINS[$y] }
329              
330             # now, month into days.
331 1356         2185 $rd += 30 * ($m - 1) + $d;
332 1356         2247 return $rd;
333             }
334              
335             sub _rd2ymd {
336 1503     1503   1753 my ($self, $rd, $extra) = @_;
337              
338 1503         1331 my $doy;
339             my $y;
340             # note: years and days are initially days *before* today, rather than
341             # today's date. This is because of fenceposts. :)
342 1503         1488 $doy = $rd - REV_BEGINNING;
343 1503 100 100     5480 if ($doy >= 0 && $doy < $YEARS_BEGINS[16])
344             {
345 1196         1509 $y = scalar grep { $_ <= $doy } @YEARS_BEGINS;
  20332         20767  
346 1196         1564 $doy -= $YEARS_BEGINS[$y - 1];
347 1196         1131 $doy++;
348             }
349             else
350             {
351             #$doy --;
352 307         310 my $x;
353 307         460 $x = int ($doy / FOUR_MILLENIA);
354 307 100       616 --$x if $doy < 0; # So pre-1792 dates will give something that look about right
355 307         382 $y += $x * 4000;
356 307         370 $doy -= $x * FOUR_MILLENIA;
357              
358 307         380 $x = int ($doy / FOUR_CENTURIES);
359 307         335 $y += $x * 400;
360 307         378 $doy -= $x * FOUR_CENTURIES;
361              
362 307         345 $x = int ($doy / CENTURY);
363 307 100       577 $x = 3 if $x == 4; # last day of the 400-year period; see comment below
364 307         329 $y += $x * 100;
365 307         292 $doy -= $x * CENTURY;
366              
367 307         310 $x = int ($doy / FOUR_YEARS);
368 307         310 $y += $x * 4;
369 307         297 $doy -= $x * FOUR_YEARS;
370              
371 307         304 $x = int ($doy / NORMAL_YEAR);
372             # The integer division above divides the 4-year period, 1461 days,
373             # into 5 parts: 365, 365, 365, 365 and 1. This mathematically sound operation
374             # is wrong with respect to the calendar, which needs to divide
375             # into 4 parts: 365, 365, 365 and 366. Therefore the adjustment below.
376 307 100       552 $x = 3 if $x == 4; # last day of the 4-year period
377 307         304 $y += $x;
378 307         304 $doy -= $x * NORMAL_YEAR;
379              
380 307         271 ++$y; # because of 0-based mathematics vs 1-based chronology
381 307         336 ++$doy;
382             }
383 1503   100     2932 my $d = $doy % 30 || 30;
384 1503         2329 my $m = ($doy - $d) / 30 + 1;
385 1503 100       2467 if ($extra)
386             {
387             # day_of_decade, day_of_year
388 1356   100     2261 my $dod = ($d % 10) || 10;
389 1356         2836 return $y, $m, $d, $dod, $doy;
390             }
391 147         434 return $y, $m, $d;
392             }
393              
394             # Aliases provided for compatibility with DateTime; if DateTime switches
395             # over to _ymd2rd and _rd2ymd, these will be removed eventually.
396             *_greg2rd = \&_ymd2rd;
397             *_rd2greg = \&_rd2ymd;
398              
399             #
400             # Accessors
401             #
402 1262     1262 1 6069 sub year { $_[0]->{local_c}{year} }
403              
404 59     59 1 189 sub month { $_[0]->{local_c}{month} }
405             *mon = \&month;
406              
407 119     119 1 784 sub month_0 { $_[0]->{local_c}{month} - 1 };
408             *mon_0 = \&month_0;
409              
410             sub month_name {
411 105     105 1 165 my $self = shift;
412 105         376 return $self->{locale}->month_name($self);
413             #return $months[$self->month_0]
414             }
415              
416             sub month_abbr {
417 12     12 1 13 my $self = shift;
418 12         44 return $self->{locale}->month_abbreviation($self);
419             #return $months_short[$self->month_0]
420             }
421              
422 169     169 1 996 sub day_of_month { $_[0]->{local_c}{day} }
423             *day = \&day_of_month;
424             *mday = \&day_of_month;
425              
426 6     6 0 25 sub day_of_month_0 { $_[0]->{local_c}{day} - 1 }
427             *day_0 = \&day_of_month_0;
428             *mday_0 = \&day_of_month_0;
429              
430 17 100   17 1 104 sub day_of_decade { $_[0]->{local_c}{day} % 10 || 10 }
431             *dod = \&day_of_decade;
432             *dow = \&day_of_decade;
433             *wday = \&day_of_decade;
434             *day_of_week = \&day_of_decade;
435              
436 56     56 0 261 sub day_of_decade_0 { ($_[0]->{local_c}{day} - 1) % 10 }
437             *dod_0 = \&day_of_decade_0;
438             *dow_0 = \&day_of_decade_0;
439             *wday_0 = \&day_of_decade_0;
440             *day_of_week_0 = \&day_of_decade_0;
441              
442             sub day_name {
443 32     32 1 64 my $self = shift;
444 32         102 return $self->{locale}->day_name($self);
445             #return $decade_days[$self->day_of_decade_0];
446             }
447              
448             sub day_abbr {
449 14     14 1 16 my $self = shift;
450 14         42 return $self->{locale}->day_abbreviation($self);
451             #return $decade_days_short[$self->day_of_decade_0];
452             }
453              
454 8     8 1 29 sub day_of_year { $_[0]->{local_c}{day_of_year} }
455             *doy = \&day_of_year;
456              
457 63     63 0 187 sub day_of_year_0 { $_[0]->{local_c}{day_of_year} - 1 }
458             *doy_0 = \&day_of_year_0;
459              
460             sub feast_short {
461 6     6 1 43 my ($dt) = @_;
462 6         37 return $dt->{locale}->feast_short($dt);
463             }
464             *feast = \&feast_short;
465              
466             sub _raw_feast {
467 2     2   2 my ($dt) = @_;
468 2         15 return $dt->{locale}->_raw_feast($dt);
469             }
470              
471             sub feast_long {
472 15     15 1 37 my ($dt) = @_;
473 15         47 return $dt->{locale}->feast_long($dt);
474             }
475              
476             sub feast_caps {
477 36     36 1 70 my ($dt) = @_;
478 36         114 return $dt->{locale}->feast_caps($dt);
479             }
480              
481             sub ymd {
482 1029     1029 1 1057 my ($self, $sep) = @_;
483 1029 100       2088 $sep = '-' unless defined $sep;
484             return sprintf("%0.4d%s%0.2d%s%0.2d",
485             $self->year, $sep,
486             $self->{local_c}{month}, $sep,
487 1029         1554 $self->{local_c}{day});
488             }
489             *date = \&ymd;
490              
491             sub mdy {
492 4     4 1 15 my ($self, $sep) = @_;
493 4 100       11 $sep = '-' unless defined $sep;
494             return sprintf("%0.2d%s%0.2d%s%0.4d",
495             $self->{local_c}{month}, $sep,
496 4         10 $self->{local_c}{day}, $sep,
497             $self->year);
498             }
499              
500             sub dmy {
501 4     4 1 18 my ($self, $sep) = @_;
502 4 100       11 $sep = '-' unless defined $sep;
503             return sprintf("%0.2d%s%0.2d%s%0.4d",
504             $self->{local_c}{day}, $sep,
505 4         13 $self->{local_c}{month}, $sep,
506             $self->year);
507             }
508              
509             # Anglo-Babylonian (or sexagesimal) time
510 2     2 1 9 sub abt_hour { $_[0]->{local_c}{abt_hour} }
511 2     2 1 7 sub abt_minute { $_[0]->{local_c}{abt_minute} } *abt_min = \&abt_minute;
512 2     2 1 7 sub abt_second { $_[0]->{local_c}{abt_second} } *abt_sec = \&abt_second;
513             sub abt_hms {
514 7     7 1 19 my ($self, $sep) = @_;
515 7 100       17 $sep = ':' unless defined $sep;
516             return sprintf("%0.2d%s%0.2d%s%0.2d",
517             $self->{local_c}{abt_hour}, $sep,
518             $self->{local_c}{abt_minute}, $sep,
519 7         132 $self->{local_c}{abt_second});
520             }
521              
522 16     16 0 24 sub nanosecond { $_[0]->{rd_nano} }
523              
524             # Decimal time
525 55     55 1 194 sub hour { $_[0]->{local_c}{hour} }
526 39     39 1 104 sub minute { $_[0]->{local_c}{minute} } *min = \&minute;
527 40     40 1 99 sub second { $_[0]->{local_c}{second} } *sec = \&second;
528              
529             sub hms {
530 1027     1027 1 1055 my ($self, $sep) = @_;
531 1027 100       1781 $sep = ':' unless defined $sep;
532             return sprintf("%0.1d%s%0.2d%s%0.2d",
533             $self->{local_c}{hour}, $sep,
534             $self->{local_c}{minute}, $sep,
535 1027         3833 $self->{local_c}{second} );
536             }
537             # don't want to override CORE::time()
538             *DateTime::Calendar::FrenchRevolutionary::time = \&hms;
539              
540             sub iso8601 {
541 1025     1025 1 3017 my $self = shift;
542 1025         1598 return join 'T', $self->ymd, $self->hms(':');
543             }
544             *datetime = \&iso8601;
545              
546 46     46 1 195 sub is_leap_year { $_[0]->_is_leap_year($_[0]->year) }
547              
548             sub decade_number {
549 11     11 1 11 my $self = shift;
550 11         20 return 3 * $self->month + int(($self->day - 1) / 10) - 2;
551             }
552             *week_number = \&decade_number;
553              
554             sub decade {
555 1     1 1 7 my $self = shift;
556 1         3 return ($self->year, $self->decade_number);
557             }
558             *week = \&decade;
559              
560             #sub time_zone { $_[0]->{tz} }
561              
562 2     2 0 31 sub offset { $_[0]->{tz}->offset_for_datetime($_[0]) }
563 1356     1356   3361 sub _offset_from_local_time { $_[0]->{tz}->offset_for_local_datetime($_[0]) }
564              
565             #sub is_dst { $_[0]->{tz}->is_dst_for_datetime($_[0]) }
566              
567             #sub time_zone_short_name { $_[0]->{tz}->short_name_for_datetime($_[0]) }
568              
569 16     16 1 57 sub locale { $_[0]->{locale} }
570              
571 101     101 1 8237 sub utc_rd_values { @{ $_[0] }{ 'utc_rd_days', 'utc_rd_secs', 'rd_nano' } }
  101         435  
572              
573             # Anglo-Babylonian time
574 0     0 0 0 sub utc_rd_as_abt_seconds { ($_[0]->{utc_rd_days} * 86400) + $_[0]->{utc_rd_secs} }
575 0     0 0 0 sub local_rd_as_abt_seconds { ($_[0]->{local_rd_days} * 86400) + $_[0]->{local_rd_secs} }
576 1356     1356   2084 sub _time_as_abt_seconds { $_[1] * 3600 + $_[2] * 60 + $_[3] }
577 1503     1503   4049 sub _abt_seconds_as_components { int($_[1] / 3600), int($_[1] % 3600 / 60), $_[1] % 60 }
578              
579             # Decimal time
580 1356     1356   2563 sub _time_as_seconds { .864 * ($_[1] * 10000 + $_[2] * 100 + $_[3]) }
581             sub _seconds_as_components {
582 1356     1356   1849 my $sec = int(.5 + $_[1] / .864);
583 1356         2568 int($sec / 10000), int($sec % 10000 / 100), $sec % 100
584             }
585              
586             # RD 1 is JD 1,721,424.5 - a simple offset
587             sub jd {
588 2     2 1 17 my $self = shift;
589 2         4 my $jd = $self->{utc_rd_days} + 1_721_424.5;
590 2         8 return $jd + ($self->{utc_rd_secs} / 86400);
591             }
592              
593 1     1 1 7 sub mjd { $_[0]->jd - 2_400_000.5 }
594              
595             my %formats = (
596             'a' => sub { $_[0]->day_abbr }
597             , 'A' => sub { $_[0]->day_name }
598             , 'b' => sub { $_[0]->month_abbr }
599             , 'B' => sub { $_[0]->month_name }
600             , 'c' => sub { $_[0]->strftime( $_[0]->{locale}->default_datetime_format ) }
601             , 'C' => sub { int($_[0]->year / 100) }
602             , 'd' => sub { sprintf '%02d', $_[0]->day_of_month }
603             , 'D' => sub { $_[0]->strftime('%m/%d/%y') }
604             , 'e' => sub { sprintf('%2d', $_[0]->day_of_month) }
605             , 'f' => sub { sprintf('%2d', $_[0]->month) }
606             , 'F' => sub { $_[0]->ymd('-') }
607             , 'g' => sub { substr($_[0]->year, -2) }
608             , 'G' => sub { sprintf '%04d', $_[0]->year }
609             , 'h' => sub { $_[0]->month_abbr }
610             , 'H' => sub { sprintf('%d', $_[0]->hour) }
611             , 'I' => sub { my $h = $_[0]->hour || 10; sprintf('%d', $h) }
612             , 'j' => sub { sprintf '%03d', $_[0]->day_of_year }
613             , 'k' => sub { sprintf('%2d', $_[0]->hour) }
614             , 'l' => sub { my $h = $_[0]->hour || 10; sprintf('%2d', $h) }
615             , 'L' => sub { sprintf '%04d', $_[0]->year }
616             , 'm' => sub { sprintf '%02d', $_[0]->month }
617             , 'M' => sub { sprintf '%02d', $_[0]->minute }
618             , 'n' => sub { "\n" } # should this be OS-sensitive?
619             , 'p' => sub { $_[0]->{locale}->am_pm($_[0]) }
620             , 'P' => sub { lc $_[0]->{locale}->am_pm($_[0]) }
621             , 'r' => sub { $_[0]->strftime('%I:%M:%S %p') }
622             , 'R' => sub { $_[0]->strftime('%H:%M') }
623             , 's' => sub { $_[0]->epoch }
624             , 'S' => sub { sprintf('%02d', $_[0]->second) }
625             , 't' => sub { "\t" }
626             , 'T' => sub { $_[0]->strftime('%H:%M:%S') }
627             , 'u' => sub { sprintf '%2d', $_[0]->day_of_decade },
628             , 'U' => sub { $_[0]->decade_number }
629             , 'V' => sub { $_[0]->decade_number }
630             , 'w' => sub { $_[0]->day_of_decade % 10 }
631             , 'W' => sub { $_[0]->decade_number }
632             , 'y' => sub { sprintf('%02d', substr( $_[0]->year, -2 )) }
633             , 'Y' => sub { sprintf '%04d', $_[0]->year }
634             , 'z' => sub { DateTime::TimeZone::offset_as_string( $_[0]->offset ) }
635             , 'Z' => sub { $_[0]->{tz}->short_name_for_datetime($_[0]) }
636             , '+' => sub { '+' }
637             , '%' => sub { '%' }
638             , 'EY' => sub { Roman $_[0]->year || $_[0]->year }
639             , 'Ey' => sub { roman $_[0]->year || $_[0]->year }
640             , '*' => sub { $_[0]->feast_long }
641             , 'Ej' => sub { $_[0]->feast_long }
642             , 'EJ' => sub { $_[0]->feast_caps }
643             , 'Oj' => sub { $_[0]->feast_short }
644              
645             );
646              
647             $formats{h} = $formats{b};
648              
649             sub strftime {
650 173     173 1 249 my $self = shift;
651             # make a copy or caller's scalars get munged
652 173         303 my @formats = @_;
653              
654 173         190 my @r;
655 173         277 foreach my $f (@formats)
656             {
657             # regex from DateTime from Date::Format - thanks Graham and Dave!
658             # but there is a twist: 3-char format specifiers such as '%Ey' are
659             # allowed. All 3-char specifiers begin with a '%E' or '%O' prefix.
660             # At the same time, if the user wants %Em or %Om, which do not exist, it defaults to %m
661             # And if the user asks for %E!,
662             # it defaults to E! because neither %E! nor %! exist.
663 184         1238 $f =~ s/
664             \%([EO]?([*%a-zA-Z]))
665             | \%\{(\w+)\}
666             /
667             $3 ? ($self->can($3) ? $self->$3() : "\%{$3}")
668             : ($formats{$1} ? $formats{$1}->($self)
669 705 100       3281 : $formats{$2} ? $formats{$2}->($self) : $1)
    100          
    100          
    100          
670             /sgex;
671 184 100       4321 return $f unless wantarray;
672 15         23 push @r, $f;
673             }
674 4         19 return @r;
675             }
676              
677             sub epoch {
678 1     1 1 6 my $self = shift;
679 1         5 my $greg = DateTime->from_object(object => $self);
680 1         420 return $greg->epoch;
681             }
682              
683             sub DefaultLocale {
684 167     167 0 3795 'fr'
685             }
686              
687             #my %events = ();
688             sub on_date {
689 4     4 1 30 my ($dt, $lan) = @_;
690 4         3 my $locale;
691              
692 4 100       9 if (defined $lan)
693 2         7 { $locale = DateTime::Calendar::FrenchRevolutionary::Locale->load( $lan )}
694             else
695 2         3 { $locale = $dt->{locale} }
696 4         13 return $locale->on_date($dt);
697              
698             }
699              
700             # A module must return a true value. Traditionally, a module returns 1.
701             # But this module is a revolutionary one, so it discards all old traditions.
702             "Liberté, égalité, fraternité
703             ou la mort !";
704              
705             __END__
706              
707             =encoding utf8
708              
709             =head1 NAME
710              
711             DateTime::Calendar::FrenchRevolutionary - Dates in the French Revolutionary Calendar
712              
713             =head1 SYNOPSIS
714              
715             use DateTime::Calendar::FrenchRevolutionary;
716              
717             # Use the date "18 Brumaire VIII" (Brumaire being the second month)
718             $dt = DateTime::Calendar::FrenchRevolutionary->new( year => 8,
719             month => 2,
720             day => 18,
721             );
722              
723             # convert from French Revolutionary to Gregorian...
724             $dtgreg = DateTime->from_object( object => $dt );
725              
726             # ... and back again
727             $dtrev = DateTime::Calendar::FrenchRevolutionary->from_object( object => $dtgreg );
728              
729             =head1 DESCRIPTION
730              
731             DateTime::Calendar::FrenchRevolutionary implements the French
732             Revolutionary Calendar. This module implements most methods of
733             DateTime; see the DateTime(3) manpage for all methods.
734              
735             =head1 HISTORICAL NOTES
736              
737             =head2 Preliminary Note
738              
739             The documentation uses the word I<décade> (the first "e" having an
740             acute accent). This French word is I<not> the translation of the
741             English word "decade" (ten-year period). It means a ten-I<day>
742             period.
743              
744             For your information, the French word for a ten-year period is
745             I<décennie>.
746              
747             =head2 Description
748              
749             The Revolutionary calendar was in use in France from 24 November 1793
750             (4 Frimaire II) to 31 December 1805 (10 Nivôse XIV). An attempt to
751             apply the decimal rule (the basis of the metric system) to the
752             calendar. Therefore, the week disappeared, replaced by the décade. In
753             addition, all months have exactly 3 decades, no more, no less.
754              
755             At first, the year was beginning on the equinox of autumn, for two
756             reasons. First, the republic had been established on 22 September
757             1792, which happened to be the equinox, and second, the equinox was
758             the symbol of equality, the day and the night lasting exactly 12 hours
759             each. It was therefore in tune with the republic's motto "Liberty,
760             Equality, Fraternity". But it was not practical, so Romme proposed a
761             leap year rule similar to the Gregorian calendar rule.
762              
763             In his book I<The French Revolution>, the XIXth century writer Thomas
764             Carlyle proposes these translations for the month names:
765              
766             =over 4
767              
768             =item Vendémiaire -> Vintagearious
769              
770             =item Brumaire -> Fogarious
771              
772             =item Frimaire -> Frostarious
773              
774             =item Nivôse -> Snowous
775              
776             =item Pluviôse -> Rainous
777              
778             =item Ventôse -> Windous
779              
780             =item Germinal -> Buddal
781              
782             =item Floréal -> Floweral
783              
784             =item Prairial -> Meadowal
785              
786             =item Messidor -> Reapidor
787              
788             =item Thermidor -> Heatidor
789              
790             =item Fructidor -> Fruitidor
791              
792             =back
793              
794             Each month has a duration of 30 days. Since a year lasts 365.25 days
795             (or so), five additional days (or six on leap years) are added after
796             Fructidor. These days are called I<Sans-Culottides>. For programming
797             purposes, they are considered as a 13th month (much shorter than the
798             12 others).
799              
800             There was also an attempt to decimalize the day's subunits, with 1 day
801             = 10 hours, 1 hour = 100 minutes and 1 minute = 100 seconds. But this
802             reform was put on hold after two years or so and it never reappeared.
803              
804             Other reforms to decimalize the time has been proposed during the last
805             part of the XIXth Century, but these reforms were not applied too.
806             And they are irrelevant for this French Revolutionary calendar module.
807              
808             =head1 METHODS
809              
810             Since the week has been replaced by the décade, the corresponding
811             method names still are C<decade_number>, C<day_of_decade>, etc.
812             English speakers, please note that this has nothing to do with a
813             10-year period.
814              
815             The module supports both Anglo-Babylonian time (24x60x60) and decimal
816             time. The accessors for ABT are C<abt_hour>, C<abt_minute>,
817             C<abt_second> and C<abt_hms>, the accessors for decimal time are
818             C<hour>, C<minute>, C<second> and C<hms>. The C<strftime> and
819             C<iso8601> methods use only decimal time. The ABT accessors are
820             provided to be historically correct, since the decimal time reform was
821             never put in force. Yet, emphasis is on decimal time because it is
822             more fun than sexagesimal time, which anyhow can be obtained with the
823             standard Gregorian C<DateTime.pm> module.
824              
825             =head2 Constructors
826              
827             =over 4
828              
829             =item * new(...)
830              
831             Creates a new date object. This class accepts the following parameters:
832              
833             =over 4
834              
835             =item * C<year>
836              
837             Year number, mandatory. Year 1 corresponds to Gregorian years late
838             1792 and early 1793.
839              
840             =item * C<month>
841              
842             Month number, in the range 1..12, plus number 13 to designate the
843             end-of-year additional days.
844              
845             =item * C<day>
846              
847             Day number, in the range 1..30. In the case of additional days, the
848             range is 1..5 or 1..6 depending on the year (leap year or normal).
849              
850             =item * C<hour>, C<minute>, C<second>
851              
852             Decimal hour number, decimal minute number and decimal second number.
853             The hour is in the 0..9 range, both other parameters are in the 0..99
854             range. These parameters cannot be specified with the sexagesimal time
855             parameters C<abt_>I<xxx> (see below).
856              
857             =item * C<abt_hour>, C<abt_minute>, C<abt_second>
858              
859             Sexagesimal hour number, sexagesimal minute number and sexagesimal
860             second number. The hour is in the 0..23 range, both other parameters
861             are in the 0..59 range. These parameters cannot be specified with the
862             decimal time parameters (see above).
863              
864             =item * C<locale>
865              
866             Only the values C<fr> (French) and C<en> (English) are
867             allowed. Default is French. No other values are possible, even
868             territory variants such as C<fr_BE> or C<en_US>.
869              
870             =back
871              
872             =item * from_epoch( epoch => $epoch )
873              
874             Creates a date object from a timestamp value. This timestamp is the
875             number of seconds since the computer epoch, not the calendar epoch.
876              
877             =item * now( )
878              
879             Creates a date object that corresponds to the precise instant the
880             method is called.
881              
882             =item * from_object( object => $object, ... )
883              
884             Creates a date object by converting another object from the DateTime
885             suite. The preferred way for calendar to calendar conversion.
886              
887             =item * last_day_of_month( ... )
888              
889             Same as C<new>, except that the C<day> parameter is forbidden and is
890             automatically set to the end of the month. If the C<month> parameter
891             is 13 for the additional days, the day is set to the end of the year,
892             either the 5th or the 6th additional day.
893              
894             =item * clone
895              
896             Creates a replica of the original date object.
897              
898             =item * set( .. )
899              
900             This method can be used to change the local components of a date time,
901             or its locale. This method accepts any parameter allowed by the
902             C<new()> method.
903              
904             This method performs parameters validation just as is done in the
905             C<new()> method.
906              
907             =back
908              
909             =head2 Accessors
910              
911             =over 4
912              
913             =item * year
914              
915             Returns the year. C<%G> in C<strftime>.
916              
917             =item * month
918              
919             Returns the month in the 1..12 range. If the date is an additional day
920             at the end of the year, returns 13, which is not really a month
921             number. C<%f> in C<strftime>.
922              
923             =item * month_0
924              
925             Returns the month in the 0..11 range. If the date is an additional day
926             at the end of the year, returns 12, which is not really a month number.
927              
928             =item * month_name
929              
930             Returns the French name of the month or its English translation. No
931             other language is supported yet. For the additional days at the end
932             of the year, returns "jour complémentaire", the translation of
933             "additional day". C<%B> in C<strftime>.
934              
935             Note: The English translations for the month names come from Thomas
936             Carlyle's book.
937              
938             =item * month_abbr
939              
940             Returns a 3-letter abbreviation of the month name. For the additional
941             days at the end of the year, returns "S-C", because these additional
942             days were also known as the I<Sans-culottides>. C<%b> or C<%h> in
943             C<strftime>.
944              
945             =item * day_of_month, day, mday
946              
947             Returns the day of the month, from 1..30. C<%d> or C<%e> in C<strftime>.
948              
949             =item * day_of_decade, dod, day_of_week, dow, wday
950              
951             Returns the day of the decade, from 1..10. The C<dow>, C<wday> and
952             C<day_of_week> names are there for compatibility's sake with
953             C<DateTime>, even if the word "week" is improper.
954              
955             =item * day_name
956              
957             Returns the name of the current day of the I<décade>. C<%A> in
958             C<strftime>.
959              
960             =item * day_abbr
961              
962             Returns the abbreviated name of the current day of the
963             I<décade>. C<%a> in C<strftime>.
964              
965             =item * day_of_year, doy
966              
967             Returns the day of the year. C<%j> in C<strftime>.
968              
969             =item * feast, feast_short, feast_long, feast_caps
970              
971             Returns the plant, animal, mineral or tool associated with the day.
972             The default format is C<short>. If requested, you can ask for the
973             C<long> format, with a C<jour de...> prefix, or the C<caps> format,
974             with the first letter of the prefix and feast capitalized. Example:
975             for 11 Vendémiaire, we have:
976              
977             feast, feast_short pomme de terre
978             feast_long jour de la pomme de terre
979             feast_caps Jour de la Pomme de terre
980              
981             C<%Ej>, C<%EJ>, C<%Oj> or C<%*> in C<strftime>.
982              
983             Note: the English translation for the feasts comes mainly from Alan
984             Taylor's website "Preserving the French Republican Calendar".
985              
986             =item * ymd, dmy, mdy
987              
988             Returns the date in the corresponding composite format. An optional
989             parameter allows you to choose the separator between the date
990             elements. C<%F> in C<strftime>.
991              
992             =item * abt_hour, abt_minute, abt_min, abt_second, abt_sec
993              
994             Return the corresponding time elements, using a sexagesimal scale.
995             This is also known as the I<Anglo-Babylonian Time>.
996              
997             =item * hour, minute, min, second, sec
998              
999             Return the corresponding time elements, using a decimal scale, with 10
1000             hours per day, 100 minutes per hour and 100 seconds per minute. C<%H>,
1001             C<%M> and C<%S> in C<strftime>.
1002              
1003             =item * abt_hms
1004              
1005             Returns a composite string with the three time elements. Uses the
1006             I<Anglo-Babylonian Time>. An optional parameter allows you to choose
1007             the separator (C<:> by default).
1008              
1009             =item * hms
1010              
1011             Returns a composite string with the three time elements. Uses the
1012             decimal time. An optional parameter allows you to choose the
1013             separator (C<:> by default).
1014              
1015             =item * iso8601
1016              
1017             Returns the date and time is a format similar to what ISO-8601 has
1018             specified for the Gregorian calendar.
1019              
1020             =item * is_leap_year
1021              
1022             Returns a true value if the year is a leap year, false else.
1023              
1024             =item * decade_number, week_number
1025              
1026             Returns the I<décade> number. C<%U>, C<%V> or C<%W> in C<strftime>.
1027              
1028             =item * decade, week
1029              
1030             Returns a 2-element list, with the year number and the decade number.
1031             Since the I<décade> is always aligned with a month and then with a
1032             year, the year element is always the same as the date's year. Anyhow,
1033             this is done for compatibility with DateTime's C<week> method.
1034              
1035             =item * utc_rd_values
1036              
1037             Returns the current UTC Rata Die days, seconds and nanoseconds as a
1038             3-element list. This exists primarily to allow other calendar modules
1039             to create objects based on the values provided by this object.
1040              
1041             =item * jd, mjd
1042              
1043             These return the Julian Day and Modified Julian Day, respectively.
1044             The value returned is a floating point number. The fractional portion
1045             of the number represents the time portion of the datetime.
1046              
1047             =item * utc_rd_as_seconds
1048              
1049             Returns the current UTC Rata Die days and seconds purely as seconds.
1050             This is useful when you need a single number to represent a date.
1051              
1052             =item * local_rd_as_seconds
1053              
1054             Returns the current local Rata Die days and seconds purely as seconds.
1055              
1056             =item * strftime( $format, ... )
1057              
1058             This method implements functionality similar to the C<strftime()>
1059             method in C. However, if given multiple format strings, then it will
1060             return multiple elements, one for each format string.
1061              
1062             See the L<strftime Specifiers|/strftime Specifiers> section for a list
1063             of all possible format specifiers.
1064              
1065             =item * epoch
1066              
1067             Return the UTC epoch value for the datetime object. Internally, this
1068             is implemented C<epoch> from C<DateTime>, which in turn calls
1069             C<Time::Local>, which uses the Unix epoch even on machines with a
1070             different epoch (such as Mac OS). Datetimes before the start of the
1071             epoch will be returned as a negative number.
1072              
1073             Since epoch times cannot represent many dates on most platforms, this
1074             method may simply return undef in some cases.
1075              
1076             Using your system's epoch time may be error-prone, since epoch times
1077             have such a limited range on 32-bit machines. Additionally, the fact
1078             that different operating systems have different epoch beginnings is
1079             another source of bugs.
1080              
1081             =item * on_date
1082              
1083             Gives a few historical events that took place on the same date
1084             (day+month, irrespective of the year). These events occur during the
1085             period of use of the calendar, that is, no later than Gregorian year
1086             1805. The related events either were located in France, or were
1087             battles in which a French army was involved.
1088              
1089             This method accepts one optional argument, the language. For the
1090             moment, only "en" for English and "fr" for French are available. If
1091             not given, the method will use the date object's current locale.
1092              
1093             Not all eligible events are portrayed there. The events database will
1094             be expanded in future versions.
1095              
1096             Most military events are extracted from I<Calendrier Militaire>, a
1097             book written by an anonymous author in VII (1798) or so. I guess there
1098             is no longer any copyright attached. Please note that this is a
1099             propaganda book, which therefore gives a very biased view of the
1100             events.
1101              
1102             =back
1103              
1104             =head2 strftime Specifiers
1105              
1106             The following specifiers are allowed in the format string given to the
1107             C<strftime()> method:
1108              
1109             =over 4
1110              
1111             =item * %a
1112              
1113             The abbreviated day of decade name.
1114              
1115             =item * %A
1116              
1117             The full day of decade name.
1118              
1119             =item * %b
1120              
1121             The abbreviated month name, or 'S-C' for additional days (abbreviation
1122             of I<Sans-culottide>, another name for these days).
1123              
1124             =item * %B
1125              
1126             The full month name.
1127              
1128             =item * %c
1129              
1130             The date-time, using the default format, as defined by the current
1131             locale.
1132              
1133             =item * %C
1134              
1135             The century number (year/100) as a 2-digit integer.
1136              
1137             =item * %d
1138              
1139             The day of the month as a decimal number (range 01 to 30).
1140              
1141             =item * %D
1142              
1143             Equivalent to %m/%d/%y. This is not a good standard format if you
1144             have want both Americans and Europeans (and others) to understand the
1145             date!
1146              
1147             =item * %e
1148              
1149             Like %d, the day of the month as a decimal number, but a leading zero
1150             is replaced by a space.
1151              
1152             =item * %f
1153              
1154             The month as a decimal number (1 to 13). Unlike %m, a leading zero is
1155             replaced by a space.
1156              
1157             =item * %F
1158              
1159             Equivalent to %Y-%m-%d (the ISO 8601 date format)
1160              
1161             =item * %g
1162              
1163             Strictly similar to %y, since I<décades> are always aligned with the
1164             beginning of the year in this calendar.
1165              
1166             =item * %G
1167              
1168             Strictly similar to %Y, since I<décades> are always aligned with the
1169             beginning of the year in this calendar.
1170              
1171             =item * %h
1172              
1173             Equivalent to %b.
1174              
1175             =item * %H
1176              
1177             The hour as a decimal number using a 10-hour clock (range 0 to 9).
1178             The result is a single-char string.
1179              
1180             =item * %I
1181              
1182             The hour as a decimal number using the numbers on a clockface, that
1183             is, range 1 to 10. The result is a single-char string, except for 10.
1184              
1185             =item * %j
1186              
1187             The day of the year as a decimal number (range 001 to 366).
1188              
1189             =item * %Ej
1190              
1191             The feast for the day, in long format ("jour de la pomme de terre").
1192             Also available as %*.
1193              
1194             =item * %EJ
1195              
1196             The feast for the day, in capitalised long format ("Jour de la Pomme
1197             de terre").
1198              
1199             =item * %Oj
1200              
1201             The feast for the day, in short format ("pomme de terre").
1202              
1203             =item * %k
1204              
1205             The hour (10-hour clock) as a decimal number (range 0 to 9); the
1206             result is a 2-char string, the digit is preceded by a blank. (See also
1207             %H.)
1208              
1209             =item * %l
1210              
1211             The hour as read from a clockface (range 1 to 10). The result is a
1212             2-char string, the digit is preceded by a blank, except of course for
1213             10. (See also %I.)
1214              
1215             =item * %L
1216              
1217             The year as a decimal number including the century. Strictly similar
1218             to %Y and %G.
1219              
1220             =item * %m
1221              
1222             The month as a decimal number (range 01 to 13).
1223              
1224             =item * %M
1225              
1226             The minute as a decimal number (range 00 to 99).
1227              
1228             =item * %n
1229              
1230             A newline character.
1231              
1232             =item * %p
1233              
1234             Either `AM' or `PM' according to the given time value, or the
1235             corresponding strings for the current locale. Noon is treated as `pm'
1236             and midnight as `am'.
1237              
1238             =item * %P
1239              
1240             Like %p but in lowercase: `am' or `pm' or a corresponding string for
1241             the current locale.
1242              
1243             =item * %r
1244              
1245             The decimal time in a.m. or p.m. notation. In the POSIX locale this
1246             is equivalent to `%I:%M:%S %p'.
1247              
1248             =item * %R
1249              
1250             The decimal time in 10-hour notation (%H:%M). (SU) For a version
1251             including the seconds, see %T below.
1252              
1253             =item * %s
1254              
1255             The number of seconds since the epoch.
1256              
1257             =item * %S
1258              
1259             The second as a decimal number (range 00 to 99).
1260              
1261             =item * %t
1262              
1263             A tab character.
1264              
1265             =item * %T
1266              
1267             The decimal time in 10-hour notation (%H:%M:%S).
1268              
1269             =item * %u
1270              
1271             The day of the I<décade> as a decimal, range 1 to 10, Primidi being 1
1272             and Décadi being 10. See also %w.
1273              
1274             =item * %U
1275              
1276             The I<décade> number of the current year as a decimal number, range 01
1277             to 37.
1278              
1279             =item * %V
1280              
1281             The decade number (French Revolutionary equivalent to the ISO
1282             8601:1988 week number) of the current year as a decimal number, range
1283             01 to 37. Identical to %U, since décades are aligned with the
1284             beginning of the year.
1285              
1286             =item * %w
1287              
1288             The day of the I<décade> as a decimal, range 0 to 9, Décadi being 0.
1289             See also %u.
1290              
1291             =item * %W
1292              
1293             The I<décade> number of the current year as a decimal number, range 00
1294             to 37. Strictly similar to %U and %V.
1295              
1296             =item * %y
1297              
1298             The year as a decimal number without a century (range 00 to 99).
1299              
1300             =item * %Y
1301              
1302             The year as a decimal number including the century.
1303              
1304             =item * %Ey
1305              
1306             The year as a lowercase Roman number.
1307              
1308             =item * %EY
1309              
1310             The year as a uppercase Roman number, which is the traditional way to
1311             write years when using the French Revolutionary calendar.
1312              
1313             =item * %z
1314              
1315             The time-zone as hour offset from UTC. Required to emit
1316             RFC822-conformant dates (using "%a, %d %b %Y %H:%M:%S %z"). Since the
1317             module does not support time zones, this gives silly results and you
1318             cannot be RFC822-conformant. Anyway, RFC822 requires the Gregorian
1319             calendar, doesn't it?
1320              
1321             =item * %Z
1322              
1323             The time zone or name or abbreviation, should the module have
1324             supported them.
1325              
1326             =item * %*
1327              
1328             The feast for the day, in long format ("jour de la pomme de terre").
1329             Also available as %Ej.
1330              
1331             =item * %%
1332              
1333             A literal `%' character.
1334              
1335             =back
1336              
1337             =head1 REMARKS
1338              
1339             =head2 Time Zones
1340              
1341             Only the I<floating> time zone is supported. Time zones were created
1342             in the late XIXth century, at a time when fast communication
1343             (railroads) and instant communication (electric telegraph) made it
1344             necessary. But at this time, the French Revolutionary calendar was no
1345             longer in use.
1346              
1347             =head2 Leap Seconds
1348              
1349             They are not supported.
1350              
1351             =head2 I18N
1352              
1353             For the moment, only French and English are available. For the English
1354             translation, I have used Thomas Carlyle's book and Alan Taylor's web
1355             site at kokogiak.com (see below). Then, I have checked some
1356             translations with Wikipedia and Jonathan Badger's French Revolutionary
1357             Calendar module written in Ruby.
1358              
1359             Some feast names are not translated, other's translations are doubtful
1360             (they are flagged with a question mark). Remarks are welcome.
1361              
1362             =head1 SUPPORT
1363              
1364             Support for this module is provided via the datetime@perl.org email
1365             list. See L<http://lists.perl.org/> for more details.
1366              
1367             Please enter bug reports at L<http://rt.cpan.org/>
1368              
1369             =head1 AUTHOR
1370              
1371             Jean Forget <JFORGET@cpan.org>
1372              
1373             based on Dave Rolsky's DateTime module, Eugene van der Pijll's
1374             DateTime::Calendar::Pataphysical module and my prior
1375             Date::Convert::French_Rev module.
1376              
1377             The development of this module is hosted by I<Les Mongueurs de Perl>,
1378             L<http://www.mongueurs.net/>.
1379              
1380             =head1 SEE ALSO
1381              
1382             =head2 Software
1383              
1384             date(1), strftime(3), perl(1), DateTime(3), DateTime::Calendar::Pataphysical(3), Date::Convert::French_Rev
1385              
1386             calendar/cal-french.el in emacs-21.2 or later or xemacs 21.1.8
1387              
1388             =head2 Books
1389              
1390             Quid 2001, M and D Frémy, publ. Robert Laffont
1391              
1392             Agenda Républicain 197 (1988/89), publ. Syros Alternatives
1393              
1394             Any French schoolbook about the French Revolution
1395              
1396             The French Revolution, Thomas Carlyle, Oxford University Press
1397              
1398             Calendrier Militaire, anonymous
1399              
1400             Histoire de l'heure en France, Jacques Gapaillard, publ. Vuibert -- ADAPT
1401              
1402             =head2 Internet
1403              
1404             L<http://datetime.perl.org/>
1405              
1406             L<http://www.faqs.org/faqs/calendars/faq/part3/>
1407              
1408             L<http://zapatopi.net/metrictime.html>
1409              
1410             L<http://datetime.mongueurs.net/>
1411              
1412             L<http://www.kokogiak.com/frc/default.asp> (the link still exists, but
1413             it seems to no longer include stuff about the French Revolutionary
1414             calendar.)
1415              
1416             L<https://github.com/jhbadger/FrenchRevCal-ruby>
1417              
1418             L<http://en.wikipedia.org/wiki/French_Republican_Calendar>
1419              
1420             =head1 LICENSE STUFF
1421              
1422             Copyright (c) 2003, 2004, 2010, 2012, 2014, 2016 Jean Forget. All
1423             rights reserved. This program is free software. You can distribute,
1424             modify, and otherwise mangle DateTime::Calendar::FrenchRevolutionary
1425             under the same terms as perl 5.16.3.
1426              
1427             This program is distributed under the same terms as Perl 5.16.3: GNU
1428             Public License version 1 or later and Perl Artistic License
1429              
1430             You can find the text of the licenses in the F<LICENSE> file or at
1431             L<http://www.perlfoundation.org/artistic_license_1_0> and
1432             L<http://www.gnu.org/licenses/gpl-1.0.html>.
1433              
1434             Here is the summary of GPL:
1435              
1436             This program is free software; you can redistribute it and/or modify
1437             it under the terms of the GNU General Public License as published by
1438             the Free Software Foundation; either version 1, or (at your option)
1439             any later version.
1440              
1441             This program is distributed in the hope that it will be useful, but
1442             WITHOUT ANY WARRANTY; without even the implied warranty of
1443             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1444             General Public License for more details.
1445              
1446             You should have received a copy of the GNU General Public License
1447             along with this program; if not, see <http://www.gnu.org/licenses/> or
1448             write to the Free Software Foundation, Inc., L<http://fsf.org>.
1449              
1450             =cut