I have written a perl module which may meet your requirements. I have not
submitted to CPAN since I do not wish to be involved in this process at this
time.
Perhaps you may want to look at and critique it. We could work together to
improve it and you want to submit it to CPAN
I am a newbie to Perl and a newcomer to DateTime so I am sure that this
module does not meet the requirements of CPAN but it is a start.
I call the module Datetime::finance.
it contains the following functions:
isLastDay # return true if given date is the
last day of month
getLastDays # fills an array with last day of month
dates
# 0, 1, 3, 6, 12 months from
for a given date
# series start the previous
month unless given date is end of month
This function is very specific
to my needs and may not belong here
thirdFriday # returns the date of the 3rd Friday
in the month of a given date.
isFriday # return true if given date is a
Friday
A rather trivial function ...
mostly a helper function for getFridays
getFridays # fills an array with Friday dates
# 0, 1, 2, 3, 4, 5, 6, 7, 13,
39, 52 from a given Friday date
# if the given date is not a
Friday, the date is set
# to the previous Friday
This function is very specific
to my needs and may not belong here
is15th # return true if given date is the
15th day of month
A rather trivial function ...
mostly a helper function for get15thDays
get15thDays # fills an array with the 15th day of
month dates
# 0, 1, 3, 6, 12 months from a
given date
# if the given date day is less
than 15th, the month is set to the
# previous month
getMonthDates # fills an array with dates that
# 0, 1, 3, 6, 12 months
earlier than given date;
This function is very
specific to my needs and may not belong here
getEOY # return the last day of year
for previous year of given date
getMarketDate # return given date if market is
open
# or the previous
market date if market is closed for the given date;
marketDays # return the number of market
days (business days)
# from date1 to date2
# expect two DateTime
objects;
daysFrom # adds a specified number of
market days to a given date
# returns a DateTime
object
# market days are days
when the stock markets is open
lastDay # return the last day of
month for a given date
isOpen # return true if given date
is Monday, Tuesday, ... Friday
# and not a market
holiday
isClose # return true if given
date is Saturday, Sunday, or market holiday
isHoliday # structure used by
isHoliday();
# needs to be updated
each year
Localized for US
Markets ... needs updating each year
nextExpirationDay # returns the next option
expiration date for current date or a given date
mmddyy2dt These functions are fairly
obvious as to what they do.
mysql2dt
mysql2csv
csv2mysql
mysql2yymmdd
----- Original Message -----
From: "Matthew Persico" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Cc: <datetime@perl.org>
Sent: Monday, June 06, 2005 2:33 PM
Subject: Re: Fwd: DateTime::Business
On 6/3/05, Rick Measham <[EMAIL PROTECTED]> wrote:
Matthew Persico wrote:
> 1) Add a convenience method called 'today' to DateTime, which is the
> same as Date::Time->now->trunc(to=>day)
Already there ..
$today = DateTime->today();
Hmm, don't know how I missed that one...
> 2) All business dates will have no time component. All decrements and
> increments of business dates will be a number of days - I don't think
> there is a concept of business weeks or months...
Absolutely disagree on this point. You have to have finer control than
days. If a project is going to take 100 man-hours and you have 7 people
working on it, you need to be able to do:
When I say business date in the US, I'm thinking in terms of dates on
which financial transactions are able to be executed or settled. Time
is irrelevant: for example, if the trade executes on a Friday, it
cannot settle on Sat or Sun because the are not business days. Hours
are irrelevant.
If I were writing an object to handle your examples below, I'd call it
DateTime::Calendar::Man (as in man-hours, man-days, man-weeks, etc,
with apologies to the other half of the human race...)
which would need a holiday calendar attached to it in some way (much
as my DateTime::Business would) to get the math right.
Between your comments and those of [EMAIL PROTECTED] prior to yours, I
am starting to think that the only "right" way to do this is to create
the calendar as a separate entity and feed it to DateTime instead of
trying to create Yet Another Sub Class of DateTime. The only thing I
have to account for in my world is setting time to 00:00
[snip]
Also, you cannnot ignore things like weeks and months. Especially
months. From a business POV, in Australia note the following behaviour
would be 'correct':
$this_year = DateTime::Calendar::Business::Australia->now->trunc( to =>
year );
print $this_year->datetime;
# 2004-07-01T00:00:00
In Australia, the tax year start on July 1st and finishes on June 30th
and so truncating to year would have to return a July 1st date. In the
states I believe it's April 19th or some such.
In the US, April 15 is the date by which you have to file your tax
return for the previous year. The tax year is Jan 1 through Dec. 31
for all personal taxes. I don't know the effect on taxes for a
business with a fiscal year != physical year. Most file quarterly
anyway - the end of year may only affect when any refunds are actually
refunded to a business.
There's probably hundreds, if not thousands, of different ways of
defining business days and so I'd suggest implementing a simple way to
localize and cascade your data such as this:
package DateTime::Calendar::Business::Australia;
@ISA = qw/DateTime::Calendar::Business/;
$YEARSTART = { month => 7, day => 1 };
@BUSINESSHOURS = [
1 => [ {hour => 9}, {hour => 17} ],
2 => [ {hour => 9}, {hour => 17} ],
3 => [ {hour => 9}, {hour => 17} ],
4 => [ {hour => 9}, {hour => 17} ],
5 => [ {hour => 9}, {hour => 17, minute => 30} ],
6 => [ {hour => 9}, {hour => 12} ],
7 => [ ],
];
@PUBLICHOLIDAYS = [
{ month=>1, day=>26 }, #Australia Day
{ month=>4, day=>25 }, #ANZAC Day
{ month=>12, day=>25 }, #Christmas Day
{ DateTime::Event::Easter->new( day=> -2) }, #Good Friday
{ DateTime::Event::Easter->new( day=> 0) }, #Easter Sunday
];
package DateTime::Calendar::Business::MyCompany;
@ISA = qw/DateTime::Calendar::Business::Australia/;
@BUSINESSHOURS = [
1 => [ {hour => 9}, {hour => 17, minute => 30} ],
2 => [ {hour => 9}, {hour => 17, minute => 30} ],
3 => [ {hour => 9}, {hour => 17, minute => 30} ],
4 => [ {hour => 9}, {hour => 21} ],
5 => [ {hour => 9}, {hour => 21} ],
6 => [ {hour => 9}, {hour => 17} ],
7 => [ {hour =>10}, {hour => 16} ],
];
__END__
Once you have all your definitions in place, then a
DateTime::Calendar::Business object should work just like a DateTime
object -- you should be able to truncate it, add to it, subtract from it
etc. Just have to remember that a day on your calendar is not the same
as a day on the gregorian calendar, your days are only 7 or 8 hours each
and you weeks are 5 or 6 days long.
Cheers!
Rick Measham
Aside from the use of hours, which I don't need,
--
Matthew O. Persico