# Copyright (c) 2008-2009 Sullivan Beck. All rights reserved.
# This program is free software; you can redistribute it and/or modify it
# under the same terms as Perl itself.

=pod

=head1 NAME

Date::Manip::Objects - A description of the various Date::Manip objects

=head1 SYNOPSIS

The Date::Manip package consist of several modules, each of which
perform a set of operations on a specific type of information. This
document describes how the various modules work together.

=head1 DESCRIPTION

Date::Manip consists of several different modules, each of which deal with
a different type of data.

The primary modules are:

=over 4

=item Date::Manip::Obj

The Date::Manip::Obj module is not intended for direct use. It is used
as a base class for all other Date::Manip classes described below.

The Date::Manip::Obj module contains some functions which are
inherited by all these classes, so to understand all of the methods
available to any of the classes below, you must include those
documented in the Date::Manip::Obj class.

=item Date::Manip::Base

The Date::Manip::Base is used to perform basic operations including
basic date operations, management of configuration options, handling
the definitions used in different languages, etc.

A Date::Manip::Base object does not, of itself, contain any date
information. Instead, it contains configuration information which
determines how the Date::Manip package performs date operations.  The
configuration information is documented in the Date::Manip::Config
manual.

The Date::Manip::Base object has one other property that is very
important. When performing basic date properties, some intermediate
results are cached in the object which leads to significant
performance increases in later operations. As such, it is important to
reuse the object as much as possible, rather than creating new
Date::Manip::Base objects all the time.

Much of the information in this document is related to this issue, and
tells how to create various objects in order to get the most efficient
reuse of this cached data.

Because all other objects depend on a Date::Manip::Base object, a
Date::Manip::Base object is embedded in all other objects.

=item Date::Manip::TZ

The Date::Manip::TZ module adds support for time zones. It is used
to verify date and time zone information, convert dates from one
time zone to another, and handle all daylight saving time transitions.

All higher level objects (those listed next) depend on both a
Date::Manip::Base and Date::Manip::TZ object, so one of each are
embedded into those objects.

=item Date::Manip::Date

=item Date::Manip::Delta

=item Date::Manip::Recur

These are the primary modules which are used to perform all high level
date operations.

The Date::Manip::Date class performs operations on dates (which includes
a date, time, and time zone). The Date::Manip::Delta class performs
operations with deltas (amounts of time). The Date::Manip::Recur class
performs operations on recurring events.

As mentioned above, each of these high level classes rely on both a
Date::Manip::TZ object and a Date::Manip::Base object, and one of each
is embedded in each object.

A Date::Manip::Date object contains a single date, so in order to
work with multiple dates, multiple Date::Manip::Date objects will
need to be created. In order to make the most effective use of cached
information in the Date::Manip::Base object, the same Date::Manip::Base
object can be embedded in each of the higher level objects.

The same goes for multiple Date::Manip::Delta and Date::Manip::Recur
objects.

=back

=head1 WORKING WITH DATE::MANIP OBJECTS

The basic way to create the first instance of a Date::Manip object (of
any class) is to use the "new" method of the appropriate class.  This
is documented in the Date::Manip::Obj manual.  For example:

   $tz   = new Date::Manip::TZ;
   $date = new Date::Manip::Date;

Optionally, config options can be passed in:

   $tz   = new Date::Manip::TZ \@opts;
   $date = new Date::Manip::Date \@opt;

In order to create additional Date::Manip objects, a previously
created object should be passed in as the first argument. This will
maximize data reuse of the cached intermediate results, and will
result in much better performance. For example:

   $date1 = new Date::Manip::Date;
   $date2 = new Date::Manip::Date $date1;

As a general rule, you should only pass in configuration options
when the first object is created. In other words, the following
behavior:

    $date1 = new Date::Manip::Date [$opt1,$val1,$opt2,$val2];
    $date2 = new Date::Manip::Date $date1;

will behave differently than:

    $date1 = new Date::Manip::Date [$opt1,$val1];
    $date2 = new Date::Manip::Date $date1,[$opt2,$val2];

In the first case, only a single Date::Manip::Base object is created.
In the second case, two Date::Manip::Base objects are created.

Unless you specifically need to work with multiple sets of
configurations (which is described below), it is far less complicated,
and results in better performance, to work with only a single
Date::Manip::Base object.

It is also preferred that all configuration be done soon after the
first object is created in order to keep things clear.

To following example illustrates a potential pitfall:

    $date1 = new Date::Manip::Date [$opt1,$val1];
    $date2 = new Date::Manip::Date $date1,
    $date1->config($opt2,$val2);

The first two lines create a total of 4 Date::Manip object. The first
line creates a Date::Manip::Base object and a Date::Manip::TZ object,
and then a Date::Manip::Date object with the first two embedded in it.

The second line creates a second Date::Manip::Date object, with the
same Date::Manip::Base and Date::Manip::TZ objects embedded in it.

The third line alters the configuration information used by the $date1
object. Since configuration information is stored only in the Base
object, that object is modified, and therefore, the configuration
change impacts both $date1 and $date2 objects (and any additional
Date::Manip objects created from either of them).

In order to keep things clean, it is highly recommended that the
above example be reordered:

    $date1 = new Date::Manip::Date [$opt1,$val1];
    $date1->config($opt2,$val2);
    $date2 = new Date::Manip::Date $date1,

and all configuration changes be made immediately after (or as close to
it as possible) the creation of the first object.

=head1 MULTIPLE CONFIGURATIONS

Occasionally, it may be useful to have multiple sets of configurations.
In order to do this, multiple Date::Manip::Base objects must be
created (each with their own set of configuration options), and then
new Date::Manip objects are created with the appropriate Date::Manip::Base
object embedded in them.

Possible reasons include:

=over 4

=item Parsing multiple languages

A Date::Manip::Base object includes information about a single
language. If you need to parse dates from two (or more) languages,
a Date::Manip::Base object needs to be created for each one. This
could be done as:

   $date_eng1 = new Date::Manip::Date ["language","English"];
   $date_spa1 = new Date::Manip::Date $date_eng1,["language","Spanish"];

Any additional Date::Manip objects created from the first will work
with English. Additional objects created from the second will work in
Spanish.

=item Business modes for different countries and/or businesses

If you are doing business mode calculations (see Date::Manip::Calc)
for two different businesses which have different holiday lists,
work weeks, or business days, you can create different objects
which read different config files (see Date::Manip::Config) with
the appropriate description of each.

=back

The primary issue when dealing with multiple configurations is
that it is necessary for the programmer to manually keep track of
which Date::Manip objects work with each configuration. For
example, refer to the following lines:

   $date1 = new Date::Manip::Date [$opt1,$val1];
   $date2 = new Date::Manip::Date $date1, [$opt2,$val2];
   $date3 = new Date::Manip::Date $date1;
   $date4 = new Date::Manip::Date $date2;

The first line creates 3 objects (a Date::Manip::Base object, a
Date::Manip::TZ object, and a Date::Manip::Date object). The
Date::Manip::Base object has the configuration set to contain the
value(s) passed in as the final list reference argument.

The second line creates 3 new objects (a second Date::Manip::Base
object, a second Date::Manip::TZ object, and a second
Date::Manip::Date object). Since a list reference containing config
variables is passed in, a new Date::Manip::Base object is created,
rather than reusing the first one. The second Date::Manip::Base object
contains all the config from the first, as well as the config
variables passed in in the list reference argument.

The third line creates another Date::Manip::Date object which uses the
first Date::Manip::Base and Date::Manip::TZ objects embedded in it.

The fourth line creates another Date::Manip::Date object which uses
the second Date::Manip::Base and Date::Manip::TZ objects embedded in
it.

Luckily, most of the time there will only be one set of configuration
options used, so this complexity is really for a very special, and not
widely used, bit of functionality.

=head1 WORKING WITH BOTH HIGH LEVEL AND LOWER LEVEL OBJECTS

If you are working with any higher level Date::Manip modules
(Date::Manip::Date, Date::Manip::Delta, or Date::Manip::Recur), you
probably will not need to work with the lower Date::Manip::Base and
Date::Manip::TZ objects directly.  However, if you want to make use of
some of the faster Date::Manip::Base operations, or work directly with
time zones, you can access the lower level objects using the "base"
and "tz" methods from the higher level object.

More information is in the Date::Manip::Obj manual.

=head1 BUGS AND QUESTIONS

Please refer to the Date::Manip::Problems documentation for
information on submitting bug reports or questions to the author.

=head1 SEE ALSO

Date::Manip        - main module documentation

=head1 LICENSE

This script is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=head1 AUTHOR

Sullivan Beck (sbeck@cpan.org)

=cut
