NAME

DateTimeX::Fiscal::Fiscal5253 - Create fiscal 52/53 week calendars

SYNOPSIS

use DateTimeX::Fiscal::Fiscal5253;
 
my $fc = DateTimeX::Fiscal::Fiscal5253->new( year => 2012 );

DESCRIPTION

This module generates calendars for a "52/53 week" fiscal year. They are also known as "4-4-5" or "4-5-4" calendars due to the repeating week patterns of the periods in each quarter. A 52/53 week year will always have either 52 or 53 weeks (364 or 371 days.) One of the best known of this type is the standard Retail 4-5-4 calendar as defined by the National Retail Federation.

You are strongly advised to speak with your accounting people (after all, the reason you are reading this is because they want reports, right?) and show them the summary data for any given year and see if it matches what they expect.

Keep in mind that when an accountant says they want data for fiscal year 2012 they are probably talking about an accounting year that ends in 2012. An accountant will usually think in terms of "the fiscal year ending in October, 2012." (Unless they are talking about Retail 4-5-4 years, see the section below that deals specifically with this.)

ERROR HANDLING

All error conditions die via croak. Please see the README file for the rationale behind this.

Note! This is a change in the API! The first releases returned undef on error with a message emitted via carp. It was felt that this change would not impose an undue hardship in the code changes required to accomdate it and that the new behavior would not introduce any undesired side-effects in any existing code.

CONSTRUCTOR

new

my $fc = DateTimeX::Fiscal::Fiscal5253->new();

my $fc = DateTimeX::Fiscal::Fiscal5253->new(
    end_month => 12,
    end_dow => 6,
    end_type => 'last',
    leap_period => 'last',
);

The constructor must be called as a class method and will throw an exception if not. It accepts the following parameters:

end_month

set the last calendar month of the fiscal year. This should be an integer in the range 1 .. 12 where "1" is January. Default: 12

end_dow

sets the last day of the week of the fiscal year. This is an integer in the range 1 .. 7 with Monday being 1. Remember, a 52/53 week fiscal calendar always ends on the same weekday. Default: 6 (Saturday)

end_type

determines how to calculate the last day of the fiscal year based on the end_month and end_dow. There are two legal vaules: "last" and "closest". Default: "last"

"last" says to use the last weekday in the month of the type specified in end_dow as the end of the fiscal year.

"closest" says to use the weekday of the type specified that is closest to the end of the calendar month as the last day, even if it is in the following month.

leap_period

determines what period the 53rd week (if needed) is placed in. This could be of importance when creating year-over-year reports. There are two legal values: "first" and "last". Default: "last"

"first" says to place the extra week in period 1.

"last" says to place the extra week in period 12.

The last two parameters control what year the calendar is generated for. These parameters are optional but mutually exclusive and will throw an exception if both are present.

year

sets the fiscal year to build for. It defaults to the correct fiscal year for the current date or to the fiscal year containing the date specified by date.

The fiscal year value will often be different than the calendar year for dates that are near the beginning or end of the fiscal year. For example, Jan 3, 2015 is the last day of FYE2014 when using an end_type of "closest".

NOTE! In normal accounting terms, a fiscal year is named for the calendar year it ends in. That is, for a fiscal year that ends in October, fiscal year 2005 would begin in October or November of calendar year 2004 (depending upon the setting of end_type.) However, Retail 4-5-4 calendars are named for the year they begin in. This means that a Retail 4-5-4 calendar for 2005 would begin in 2005 and not 2004 as an accountant would normally think. See the discussion at the end of this documentation about Retail 4-5-4 calendars for more information.

date

if present, is either a string representing a date or a DateTime object. This will be used to build a calendar that contains the given value. Again, be aware that dates that are close to the end of a given fiscal year might have different values for the calendar year vs the fiscal year.

If the value for date is a string, it must be specified as either "YYYY-MM-DD" or "MM/DD/YYYY" or some reasonable variant of those such as single digit days and months. Time components, if present, are discarded. Any other format will throw an exception. A DateTime object will be cloned before being used to prevent unwanted changes to the original object.

ACCESSORS

The accessors allow you to examine the parameters used to create the calendar and the resulting base values. All accessors are read-only and will throw an exception if a parameter is passed to them.

If you want to change any of the underlying properties that define an object, create a new object!

end_month

my $end_month = $fc->end_month();

end_dow

my $end_dow = $fc->end_dow();

end_type

my $end_type = $fc->end_type();

leap_period

my $leap_period = $fc->leap_period();

year

my $year = $fc->year();

Returns the either the value that was supplied for the year parameter to the constuctor or the year that resulted from the value supplied in the constructor's date parameter. This is what will be used as the name of the fiscal year.

start

my $start = $fc->start();

Returns the first date in the fiscal year as constructed from the parameters given to the constructor.

end

my $end = $fc->end();

Returns the last date in the fiscal year as constructed from the parameters given to the constructor.

weeks

my $weeks = $fc->weeks();

Returns the number of weeks in the fiscal year as generated by the parameters given to the construtor. The value will be either "52" or "53" depending on whether a leap week was added. This value does not look at the calendar style but rather is based on only the fiscal year itself.

has_leap_week

my $fc = DateTimeX::Fiscal::Fiscal5253->new( year => 2006 );
print "This is a Fiscal Leap Year" if $fc->has_leap_week;

This method is basically syntactic sugar for the weeks accessor and returns a Boolean value indicating whether or not the fiscal Year for the object has 53 weeks instead of the standard 52 weeks.

METHODS

style

my $fc = DateTimeX::Fiscal::Fiscal5253->new( year => 2006 );
my $cal_style = $fc->style; # returns the current style
$fc->style( 'restated );    # set the style to 'restated'

This method reads and sets the calendar style to be used by all of the following methods. It can be overridden on a case by case basis as needed by those methods.

The legal values are "fiscal", "restated", and "truncated" when the style is being set. A new object has the style set to 'fiscal' by default.

The value 'fiscal' will use a calendar with the full number of weeks without regard to whether there are 52 or 53 weeks in the year.

The value 'restated' says to ignore the first week in a 53 week year and create a calendar with only 52 weeks. This allows for more accurate year-over-year comparisons involving a year that would otherwise have 53 weeks.

The value 'truncated' says to ignore the last week in a 53 week year and create a calendar with only 52 weeks. This may allow for more accurate year-over-year comparisons involving a year that would otherwise have 53 weeks.

"restated" and "truncated" have no effect in normal 52 week years.

summary

my %summary = $fc->summary();
my $summary = $fc->summary();

my %summary = $fc->summary( style => 'restated');
my $summary = $fc->summary( 'restated' );

This method will return either a hash or a reference to a hash (depending upon context) containing a summary of the current calendar style or the one specified by the style parameter.

my $fc = DateTimeX::Fiscal::Fiscal5253->new( year => 2012 );
my $fc_info = $fc->summary();
 
print Dumper($fc_info);
$VAR1 = {
         'style => 'fiscal',
         'year' => 2012,
         'start' => '2012-01-01',
         'end' => '2012-12-29',
         'weeks' => 52
       };

The value contained in $fc_info->{year} is the name of the fiscal year as commonly used by accountants (as in "fye2012") and is usually the same as the calendar year the fiscal year ends in. However, it is possible for the actual ending date to be in the following calendar year when the end_month is '12' (the default) and an end_type of "closest" is specified, fiscal year 2014 built as shown below demonstrates this:

my $fc = DateTimeX::Fiscal::Fiscal5253->new(
             year => 2014,
             end_type => 'closest'
         );

print Dumper($fc->summary());
$VAR1 = {
         'style => 'fiscal',
         'year' => 2014,
         'start' => '2013-12-29',
         'end' => '2015-01-03',
         'weeks' => 53
       };

contains

my $fc = DateTimeX::Fiscal::Fiscal5253->new( year => 2012 );
 
if ( my $wnum = $fc->contains() ) {
    print "The current date is in week $wnum\n";
}
 
if ( $fc->contains( date => 'today', style => 'restated' ) ) {
    print 'The current day is in the fiscal calendar';
}
 
if ( $fc->contains( date => '2012-01-01', style => 'fiscal' ) ) {
    print '2012-01-01 is in the fiscal calendar';
}
 
my $dt = DateTime->today( time_zone => 'floating' );
if ( my $wnum = $fc->contains( date => $dt ) ) {
    print "$dt is in week $wnum\n";
}
 
my %containers = $fc->contains( '2012-06-04' );
print Dumper(\%containers);
$VAR1 = {
         'period' => 6,
         'week' => 23
       };

Returns the week number in the designated style that contains the given date or undef if not. The method will croak if an error occurs such as an invalid date format or unknown style type.

This method takes two named parameters, 'date' and 'style'. Bear in mind that some dates that are in the fiscal calendar might not be in a restated or truncated calendar. A single un-named parameter can be used as a shorthand for supplying only the date.

A hash containing both the period and week numbers is returned if the method is called in list context and the date is present.

date

Accepts the same formats as the constructor as well as the special keyword 'today'. Defaults to the current date if not supplied.

style

Specifies which calendar style to check against and accepts the same values as the 'style' method does. The default is the current value returned as set by the style method.

period

my %pdata = $fc->period( period => 5, style => 'restated' );
my $pdata = $fc->period( period => 1, style => 'fiscal' );

Read-only method that returns a hash or a reference to a hash depending upon context that contains all of the data for the requested period in the specified style type.

period

Must be a number in the range 1 - 12. An exception will be thrown if this parameter is not given.

style

Specifies what calendar style to retrieve the period information from. Legal values are the same as those for the style method. The current value of the style method will be used by default.

The returned data is as follows:

print Dumper($pdata);
$VAR1 = { 
         'period' => 1,
         'month' => 'February',
         'start' => '2012-02-04',
         'weeks' => 4,
         'end' => '2012-03-02'
       };

The following methods are syntactic sugar for those who prefer to access the individual components of the period structure without dealing with a hash. They return a scalar value and accept the same parameters as period does.

period_month
my $pmonth = $fc->period_month( period => 3, style => 'fiscal' );
period_start
my $pstart = $fc->period_start( period => 5 );
period_end
my $pend = $fc->period_end( style => 'fiscal' );
period_weeks
my $pweeks = $fc->period_weeks( period => 2, style => 'restated' );

There is no method to return the period number component because presumably you already know that. Use contains to get the period number for the current date if applicable. (Besides, $fc->period_period is just plain ugly!)

week

my %wdata = $fc->week( week => 5, style => 'restated' );
my $wdata = $fc->week( week => 5, style => 'restated' );

Read-only method that returns a hash or a reference to a hash depending upon context that contains all of the data for the requested week in the specified style type.

week

Must be a number in the range 1 - 52 (53 if a leap week is present in the requested style.) An exception will be thrown if not given.

style

Specifies what calendar style to retrieve the week information from. Legal values are the same as those for the style method. The current value for the style method will be used by default.

The returned data is as follows:

print Dumper($wdata);
$VAR1 = { 
         'week' => 5,
         'period' => 2,
         'period_week' => 1,
         'start' => '2012-01-29'
         'end' => '2012-02-04',
       };

The following methods are syntactic sugar for those who prefer to access the individual components of the week structure without dealing with a hash. They return a scalar value and accept the same parameters as week does.

week_period
my $wperiod = $fc->week_period( week => 3, style => 'fiscal' );
week_period_week
my $wperiod = $fc->week_period_week( week => 3, style => 'fiscal' );
week_start
my $wstart = $fc->week_start( week => 5 );
week_end
my $wend = $fc->week_end( style => 'fiscal' );

There is no method to return the week number component because presumably you already know that. Use contains to get the week number for the current date if applicable. (Besides, $fc->week_week is just plain ugly!)

RETAIL 4-5-4 CALENDARS

A Retail 4-5-4 calendar (as described by the National Retail Federation here: http://www.nrf.com/modules.php?name=Pages&sp_id=392) is an example of a fiscal 52/53 week year that starts on the Sunday closest to Jan 31 of the specified year.

In other words, to create a Retail 4-5-4 calendar for 2012, you will create a Fiscal5253 object that ends in 2013 on the Saturday closest to Jan 31.

Note! Fiscal years are named for the year they end in, Retail 4-5-4 years are named for the year they begin in!

# Create a Retail 4-5-4 calendar for 2012
my $r2012 = DateTimeX::Fiscal::Fiscal5253->new(
    year => 2013,          # This will be the ending year for the calendar
    end_month => 1,        # End in January
    end_dow => 6,          # on the Saturday
    end_type => 'closest', # closest to the end of the month
    leap_period => 'last'  # and any leap week in the last period
);

print Dumper(\%{$r2012->summary()});
$VAR1 = { 
         'style' => 'fiscal',
         'year' => '2013',
         'weeks' => 53,
         'start' => '2012-01-29'
         'end' => '2013-02-02',
        };

print Dumper(\%{$r2012->summary( style => 'restated' )});
$VAR1 = { 
         'style' => 'restated',
         'year' => '2013',
         'weeks' => 52,
         'start' => '2012-02-05'
         'end' => '2013-02-02',
       };

print Dumper(\%{$r2012->summary( style => 'truncated' )});
$VAR1 = { 
         'style' => 'truncated',
         'year' => '2013',
         'weeks' => 52,
         'start' => '2012-01-29'
         'end' => '2013-01-26',
       };

You can verify that this is correct by viewing the calendars available at the NRF website: http://www.nrf.com/4-5-4Calendar

The reporting date can be determined by adding 5 days to the end of any given period. Using DateTime makes this trivial:

# Get the reporting date for period 5 for the object created above
my ($y,$m,$d) = split(/\-/,$r2012->period_end( period => 5 ));
my $report_date = DateTime->new(
    year => $y,
    month => $m,
    day => $d
)->add( days => 5 )->ymd;

DEPENDENCIES

DateTime, Carp

TO DO

Allow the leap_period parameter to 'new' to accept a number in the range 1 .. 12 besides 'first' and 'last' to specify explicitly which period to place any leap week in.

Anything else that users of this module deem desirable.

SEE ALSO

DateTime to get ideas about how to work with an object suppiled to the constructor as the date parameter.

Do a Google (or comparable) search to learn more about fiscal Years and the 52/53 week. This is a fairly arcane subject that usually is of interest only to accountants and those of us who must provide reports to them.

Of particular interest will be how a Retail 4-5-4 calendar differs in definition from an accounting 4-4-5 fiscal year.

CREDITS

This module, like any other in the DateTime family, could not exist without the work and dedication of Dave Rolsky.

SUPPORT

Support is provided by the author. Please report bugs or make feature requests to the author or use the GitHub repository:

http://github.com/boftx/DateTimeX-Fiscal-Fiscal5253

AUTHOR

Jim Bacon, <jim@nortx.com>

COPYRIGHT AND LICENSE

Copyright (C) 2012 by Jim Bacon

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.