|
Packit |
95306a |
# Copyright (c) 2008-2017 Sullivan Beck. All rights reserved.
|
|
Packit |
95306a |
# This program is free software; you can redistribute it and/or modify it
|
|
Packit |
95306a |
# under the same terms as Perl itself.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=pod
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=head1 NAME
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Date::Manip::Objects - A description of the various Date::Manip objects
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=head1 SYNOPSIS
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The Date::Manip package consist of several modules, each of which
|
|
Packit |
95306a |
perform a set of operations on a specific class of objects. This
|
|
Packit |
95306a |
document describes how the various modules work together.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=head1 DESCRIPTION
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Date::Manip consists of the following primary modules:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=over 4
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item L<Date::Manip::Obj>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The L<Date::Manip::Obj> module is not intended for direct use. It is used
|
|
Packit |
95306a |
as a base class for all other Date::Manip classes described below.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The L<Date::Manip::Obj> module contains some functions which are
|
|
Packit |
95306a |
inherited by all these classes, so to understand all of the methods
|
|
Packit |
95306a |
available to any of the classes below, you must include those
|
|
Packit |
95306a |
documented in the L<Date::Manip::Obj> class.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item L<Date::Manip::Base>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The L<Date::Manip::Base> is used to perform basic operations including
|
|
Packit |
95306a |
basic date operations, management of configuration options, handling
|
|
Packit |
95306a |
the definitions used in different languages, etc.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
A L<Date::Manip::Base> object does not, of itself, contain any date
|
|
Packit |
95306a |
information. Instead, it contains configuration information which
|
|
Packit |
95306a |
determines how the Date::Manip package performs date operations. The
|
|
Packit |
95306a |
configuration information is documented in the L<Date::Manip::Config>
|
|
Packit |
95306a |
document.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The L<Date::Manip::Base> object has one other property that is very
|
|
Packit |
95306a |
important. When performing basic date operations, some intermediate
|
|
Packit |
95306a |
results are cached in the object which leads to significant
|
|
Packit |
95306a |
performance increases in later operations. As such, it is important to
|
|
Packit |
95306a |
reuse the object as much as possible, rather than creating new
|
|
Packit |
95306a |
L<Date::Manip::Base> objects all the time.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Much of the information in this document is related to this issue, and
|
|
Packit |
95306a |
tells how to create various higher-level objects in order to get the
|
|
Packit |
95306a |
most efficient reuse of this cached data.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Because all other objects depend on a L<Date::Manip::Base> object, a
|
|
Packit |
95306a |
L<Date::Manip::Base> object is embedded in all other objects, and the
|
|
Packit |
95306a |
same Base object can be shared by any number of objects to achieve
|
|
Packit |
95306a |
maximum performance.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item L<Date::Manip::TZ>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The L<Date::Manip::TZ> module adds support for time zones. It is used to
|
|
Packit |
95306a |
verify date and time zone information, convert dates from one time
|
|
Packit |
95306a |
zone to another, and handle all daylight saving time transitions.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Similar to the L<Date::Manip::Base> object, a great deal of information
|
|
Packit |
95306a |
is cached in the L<Date::Manip::TZ> object. This includes lists of all
|
|
Packit |
95306a |
time zones, offsets, and abbreviations for all time zones. It also
|
|
Packit |
95306a |
includes more a more detailed description of every time zone that has
|
|
Packit |
95306a |
actually been worked used.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
A L<Date::Manip::TZ> object relies on a L<Date::Manip::Base> object (and a
|
|
Packit |
95306a |
L<Date::Manip::Base> object is always embedded in a L<Date::Manip::TZ>
|
|
Packit |
95306a |
object). All higher level objects (those listed next) depend on both
|
|
Packit |
95306a |
a L<Date::Manip::Base> and L<Date::Manip::TZ> object, so a L<Date::Manip::TZ>
|
|
Packit |
95306a |
object is embedded in them.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
In order to achieve maximum performance, and minimize memory usage,
|
|
Packit |
95306a |
a L<Date::Manip::TZ> object can be shared by any number of higher
|
|
Packit |
95306a |
level objects, and in fact, it is desirable to reuse the same L<Date::Manip::TZ>
|
|
Packit |
95306a |
object as often as possible.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item L<Date::Manip::Date>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item L<Date::Manip::Delta>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item L<Date::Manip::Recur>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
These are the primary modules which are used to perform all high level
|
|
Packit |
95306a |
date operations.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The L<Date::Manip::Date> class performs operations on dates (which includes
|
|
Packit |
95306a |
a date, time, and time zone). The L<Date::Manip::Delta> class performs
|
|
Packit |
95306a |
operations with deltas (amounts of time). The L<Date::Manip::Recur> class
|
|
Packit |
95306a |
performs operations on recurring events.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
As mentioned above, each of these high level classes rely on both a
|
|
Packit |
95306a |
L<Date::Manip::TZ> object and a L<Date::Manip::Base> object, so a
|
|
Packit |
95306a |
L<Date::Manip::TZ> object is embedded in each one (and the
|
|
Packit |
95306a |
L<Date::Manip::TZ> object has a L<Date::Manip::Base> object embedded in
|
|
Packit |
95306a |
it).
|
|
Packit |
95306a |
|
|
Packit |
95306a |
A L<Date::Manip::Date> object contains a single date, so in order to
|
|
Packit |
95306a |
work with multiple dates, multiple L<Date::Manip::Date> objects will
|
|
Packit |
95306a |
need to be created. In order to make the most effective use of cached
|
|
Packit |
95306a |
information in the L<Date::Manip::Base> object, the same L<Date::Manip::TZ>
|
|
Packit |
95306a |
object can be embedded in each of the higher level objects.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The same goes for multiple L<Date::Manip::Delta> and L<Date::Manip::Recur>
|
|
Packit |
95306a |
objects.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=back
|
|
Packit |
95306a |
|
|
Packit |
95306a |
There are also many secondary modules including:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Date::Manip::TZ_Base
|
|
Packit |
95306a |
Date::Manip::TZdata
|
|
Packit |
95306a |
Date::Manip::Zones
|
|
Packit |
95306a |
Date::Manip::Lang::*
|
|
Packit |
95306a |
Date::Manip::TZ::*
|
|
Packit |
95306a |
Date::Manip::Offset::*
|
|
Packit |
95306a |
|
|
Packit |
95306a |
None of these are intended to be used directly.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=head1 WORKING WITH DATE::MANIP OBJECTS (SINGLE CONFIGURATION)
|
|
Packit |
95306a |
|
|
Packit |
95306a |
By far the most common usage of Date::Manip involves setting a single
|
|
Packit |
95306a |
local time zone, parsing dates in a single language, and having all
|
|
Packit |
95306a |
other configuration parameters set to a single value that doesn't
|
|
Packit |
95306a |
change over the course of the program.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Whenever this is the case, you can use the methods listed in this
|
|
Packit |
95306a |
section to create any number of Date::Manip objects. It will automatically
|
|
Packit |
95306a |
optimize the use of cached data to get the best performance.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
If you do need to work with multiple different configurations (such as
|
|
Packit |
95306a |
parsing dates from multiple languages), please refer to the next
|
|
Packit |
95306a |
section L</"WORKING WITH DATE::MANIP OBJECTS (MULTIPLE CONFIGURATION)">.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=over 4
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item B<Working with high level objects>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The most common situation is one where you will need to use one or
|
|
Packit |
95306a |
more high level objects (Date, Delta, or Recur objects). In addition, you
|
|
Packit |
95306a |
may want to use the lower level (Base or TZ) objects.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The first thing you should do is to create your initial object. Create the
|
|
Packit |
95306a |
highest level object you will be using. For example if you will be working with
|
|
Packit |
95306a |
dates, create the first date object with:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$date = new Date::Manip::Date;
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The next step is to set the configuration values. Use the config method to
|
|
Packit |
95306a |
do this:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$date->config(ARGS);
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Although you can call the config method later, it is strongly
|
|
Packit |
95306a |
suggested that the configuration be set soon after the initial object
|
|
Packit |
95306a |
is created and not altered later. Every time you alter the
|
|
Packit |
95306a |
configuration, some of the cached data is cleared, so for optimal
|
|
Packit |
95306a |
performance, you don't want to alter the configuration if possible.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Additional high-level objects can be created using the calls:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$date2 = $date->new_date();
|
|
Packit |
95306a |
$delta = $date->new_delta();
|
|
Packit |
95306a |
$recur = $date->new_recur();
|
|
Packit |
95306a |
|
|
Packit |
95306a |
To access the embedded L<Date::Manip::TZ> and L<Date::Manip::Base> objects,
|
|
Packit |
95306a |
use the calls:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$tz = $date->tz();
|
|
Packit |
95306a |
$base = $date->base();
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item B<Working with low level objects only>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
If you will only be working with low level objects, create them with one
|
|
Packit |
95306a |
of the calls:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$tz = new Date::Manip::TZ;
|
|
Packit |
95306a |
$base = new Date::Manip::Base;
|
|
Packit |
95306a |
|
|
Packit |
95306a |
To get the base object embedded in a L<Date::Manip::TZ> object, use:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$base = $tz->base();
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=back
|
|
Packit |
95306a |
|
|
Packit |
95306a |
For a more complete description of the methods used here, refer to the
|
|
Packit |
95306a |
L<Date::Manip::Obj> document.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=head1 WORKING WITH DATE::MANIP OBJECTS (MULTIPLE CONFIGURATION)
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Occasionally, it may be useful to have multiple sets of configurations.
|
|
Packit |
95306a |
In order to do this, multiple L<Date::Manip::Base> objects must be
|
|
Packit |
95306a |
created (each with their own set of configuration options), and then
|
|
Packit |
95306a |
new Date::Manip objects are created with the appropriate L<Date::Manip::Base>
|
|
Packit |
95306a |
object embedded in them.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Possible reasons include:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=over 4
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item B<Parsing multiple languages>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
A L<Date::Manip::Base> object includes information about a single
|
|
Packit |
95306a |
language. If you need to parse dates from two (or more) languages,
|
|
Packit |
95306a |
a L<Date::Manip::Base> object needs to be created for each one. This
|
|
Packit |
95306a |
could be done as:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$date_eng1 = new Date::Manip::Date;
|
|
Packit |
95306a |
$date_eng1->config("language","English");
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$date_spa1 = new Date::Manip::Date;
|
|
Packit |
95306a |
$date_spa1->config("language","Spanish");
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Any additional Date::Manip objects created from the first will work
|
|
Packit |
95306a |
with English. Additional objects created from the second will work in
|
|
Packit |
95306a |
Spanish.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item B<Business modes for different countries and/or businesses>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
If you are doing business mode calculations (see L<Date::Manip::Calc>)
|
|
Packit |
95306a |
for two different businesses which have different holiday lists,
|
|
Packit |
95306a |
work weeks, or business days, you can create different objects
|
|
Packit |
95306a |
which read different config files (see L<Date::Manip::Config>) with
|
|
Packit |
95306a |
the appropriate description of each.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=back
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The primary issue when dealing with multiple configurations is
|
|
Packit |
95306a |
that it is necessary for the programmer to manually keep track of
|
|
Packit |
95306a |
which Date::Manip objects work with each configuration. For
|
|
Packit |
95306a |
example, refer to the following lines:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$date1 = new Date::Manip::Date [$opt1,$val1];
|
|
Packit |
95306a |
$date2 = new Date::Manip::Date $date1, [$opt2,$val2];
|
|
Packit |
95306a |
$date3 = new Date::Manip::Date $date1;
|
|
Packit |
95306a |
$date4 = new Date::Manip::Date $date2;
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The first line creates 3 objects: a L<Date::Manip::Base> object, a
|
|
Packit |
95306a |
L<Date::Manip::TZ> object, and a L<Date::Manip::Date> object). The
|
|
Packit |
95306a |
L<Date::Manip::Base> object has the configuration set to contain the
|
|
Packit |
95306a |
value(s) passed in as the final list reference argument.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The second line creates 3 new objects (a second L<Date::Manip::Base>
|
|
Packit |
95306a |
object, a second L<Date::Manip::TZ> object, and a second
|
|
Packit |
95306a |
L<Date::Manip::Date> object). Since a list reference containing config
|
|
Packit |
95306a |
variables is passed in, a new L<Date::Manip::Base> object is created,
|
|
Packit |
95306a |
rather than reusing the first one. The second L<Date::Manip::Base> object
|
|
Packit |
95306a |
contains all the config from the first, as well as the config
|
|
Packit |
95306a |
variables passed in in the list reference argument.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The third line creates another L<Date::Manip::Date> object which uses the
|
|
Packit |
95306a |
first L<Date::Manip::Base> and L<Date::Manip::TZ> objects embedded in it.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The fourth line creates another L<Date::Manip::Date> object which uses
|
|
Packit |
95306a |
the second L<Date::Manip::Base> and L<Date::Manip::TZ> objects embedded in
|
|
Packit |
95306a |
it.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Most of the time there will only be one set of configuration options
|
|
Packit |
95306a |
used, so this complexity is really for a very special, and not widely
|
|
Packit |
95306a |
used, bit of functionality.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=head1 WORKING WITH DATE::MANIP OBJECTS (ADDITIONAL NOTES)
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=over 4
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item B<object reuse>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
In order to create additional Date::Manip objects, a previously
|
|
Packit |
95306a |
created object should be passed in as the first argument. This will
|
|
Packit |
95306a |
allow the same Base object to be embedded in both in order to maximize
|
|
Packit |
95306a |
data reuse of the cached intermediate results, and will result in much
|
|
Packit |
95306a |
better performance. For example:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$date1 = new Date::Manip::Date;
|
|
Packit |
95306a |
$date2 = new Date::Manip::Date $date1;
|
|
Packit |
95306a |
|
|
Packit |
95306a |
This is important for two reasons. First is memory usage. The
|
|
Packit |
95306a |
L<Date::Manip::Base> object is quite large. It stores a large number of
|
|
Packit |
95306a |
precompile regular expressions for language parsing, and as date
|
|
Packit |
95306a |
operations are done, intermediate results are cached which can be
|
|
Packit |
95306a |
reused later to improve performance. The L<Date::Manip::TZ> object is
|
|
Packit |
95306a |
even larger and contains information about all known time zones indexed
|
|
Packit |
95306a |
several different ways (by offset, by abbreviation, etc.). As
|
|
Packit |
95306a |
time zones are actually used, a description of all of the time change
|
|
Packit |
95306a |
rules are loaded and added to this object.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Since these objects are so large, it is important to reuse them, rather
|
|
Packit |
95306a |
than to create lots of copies of them. It should be noted that because
|
|
Packit |
95306a |
these objects are embedded in each of the high level object (L<Date::Manip::Date>
|
|
Packit |
95306a |
for example), it makes these objects appear quite large.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
The second reason to reuse L<Date::Manip::Base> objects is
|
|
Packit |
95306a |
performance. Since intermediate results are cached there, many date
|
|
Packit |
95306a |
operations only need to be done once and then they can be reused any
|
|
Packit |
95306a |
number of times. In essence, this is doing the same function as the
|
|
Packit |
95306a |
Memoize module, but in a more efficient manner. Memoize caches results
|
|
Packit |
95306a |
for function calls. For Date::Manip, this would often work, but if you
|
|
Packit |
95306a |
change a config variable, the return value may change, so Memoize
|
|
Packit |
95306a |
could cause things to break. In addition, Memoize caches primarily at
|
|
Packit |
95306a |
the function level, but Date::Manip stores caches intermediate results
|
|
Packit |
95306a |
wherever performance increase is seen. Every time I consider caching a
|
|
Packit |
95306a |
result, I run a test to see if it increases performance. If it
|
|
Packit |
95306a |
doesn't, or it doesn't make a significant impact, I don't cache it.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Because the caching is quite finely tuned, it's much more efficient
|
|
Packit |
95306a |
than using a generic (though useful) tool such as Memoize.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=item B<configuration changes>
|
|
Packit |
95306a |
|
|
Packit |
95306a |
As a general rule, you should only pass in configuration options
|
|
Packit |
95306a |
when the first object is created. In other words, the following
|
|
Packit |
95306a |
behavior is discouraged:
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$date = new Date::Manip::Date;
|
|
Packit |
95306a |
$date->config(@opts);
|
|
Packit |
95306a |
|
|
Packit |
95306a |
... do some stuff
|
|
Packit |
95306a |
|
|
Packit |
95306a |
$date->config(@opts);
|
|
Packit |
95306a |
|
|
Packit |
95306a |
... do some other stuff
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Because some of the cached results are configuration specific, when a
|
|
Packit |
95306a |
configuration change is made, some of the cached data must be discarded
|
|
Packit |
95306a |
necessitating those results to be recalculated.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
If you really need to change configuration in the middle of execution,
|
|
Packit |
95306a |
it is certainly allowed of course, but if you can define the configuration
|
|
Packit |
95306a |
once immediately after the object is first created, and then leave the
|
|
Packit |
95306a |
configuration alone, performance will be optimized.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=back
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=head1 BUGS AND QUESTIONS
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Please refer to the L<Date::Manip::Problems> documentation for
|
|
Packit |
95306a |
information on submitting bug reports or questions to the author.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=head1 SEE ALSO
|
|
Packit |
95306a |
|
|
Packit |
95306a |
L<Date::Manip> - main module documentation
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=head1 LICENSE
|
|
Packit |
95306a |
|
|
Packit |
95306a |
This script is free software; you can redistribute it and/or
|
|
Packit |
95306a |
modify it under the same terms as Perl itself.
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=head1 AUTHOR
|
|
Packit |
95306a |
|
|
Packit |
95306a |
Sullivan Beck (sbeck@cpan.org)
|
|
Packit |
95306a |
|
|
Packit |
95306a |
=cut
|