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