I like core module Time::Local's timelocal_nocheck / timegm_nocheck for doing time and date arithmetic.
use strict;
use warnings;
use POSIX qw( strftime );
use Time::Local qw( timegm_nocheck );
# Supplied definitions.
my $base_year = 2004;
my $base_month = 1; # 0-based
my $base_day = 1; # 1-based
my @weeks_in_month = (
4, # Feb
5, # Mar
4, # Apr
4, # May
5, # Jun
4, # Jul
4, # Aug
5, # Sep
4, # Oct
4, # Nov
5, # Dec
4, # Jan
);
# Derived constants.
my @days_before_month = (0);
for (0..11) {
$days_before_month[$_+1] = $days_before_month[$_]
+ $weeks_in_month[$_] * 7;
}
my $days_in_year = $days_before_month[12];
# The guts.
sub first_day_of_accounting_month {
my ($year, $month) = @_;
my $day = $base_day
+ ($year - $base_year) * $days_in_year
+ $days_before_month[$month];
my $time = timegm_nocheck(0,0,0, $day, $base_month, $base_year);
}
sub first_day_of_accounting_year {
push(@_, 0);
goto &first_day_of_accounting_month;
}
# Generate a bunch of data for demo purposes.
# The output format can easily be changed.
my $date_format = '%b %d, %Y';
for my $year (2004 .. 2015) {
my $time;
$time = first_day_of_accounting_year($year);
print("Accounting year $year\n");
print(strftime($date_format, gmtime($time)) . "\n");
print("\n");
for my $month (0..11) { # Feb..Jan
$time = first_day_of_accounting_month($year, $month);
print(strftime($date_format, gmtime($time)) . "\n");
}
print("\n");
print("\n");
}
The above prints:
Accounting year 2004
Feb 01, 2004
Feb 01, 2004
Feb 29, 2004
Apr 04, 2004
May 02, 2004
May 30, 2004
Jul 04, 2004
Aug 01, 2004
Aug 29, 2004
Oct 03, 2004
Oct 31, 2004
Nov 28, 2004
Jan 02, 2005
Accounting year 2005
Jan 30, 2005
Jan 30, 2005
Feb 27, 2005
...
Accounting year 2006
Jan 29, 2006
Jan 29, 2006
Feb 26, 2006
...
Accounting year 2007
Jan 28, 2007
Jan 28, 2007
Feb 25, 2007
...
Update: I moved the guts into functions, and I added a few more comments.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.