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