Java-JCR
view release on metacpan or search on metacpan
lib/Java/JCR/Calendar.pm view on Meta::CPAN
=over
=item year
This is the year. Use positive values to represent AD/CE years. Use negative values to represent BC/BCE years. (0 is not a valid year and will result in an exception.)
=item month
This is the month of the year. Values must fall within the range of 1 to 12.
Values outside this range will result in an exception unless "lenient" is set to a true value.
=item day
This is the day of the month. Values must fall within the range of 1 to 31, though the upper limit is month dependent.
If you set the value to an invalid day for the given month, an exception will be thrown unless "lenient" is set to a true value.
=item hour
This is the hour of the day. Values must fall within the range of 0 to 23. If not specified, this value will be set to 0.
If you set the value outside this range an exception will be thrown unless "lenient" is set to a true value.
=item minute
This is the minute of the hour. Values must fall within the range of 0 to 59. If not specified, this value will be set to 0.
Values outside this range will cause an exception to be thrown unless "lenient" is set to a true value.
=item second
This is the second of the minute. Values must fall within the range of 0 to 59. If not specified, this value will be set to 0.
Any value given outside of this range will result in an exception unless "lenient" is set to a true value.
=item nanosecond
This is the the nanoseconds within the current second. Values must fall within the range of 0 to 999,999,999. If not specified, this value will be set to 0.
If the value given is outside of this range and exception will be thrown unless "lenient" is set to a true value.
=item timezone
This is the time zone of the date and time. The values available for this may either be numeric offsets from UTC. These offsets can have the following formats:
GMT-6
GMT+10
GMT+230
GMT+10:45
The time zone may also be specified as a named zone (which is usually better because named zones can cope with local rules dealing with Daylight Savings Time and other adjustments---such as new legislation changing DST). However, Java doesn't specify...
Since L<DateTime::TimeZone> uses the Olson database for it's time zones, you may use that as a reference.
If no time zone is specified during deflation, Java will be told to assume the default time zone. The default is generally the local time zone, but may vary depending upon your JVM configuration.
=item locale
I'm not certain if this is actually significant to how the JCR stores a calendar object, but I've included it for completeness (and it doesn't require much in the way of extra effort either way).
The locale must be specified using the ISO-639 and ISO-3166 standards with the possiblity of vendor or browser-specific variant codes. See the Javadoc for C<java.util.Locale> if you want more specific details.
If no locale is specified during deflation, the default Java locale will be used.
=item lenient
By setting this to a true value, the C<java.util.Calendar> object will have the lenient setting set to true. This will allow you to specify month, day, hour, minute, second, and nanosecond values outside the normal range without throwing an exception...
This value defaults to false. Thus, if it isn't given, an exception will be thrown when an out of bounds value is given.
The hash given to the inflation function will always have this value set to false. However, your inflation function may be as lenient or strict as desired. The Calendar implementation on your JVM should return valid dates, so it shouldn't be an issue...
=back
All dates are, obviously, according to the Gregorian calendar, which is due to the fact that the Calendar API of Java only fully supports Gregorian-style calendars. However, since we're using Perl, we're not limited to that calendar. If you want to, ...
The inflation function, C<\&inflater>, can expect a single argument, which is the hash (as described above), containing all the above fields filled. The inflation function must return an object of the specified class, C<$class>, or throw an exception...
During inflation, the hash will be created by reading in the fields set on the C<java.util.Calendar> object returned by the JCR.
The deflation function, C<\&deflater>, can expect a single argument, which is an object blessed into the specified class, C<$class>. The deflation function must return a hash containing the date (as described above). The date fields must be set.
During deflation, a C<java.util.Calendar> object will be created by fetching a Calendar instance according to the time zone and locale specified in the hash returned by the C<\&deflater> function. Then, each field will be set in the following order: ...
=cut
my $default_date_class;
my %date_conversions;
sub register_date_conversion {
my ($class, $date_class, $inflater, $deflater) = @_;
$date_conversions{$date_class} = {
inflater => $inflater,
deflater => $deflater,
};
}
=item Java::JCR::Calendar->default_date_class($class)
Specify the default date class to use when none is specified. This affects any JCR method which returns a date. On any such method, you may specify the date class to use explicitly by using the class name as the last argument to the method. However, ...
The default class name is specified by calling this method and giving it a class name, C<$class>.
If you set the class name, C<$class>, to C<undef>, you are requiring the specification of a date class on any method that returns a date. If no date class is given when the default has been set to C<undef>, an exception will be thrown.
=cut
sub default_date_class {
my ($class, $date_class) = @_;
$default_date_class = $date_class;
}
=back
=cut
sub _perl_date_has_conversion {
my ($date) = @_;
my $class = blessed $date;
return !defined $class ? 0
: defined $date_conversions{$class} ? 1
: 0;
}
sub _perl_date_to_java_calendar {
my ($date) = @_;
my $class = blessed $date;
croak 'Cannot use an unblessed date object' if not defined $class;
croak qq(No Perl-to-Java date conversion is available for "$class")
if not defined $date_conversions{$class};
my $conversion = $date_conversions{$class};
my $deflater = $conversion->{deflater};
return Java::JCR::JavaUtils::hash_to_calendar($deflater->($date));
}
sub _java_calendar_to_perl_date {
my ($calendar, $class) = @_;
$class ||= $default_date_class;
croak 'Cannot convert date from Java to Perl: ',
'No date class was given and no default is available.'
if not defined $class;
croak qq(No Java-to-Perl date conversion is available for "$class")
if not defined $date_conversions{$class};
my $conversion = $date_conversions{$class};
my $inflater = $conversion->{inflater};
return $inflater->(Java::JCR::JavaUtils::calendar_to_hash($calendar));
}
eval 'use DateTime';
if (!$@) {
__PACKAGE__->register_date_conversion(
'DateTime',
sub { # inflater
my ($hash) = @_;
my $time_zone = $hash->{timezone};
$time_zone =~ s/^GMT([-+])/$1/;
return DateTime->new(
year => $hash->{year},
month => $hash->{month},
day => $hash->{day},
hour => $hash->{hour},
minute => $hash->{minute},
second => $hash->{second},
nanosecond => $hash->{nanosecond},
time_zone => $time_zone,
);
},
sub { # deflater
my ($date) = @_;
my $hash = {
year => $date->year,
month => $date->month,
day => $date->day,
hour => $date->hour,
minute => $date->minute,
second => $date->second,
nanosecond => $date->nanosecond,
};
my $tz = $date->time_zone;
if ($tz->is_olson) {
$hash->{timezone} = $tz->name;
}
elsif ($tz->is_utc) {
$hash->{timezone} = 'UTC';
}
elsif (!$tz->is_floating) {
$hash->{timezone}
= 'GMT'.DateTime::TimeZone->offset_as_string(
$tz->offset_for_datetime($date)
);
}
# else floating, let Java use the default
return $hash;
},
);
__PACKAGE__->default_date_class('DateTime');
}
( run in 1.225 second using v1.01-cache-2.11-cpan-39bf76dae61 )