1package DateTime::Calendar::Christian;
2
3use 5.008004;
4
5use strict;
6use warnings;
7
8our $VERSION = '0.12';
9
10use DateTime 0.1402;
11use DateTime::Calendar::Julian 0.04;
12
13use Carp ();
14
15use overload ( 'fallback' => 1,
16               '<=>' => '_compare_overload',
17               'cmp' => '_compare_overload',
18               '-' => '_subtract_overload',
19               '+' => '_add_overload',
20             );
21
22use constant ARRAY_REF	=> ref [];
23
24{
25    my %reform_dates = (
26	italy      => [ 1582, 10, 15 ], # including some other catholic
27					# countries (spain, portugal, ...)
28	france     => [ 1582, 12, 20 ],
29	belgium    => [ 1583,  1,  1 ],
30	holland    => [ 1583,  1,  1 ], # or 1583-1-12?
31	liege      => [ 1583,  2, 21 ],
32	augsburg   => [ 1583,  2, 24 ],
33	treves     => [ 1583, 10, 15 ],
34	bavaria    => [ 1583, 10, 16 ],
35	tyrolia    => [ 1583, 10, 16 ],
36	julich     => [ 1583, 11, 13 ],
37	cologne    => [ 1583, 11, 14 ], # or 1583-11-13?
38	wurzburg   => [ 1583, 11, 15 ],
39	mainz      => [ 1583, 11, 22 ],
40	strasbourg_diocese => [ 1583, 11, 27 ],
41	baden      => [ 1583, 11, 27 ],
42	carynthia  => [ 1583, 12, 25 ],
43	bohemia    => [ 1584,  1, 17 ],
44	lucerne    => [ 1584,  1, 22 ],
45	silesia    => [ 1584,  1, 23 ],
46	westphalia => [ 1584,  7, 12 ],
47	paderborn  => [ 1585,  6, 27 ],
48	hungary    => [ 1587, 11,  1 ],
49	transylvania => [ 1590, 12, 25 ],
50	prussia    => [ 1610,  9,  2 ],
51	hildesheim => [ 1631,  3, 26 ],
52	minden     => [ 1668,  2, 12 ],
53	strasbourg => [ 1682,  2, 16 ],
54	denmark    => [ 1700,  3,  1 ],
55	germany_protestant => [ 1700,  3,  1 ],
56	gelderland => [ 1700,  7, 12 ],
57	faeror     => [ 1700, 11, 28 ], # or 1700-11-27?
58	iceland    => [ 1700, 11, 28 ],
59	utrecht    => [ 1700, 12, 12 ],
60	zurich     => [ 1701,  1, 12 ],
61	friesland  => [ 1701,  1, 12 ], # or 1701-01-13?
62	drente     => [ 1701,  5, 12 ], # or 1701-01-12?
63	uk         => [ 1752,  9, 14 ],
64	bulgaria   => [ 1915, 11, 14 ], # or 1916-04-14?
65	russia     => [ 1918,  2, 14 ],
66	latvia     => [ 1918,  2, 15 ],
67	romania    => [ 1919,  4, 14 ], # or 1924-10-14?
68    );
69
70    # Dates are from http://www.polysyllabic.com/GregConv.html and
71    # http://privatewww.essex.ac.uk/~kent/calisto/guide/changes.htm
72    # Only those dates that both sites agree on are included at the moment.
73
74    # ALL interpretation of the reform_date argument MUST go through here.
75    sub _process_reform_date {
76	my ( $class, $rd ) = @_;
77	if ( my $ref = ref $rd ) {
78	    if ( ARRAY_REF eq $ref ) {
79		return DateTime->new(
80		    year	=> $rd->[0],
81		    month	=> $rd->[1] || 1,
82		    day	=> $rd->[2] || 1,
83		    hour	=> $rd->[3] || 0,
84		    minute	=> $rd->[4] || 0,
85		    second	=> $rd->[5] || 0,
86		    nanosecond	=> $rd->[6] || 0,
87		);
88	    } else {
89		return DateTime->from_object( object => $rd );
90	    }
91	} elsif ( $rd ) {
92	    if ( my $rda = $reform_dates{ my $rd_lc = lc $rd } ) {
93		ARRAY_REF eq ref $rda
94		    and return ( $reform_dates{$rd_lc} =
95		    $class->_process_reform_date( $rda ) );
96		return $rda;
97	    }
98	    if ( $rd =~ m/ \A [0-9] /smx
99		    and my @rda = split qr{ [^0-9]+ }smx, $rd ) {
100		return $class->_process_reform_date( \@rda );
101	    }
102	    Carp::croak( "Unknown calendar region '$rd'" );
103	} elsif ( ref $class && ( ref $class )->can( 'reform_date' ) ) {
104	    return $class->reform_date();
105	} else {
106	    return $class->DefaultReformDate();
107	}
108    }
109}
110
111__PACKAGE__->DefaultReformDate( 'Italy' );
112
113sub new {
114    my ( $class, %args ) = @_;
115
116    my $self = $class->_new( \%args );
117
118    if (defined $args{year}) {
119        $self->{date} = DateTime::Calendar::Julian->new(%args);
120        if ($self->{date} >= $self->{reform_date}) {
121            $self->{date} = DateTime->new(%args);
122            $self->_adjust_calendar;
123        }
124    }
125
126    return $self;
127}
128
129sub _new {
130    my ( $class, $arg, $method ) = @_;
131
132    my $self = bless {
133	reform_date	=> $class->_process_reform_date(
134	    delete $arg->{reform_date} ),
135    }, ref $class || $class;
136
137    if ( $method ) {
138	$self->{date} = DateTime->$method( %{ $arg } );
139	$self->_adjust_calendar();
140    }
141
142    return $self;
143}
144
145sub _adjust_calendar {
146    my $self = shift;
147
148    if ($self->is_gregorian and $self->{date} < $self->{reform_date}) {
149        $self->{date} = DateTime::Calendar::Julian->from_object(
150                                                object => $self->{date} );
151    } elsif ($self->is_julian and $self->{date} >= $self->{reform_date}) {
152        $self->{date} = DateTime->from_object( object => $self->{date} );
153    }
154
155    return;
156}
157
158sub is_julian {
159    return $_[0]{date}->isa('DateTime::Calendar::Julian');
160}
161
162sub is_gregorian {
163    return ! $_[0]->is_julian;
164}
165
166sub calendar_name {
167    my ( $self ) = @_;
168    return $self->is_julian() ? 'Julian' : 'Gregorian';
169}
170
171sub from_epoch {
172    my ( $class, %args ) = @_;
173
174    return $class->_new( \%args, 'from_epoch' );
175}
176
177sub now { return shift->from_epoch( epoch => (scalar time), @_ ) }
178
179sub today { return shift->now(@_)->truncate( to => 'day' ) }
180
181sub from_object {
182    my ( $class, %args ) = @_;
183
184    return $class->_new( \%args, 'from_object' );
185}
186
187sub from_day_of_year {
188    my ( $class, %args ) = @_;
189
190    my $self = $class->_new( \%args );
191
192    my $rd = $self->reform_date();
193    my $ry = $rd->year;
194
195    if ( $args{year} > $ry ) {
196	$self->{date} = DateTime->from_day_of_year( %args );
197    } elsif ( $args{year} < $ry ) {
198	$self->{date} = DateTime::Calendar::Julian->from_day_of_year(
199	    %args );
200    } else {
201	my $dev = DateTime::Calendar::Christian->gregorian_deviation( $rd );
202	my $rdoy = $rd->day_of_year - $dev;
203	if ( $args{day_of_year} < $rdoy ) {
204	    $self->{date} = DateTime::Calendar::Julian->from_day_of_year(
205		%args );
206	} else {
207	    $args{day_of_year} += $dev;
208	    $self->{date} = DateTime->from_day_of_year( %args );
209	}
210    }
211
212    return $self;
213}
214
215# This method assumes that both current month and next month exists.
216# There can be problems when the number of missing days is larger than
217# 27.
218sub last_day_of_month {
219    my ($class, %p) = @_;
220    # First, determine the first day of the next month.
221    $p{day} = 1;
222    $p{month}++;
223    if ($p{month} > 12) {
224        $p{month} -= 12;
225        $p{year}++;
226    }
227    my $self = $class->new( %p );
228
229    if ($self->month != $p{month}) {
230        # Apparently, month N+1 does not have a day 1.
231        # This means that this date is removed in the calendar reform,
232        # and the last day of month N is the last day before the reform.
233
234        $self = $self->from_object( object => $self->{reform_date} );
235    }
236
237    # Subtract one. That should be the last day of the month.
238    $self->subtract( days => 1 );
239
240    return $self;
241}
242
243sub clone {
244    my $self = shift;
245
246    my $new = {};
247    $new->{reform_date} = $self->{reform_date}->clone;
248    $new->{date} = $self->{date}->clone if exists $self->{date};
249    return bless $new, ref $self;
250}
251
252sub is_leap_year {
253    my $self = shift;
254
255    my $year = $self->year;
256    # This could go wrong if the number of missing days is more than
257    # about 300, and reform_date lies at the beginning of the next year.
258    if ($year != $self->{reform_date}->year) {
259        return $self->{date}->is_leap_year;
260    }
261
262    # Difficult case: $year is in the year of the calendar reform
263    # Test if Feb 29 exists
264    my $d = eval { $self->new( year  => $year,
265                               month => 2,
266                               day   => 29,
267                             ) };
268    return defined($d) && $d->month == 2 && $d->day == 29;
269}
270
271sub _add_overload {
272    my ($dt, $dur, $reversed) = @_;
273
274    if ($reversed) {
275        ($dur, $dt) = ($dt, $dur);
276    }
277
278    my $new = $dt->clone;
279    $new->add_duration($dur);
280    return $new;
281}
282
283sub _subtract_overload {
284    my ($date1, $date2, $reversed) = @_;
285
286    if ($reversed) {
287        ($date2, $date1) = ($date1, $date2);
288    }
289
290    if (UNIVERSAL::isa($date2, 'DateTime::Duration')) {
291        my $new = $date1->clone;
292        $new->add_duration( $date2->inverse );
293        return $new;
294    } else {
295        my $date3 = DateTime->from_object( object => $date2 );
296        return $date1->{date}->subtract_datetime($date3);
297    }
298}
299
300sub add { return shift->add_duration( DateTime::Duration->new(@_) ) }
301
302sub subtract { return shift->subtract_duration( DateTime::Duration->new(@_) ) }
303
304sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) }
305
306sub subtract_datetime {
307    my $self = shift;
308    my $dt = shift;
309
310    return $self->{date} - $dt->{date};
311}
312
313sub add_duration {
314    my ($self, $dur) = @_;
315
316    my $start_jul = $self->is_julian;
317
318    # According to the papal bull and the English royal decree that
319    # introduced the Gregorian calendar, dates should be calculated as
320    # if the change did not happen; this makes date math very easy in
321    # most cases...
322    $self->{date}->add_duration($dur);
323    $self->_adjust_calendar;
324
325    my $dd;
326    if ($start_jul and $self->is_gregorian) {
327
328        # The period after reform_date has been calculated in Julian
329        # instead of in Gregorian; this may have introduced extra leap
330        # days; the date should be set back.
331        $dd = $self->gregorian_deviation($self->{date}) -
332              $self->gregorian_deviation($self->{reform_date});
333    } elsif (not $start_jul and $self->is_julian) {
334
335        # The period before reform_date has been calculated in Gregorian
336        # instead of in Julian; we may have to introduce extra leap
337        # days; the date should be set back
338        $dd = $self->gregorian_deviation($self->{reform_date}) -
339              $self->gregorian_deviation($self->{date});
340    }
341
342    $self->{date}->subtract( days => $dd ) if $dd;
343
344    return $self;
345}
346
347sub gregorian_deviation {
348    my ($class, $date) = @_;
349
350    $date ||= $class;
351
352    $date = DateTime::Calendar::Julian->from_object( object => $date );
353    return $date->gregorian_deviation;
354}
355
356sub reform_date { return $_[0]->{reform_date} }
357
358# Almost the same as DateTime::week
359sub week
360{
361    my $self = shift;
362
363    unless ( defined $self->{date}{local_c}{week_year} )
364    {
365        my $doy = $self->day_of_year;
366        my $dow = $self->day_of_week;
367
368        # Convert to closest Thursday:
369        $doy += 4-$dow;
370
371        $self->{date}{local_c}{week_number} =
372                int(($doy + 6) / 7);
373
374        if ( $self->{date}{local_c}{week_number} == 0 )
375        {
376            $self->{date}{local_c}{week_year} = $self->year - 1;
377            $self->{date}{local_c}{week_number} =
378                $self->_weeks_in_year( $self->{date}{local_c}{week_year} );
379        }
380        elsif ( $self->{date}{local_c}{week_number} >
381                $self->_weeks_in_year( $self->year ) )
382        {
383            $self->{date}{local_c}{week_number} = 1;
384            $self->{date}{local_c}{week_year} = $self->year + 1;
385        }
386        else
387        {
388            $self->{date}{local_c}{week_year} = $self->year;
389        }
390    }
391
392    return @{ $self->{date}{local_c} }{ 'week_year', 'week_number' }
393}
394
395# This routine assumes that the month December actually exists.
396# There can be problems if the number of missing days is larger than 30.
397sub _weeks_in_year
398{
399    my $self = shift;
400    my $year = shift;
401
402    my $dec_31 = $self->last_day_of_month( year => $year, month => 12 );
403
404    my $days_in_yr = $dec_31->day_of_year;
405    my $dow = $dec_31->day_of_week;
406
407    return int(($days_in_yr +
408                ($dow >= 4 ? 7 - $dow : - $dow)) / 7
409                + 0.5);
410}
411
412sub set {
413    my ( $self, %p ) = @_;
414
415    Carp::croak( 'Cannot change reform_date with set()' )
416        if exists $p{reform_date};
417    Carp::carp( 'You passed a locale to the set() method.',
418	' You should use set_locale() instead, as using set() may ',
419	'alter the local time near a DST boundary.' )
420	if $p{locale};
421
422    my %old_p =
423        ( reform_date => $self->{reform_date},
424          map { $_ => $self->$_() }
425            qw( year month day hour minute second nanosecond
426                locale time_zone )
427        );
428
429    my $new_dt = (ref $self)->new( %old_p, %p );
430
431    %$self = %$new_dt;
432
433    return $self;
434}
435
436sub set_time_zone {
437    my ( $self, @arg ) = @_;
438    $self->{date}->set_time_zone( @arg );
439    $self->_adjust_calendar;
440    return $self;
441}
442
443# This code assumes there is a month of December of the previous year.
444sub day_of_year {
445    my $self = shift;
446
447    my $doy = $self->{date}->doy;
448    if ($self->year == $self->reform_date->year &&
449        $self >= $self->reform_date ) {
450        $doy -= $self->gregorian_deviation;
451        my $end_of_year = $self->last_day_of_month( year  => $self->year - 1,
452                                                    month => 12 );
453        $doy = ($self->utc_rd_values)[0] - ($end_of_year->utc_rd_values)[0];
454    }
455    return $doy;
456}
457
458sub day_of_year_0 {
459    return shift->day_of_year - 1;
460}
461
462sub strftime {
463    my ( $self, @fmts ) = @_;
464    foreach ( @fmts ) {
465	s/ %\{ ( calendar_name ) \} / $self->_strftime_helper( "$1" ) /smxge;
466    }
467    return $self->{date}->strftime( @fmts );
468}
469
470sub _strftime_helper {
471    my ( $self, $method ) = @_;
472    my $rslt = $self->$method();
473    $rslt =~ s/ % /%%/smxg;
474    return $rslt;
475}
476
477sub STORABLE_freeze {
478    my ( $self ) = @_;
479    return (
480	$self->reform_date,
481	$self->{date} ? $self->{date} : (),
482    );
483}
484
485sub STORABLE_thaw {
486    my ( $self, undef, $reform, $date ) = @_;
487    $self->{reform_date} = $reform;
488    defined $date
489	and $self->{date} = $date;
490    return $self;
491}
492
493
494# Delegate to $self->{date}
495for my $sub (
496		# The following by Eugene van der Pijll
497		qw/year ce_year month month_0 month_name month_abbr
498                day_of_month day_of_month_0 day_of_week day_of_week_0
499                day_name day_abbr ymd mdy dmy hour minute second hms
500                nanosecond millisecond microsecond
501                iso8601 datetime week_year week_number
502                time_zone offset is_dst time_zone_short_name locale
503                utc_rd_values utc_rd_as_seconds local_rd_as_seconds jd
504                mjd epoch utc_year compare /,
505		# these should be replaced with a corrected version -- EvdP
506		qw/truncate/,
507		# The following by Thomas R. Wyant, III
508		qw/
509		am_or_pm compare_ignore_floating
510		christian_era secular_era era era_abbr era_name
511		delta_days delta_md delta_ms duration_class format_cldr
512		formatter fractional_second hires_epoch
513		hour_1 hour_12 hour_12_0 is_finite is_infinite
514		leap_seconds local_day_of_week local_rd_values
515		quarter quarter_0 quarter_name quarter_abbr
516		set_locale set_formatter subtract_datetime_absolute
517		time_zone_long_name
518		year_with_christian_era year_with_era
519		year_with_secular_era
520		/,
521		# Because Eugene accepted week_number and week_year even
522		# though they might span the reform date, I will accept
523		# the following -- TRW
524		qw/
525		week_of_month
526		weekday_of_month
527		/,
528) {
529    no strict 'refs';
530    *$sub = sub {
531                my $self = shift;
532		Carp::croak( "Empty date object in call to $sub" )
533                    unless exists $self->{date};
534                $self->{date}->$sub(@_)
535            };
536}
537
538sub _compare_overload {
539    my ( $self, $other ) = @_;
540    $self->{date}
541	or return -1;
542    return $self->{date}->_compare_overload( $other );
543}
544
545# Delegate to set();
546
547for my $name ( qw/ year month day hour minute second nanosecond / ) {
548    my $sub = "set_$name";
549    no strict 'refs';
550    *$sub = sub {
551	my ( $self, $value ) = @_;
552	return $self->set( $name => $value );
553    };
554}
555
556{
557    no warnings 'once';
558
559    *mon = \&month;
560    *mon_0 = \&month_0;
561    *day  = \&day_of_month;
562    *mday = \&day_of_month;
563    *day_0  = \&day_of_month_0;
564    *mday_0 = \&day_of_month_0;
565    *wday = \&day_of_week;
566    *dow  = \&day_of_week;
567    *wday_0 = \&day_of_week_0;
568    *dow_0  = \&day_of_week_0;
569    *doq    = \&day_of_quarter;
570    *doq_0  = \&day_of_quarter_0;
571    *doy = \&day_of_year;
572    *doy_0 = \&day_of_year_0;
573    *date = \&ymd;
574    *min = \&minute;
575    *sec = \&second;
576    *DateTime::Calendar::Christian::time = \&hms;
577}
578
579sub DefaultLocale {
580    shift;
581    return DateTime->DefaultLocale( @_ );
582}
583
584{
585    my $DefaultReformDate;
586
587    sub DefaultReformDate {
588	my ( $class, $rd ) = @_;
589	$rd
590	    and $DefaultReformDate = $class->_process_reform_date( $rd );
591	return $DefaultReformDate;
592    }
593}
594
5951;
596__END__
597
598=head1 NAME
599
600DateTime::Calendar::Christian - Dates in the Christian calendar
601
602=head1 SYNOPSIS
603
604  use DateTime::Calendar::Christian;
605
606  $dt = DateTime::Calendar::Christian->new( year  => 1752,
607                                            month => 10,
608                                            day   => 4,
609                                            reform_date => $datetime );
610
611=head1 DESCRIPTION
612
613DateTime::Calendar::Christian is the implementation of the combined
614Julian and Gregorian calendar.
615
616See L<DateTime> for information about most of the methods.
617
618=head1 BACKGROUND
619
620The Julian calendar, introduced in Roman times, had an average year
621length of 365.25 days, about 0.03 days more than the correct number. When
622this difference had accumulated to about ten days, the calendar was
623reformed by pope Gregory XIII, who introduced a new leap year rule. To
624correct for the error that had built up over the centuries, ten days
625were skipped in October 1582. In most countries, the change date was
626later than that; England went Gregorian in 1752, and Russia didn't
627change over until 1918.
628
629=head1 METHODS
630
631This manpage only describes those methods that differ from those of
632DateTime. See L<DateTime|DateTime> for all other methods. A spirited
633attempt has been made to implement the B<entire> L<DateTime|DateTime>
634interface.
635
636Methods not documented below may behave in unexpected ways when they
637involve dates both before and after the reform date. For example,
638C<week_number()>, when called on a date in the reform year but after the
639reform, returns the week number in the Gregorian year, not the actual
640year.
641
642B<Caveat programmer.>
643
644=over
645
646=item * new( ... )
647
648Besides the usual parameters ("year", "month", "day", "hour", "minute",
649"second", "nanosecond", "locale", "formatter" and "time_zone"),
650this class method takes the additional "reform_date" parameter. See
651L<SPECIFYING REFORM DATE|/SPECIFYING REFORM DATE> below for how to
652specify this.
653
654If this method is used as an instance method and no "reform_date" is
655given, the "reform_date" of the returned object is the same as the one
656of the object used to call this constructor. This means you can make
657"date generators", that implement a calendar with a fixed reform date:
658
659  $english_calendar = DateTime::Calendar::Christian(
660                          reform_date => DateTime->new( year  => 1752,
661                                                        month => 9,
662                                                        day   => 14 )
663                                                   );
664
665or equivalently:
666
667  $english_calendar = DateTime::Calendar::Christian(
668                          reform_date => 'UK' );
669
670You can use this generator to create dates with the given reform_date:
671
672  $born = $english_calendar->new( year => 1732, month => 2, day => 22 );
673  $died = $english_calendar->new( year => 1799, month => 12, day => 14 );
674
675When a date is given that was skipped during a calendar reform, it is
676assumed that it is a Gregorian date, which is then converted to the
677corresponding Julian date. This behaviour may change in future
678versions. If a date is given that can be both Julian and Gregorian, it
679will be considered Julian. This is a bug.
680
681=item * from_epoch, from_object, from_day_of_year, last_day_of_month
682
683These methods accept an additional "reform_date" argument. Note that the
684epoch is defined for most (all?) systems as a date in the Gregorian
685calendar.
686
687=item * reform_date
688
689Returns the date of the calendar reform, as a DateTime object.
690
691=item * is_julian, is_gregorian
692
693Return true or false indicating whether the datetime object is in a
694specific calendar.
695
696=item * calendar_name
697
698Return C<'Julian'> or C<'Gregorian'>, depending on the value returned by
699C<is_julian()>.
700
701=item * is_leap_year
702
703This method returns a true or false indicating whether or not the
704datetime object is in a leap year. If the object is in the year of the
705date reform, this method indicates whether there is a leap day in that
706year, irrespective of whether the datetime object is in the same
707calendar as the possible leap day.
708
709=item * days_in_year
710
711Returns the number of days in the year. Is equal to 365 or 366, except
712for the year(s) of the calendar reform.
713
714=item * day_of_year, day_of_year_0
715
716Returns the day of the year, either one-based or zero-based depending on
717the actual method called. In the reform year this is the actual number
718of days from January 1 (Julian) to the current date, whether Julian or
719Gregorian.
720
721=item * add_datetime, subtract_datetime
722
723These are done in terms of duration, so that, for example, subtracting a
724day from the reform date (Gregorian) gets you the day before the reform
725date (Julian).
726
727=item * strftime
728
729This override allows selected methods of this class (i.e. not inherited
730from DateTime) to be used in the C<'%{method_name}'> construction in
731templates. The only method allowed at the moment is C<calendar_name>.
732
733=item * gregorian_deviation( [$datetime] )
734
735This method returns the difference in days between the Gregorian and the
736Julian calendar. If the parameter $datetime is given, it will be used to
737calculate the result; in this case this method can be used as a class
738method.
739
740=item * DefaultReformDate
741
742This static method returns a L<DateTime|DateTime> object representing
743the default reform date. If called with an argument, the argument
744becomes the new reform date, which is returned. The argument is either a
745L<DateTime|DateTime> object (or something that can be converted into
746one) or a reform date location name. See
747L<SPECIFYING REFORM DATE|/SPECIFYING REFORM DATE> below for what kind of
748arguments can be specified.
749
750=back
751
752=head1 INTERFACES
753
754This module implements the following interfaces:
755
756=over
757
758=item * Storable
759
760This module implements the Storable interface. All the donkey work is
761done by L<DateTIme|DateTime>.
762
763=item * Overloading
764
765Addition, subtraction, and both string and numeric comparison are
766overloaded. Objects with no date (that is, objects initialized as "date
767generators") collate before objects with a date.
768
769=back
770
771=head1 SPECIFYING REFORM DATE
772
773The reform date represents the first date the Gregorian calendar came
774into use. It can be specified a number of different ways:
775
776=over
777
778=item * A DateTime object, or an object that can be converted into one.
779
780=item * A location name (case-insensitive) from the following list:
781
782 Italy -------------- 1582-10-15 # and some other Catholic countries
783 France ------------- 1582-12-20
784 Belgium ------------ 1583-1-1
785 Holland ------------ 1583-1-1   # or 1583-1-12?
786 Liege -------------- 1583-2-21
787 Augsburg ----------- 1583-2-24
788 Treves ------------- 1583-10-15
789 Bavaria ------------ 1583-10-16
790 Tyrolia ------------ 1583-10-16
791 Julich ------------- 1583-11-13
792 Cologne ------------ 1583-11-14 # or 1583-11-13?
793 Wurzburg ----------- 1583-11-15
794 Mainz -------------- 1583-11-22
795 Strasbourg_Diocese - 1583-11-27
796 Baden -------------- 1583-11-27
797 Carynthia ---------- 1583-12-25
798 Bohemia ------------ 1584-1-17
799 Lucerne ------------ 1584-1-22
800 Silesia ------------ 1584-1-23
801 Westphalia --------- 1584-7-12
802 Paderborn ---------- 1585-6-27
803 Hungary ------------ 1587-11-1
804 Transylvania ------- 1590-12-25
805 Prussia ------------ 1610-9-2
806 Hildesheim --------- 1631-3-26
807 Minden ------------- 1668-2-12
808 Strasbourg --------- 1682-2-16
809 Denmark ------------ 1700-3-1
810 Germany_Protestant - 1700-3-1
811 Gelderland --------- 1700-7-12
812 Faeror ------------- 1700-11-28 # or 1700-11-27?
813 Iceland ------------ 1700-11-28
814 Utrecht ------------ 1700-12-12
815 Zurich ------------- 1701-1-12
816 Friesland ---------- 1701-1-12  # or 1701-01-13?
817 Drente ------------- 1701-5-12  # or 1701-01-12?
818 UK ----------------- 1752-9-14
819 Bulgaria ----------- 1915-11-14 # or 1916-04-14?
820 Russia ------------- 1918-2-14
821 Latvia ------------- 1918-2-15
822 Romania ------------ 1919-4-14  # or 1924-10-14?
823
824=item * An array reference.
825
826The first seven elements of the array are year, month, day, hour,
827minute, second and nanosecond. Element C<[0]> is the only one that is
828required. Elements C<[1]> and C<[2]> default to C<1>, and the rest to
829C<0>.
830
831=item * An ISO-8601-ish string.
832
833The string is split on non-numerics, and the reform date initialized
834from a reference to the resultant array, as described in the previous
835item. The string B<must> be the punctuated form; that is, C<'1752-9-14'>
836will work, but C<'17520914'> will not. There must not be a zone
837specification, and the year must not be signed.
838
839=back
840
841=head1 BUGS
842
843=over
844
845=item * There are problems with calendars switch to Gregorian before 200 AD or after about 4000 AD. Before 200 AD, this switch leads to duplication of dates. After about 4000 AD, there could be entire missing months. (The module can handle dates before 200 AD or after 4000 AD just fine; it's just the calendar reform dates that should be inside these limits.)
846
847=item * There may be functions that give the wrong results for the year of the calendar reform. The function C<truncate()> is a known problem, and C<today()> may be a problem. If you find any more problems, please let me know.
848
849=back
850
851=head1 SUPPORT
852
853Support for this module is provided via the F<datetime@perl.org> email
854list. See L<https://lists.perl.org/> for more details.
855
856Please report bugs to
857L<https://rt.cpan.org/Public/Dist/Display.html?Name=DateTime-Calendar-Christian>,
858L<https://github.com/trwyant/perl-DateTime-Calendar-Christian/issues>, or
859in electronic mail to F<wyant@cpan.org>.
860
861=head1 AUTHOR
862
863Eugene van der Pijll <pijll@gmx.net>
864
865Thomas R. Wyant, III F<wyant at cpan dot org>
866
867=head1 COPYRIGHT
868
869Copyright (c) 2003 Eugene van der Pijll. All rights reserved.
870
871Copyright (C) 2016-2021 Thomas R. Wyant, III
872
873This program is free software; you can redistribute it and/or modify it
874under the same terms as Perl itself; either the GNU General Public
875License version 1 (or, at your option, any later version) or the
876Artistic License. For more details, see the full text of the licenses in
877the directory LICENSES.
878
879This program is distributed in the hope that it will be useful, but
880without any warranty; without even the implied warranty of
881merchantability or fitness for a particular purpose.
882
883=head1 SEE ALSO
884
885L<DateTime>, L<DateTime::Calendar::Julian>
886
887datetime@perl.org mailing list
888
889=cut
890
891# ex: set textwidth=72 :
892