Astro-App-Satpass2
view release on metacpan or search on metacpan
lib/Astro/App/Satpass2/FormatTime/DateTime.pm view on Meta::CPAN
$self->{_tz_obj} and return $self->{_tz_obj};
my $tz = $self->tz();
if ( defined $tz && $tz ne '' ) {
return ( $self->{_tz_obj} = DateTime::TimeZone->new(
name => $tz ) );
} else {
return ( $self->{_tz_obj} = $zone_local ||=
DateTime::TimeZone->new( name => 'local' ) );
}
}
}
sub __format_datetime_width_adjust_object {
my ( $self, $obj, $name, $val, $gmt ) = @_;
if ( $obj ) {
$obj->set( $name => $val );
} else {
my ( $class, $dt_arg ) = $self->_dt_class_and_args();
$obj = $class->new(
time_zone => $self->_get_zone( $gmt ),
locale => scalar __preferred(),
$name => $val,
( 'year' eq $name ? () : ( year => 2020 ) ),
@{ $dt_arg },
);
}
return $obj;
}
# my $mod_fmt = $self->__preprocess_strftime_format( $dt_obj, $fmt )
# Preprocess out all the extensions to the strftime format.
# What we're handling here is things of the form %{name:modifiers},
# where the colon and modifiers are optional.
# The modifier is a series of single-character flags followed by a field
# width. The flags are:
# '-' - left-justify
# '0' - zero-pad (ineffective if '-' specified)
# 't' - truncate to field width
sub __preprocess_strftime_format {
my ( $self, $dt_obj, $fmt ) = @_;
caller->isa( __PACKAGE__ )
or $self->weep(
'__preprocess_strftime_format() is private to Astro-App-Satpass2' );
$fmt =~ s< ( % [{] ( \w+ | % ) (?: : ( [-0t]* ) ( [0-9]+ ) )? [}] ) >
< _expand_strftime_format( $dt_obj, $1, $2, $3, $4 ) >smxge;
return $fmt;
}
use constant CALENDAR_GREGORIAN => 'Gregorian';
use constant CALENDAR_JULIAN => 'Julian';
{
my %special = (
'%' => sub { return '%' },
calendar_name => sub {
my ( $dt_obj ) = @_;
my $code;
$code = $dt_obj->can( 'calendar_name' )
and return $code->( $dt_obj );
$code = $dt_obj->can( 'is_julian' )
and return $code->( $dt_obj ) ?
CALENDAR_JULIAN :
CALENDAR_GREGORIAN;
( ref $dt_obj ) =~ m/ \A DateTime:: (?: \w+ :: )* ( \w+ ) \z /smx
and return "$1";
return CALENDAR_GREGORIAN;
},
);
sub _expand_strftime_format {
my ( $dt_obj, $all, $name, $flags, $width ) = @_;
my $code = $special{$name} || $dt_obj->can( $name )
or return $all;
my $rslt = $code->( $dt_obj );
my %flg = map { $_ => 1 } split qr{}, defined $flags ? $flags : '';
if ( $width ) {
my $tplt = '%';
foreach my $f ( qw{ - 0 } ) {
$flg{$f}
and $tplt .= $f;
}
$tplt .= '*s';
$rslt = sprintf $tplt, $width, $rslt;
$flg{t}
and length $rslt > $width
and substr $rslt, $width, length $rslt, '';
}
return $rslt;
}
}
sub __back_end_default {
my ( undef, $cls ) = @_; # Invocant ($self) unused
return defined $cls ? $cls : 'DateTime';
}
sub __back_end_validate {
my ( undef, $cls, @arg ) = @_; # Invocant ($self) unused
$cls->now( @arg );
return;
}
1;
__END__
=head1 NAME
Astro::App::Satpass2::FormatTime::DateTime - Format time using DateTime
=head1 SYNOPSIS
None. All externally-available functionality is provided by either the
superclass or one of the subclasses.
=head1 NOTICE
This class and its subclasses are private to the
lib/Astro/App/Satpass2/FormatTime/DateTime.pm view on Meta::CPAN
These are public unless otherwise stated in the documentation of the
individual method. As a guide, you should expect methods whose name
begins with a double underscore to be private to the
C<Astro-App-Satpass2> package.
=head2 back_end
$self->back_end( 'DateTime::Calendar::Christian' );
$self->back_end( 'Christian' );
$self->back_end( 'Christian,reform_date=uk' );
$self->back_end( 'Christian', reform_date => 'uk' );
my $back_end = $self->back_end();
my ( $class, @arg ) = $self->back_end();
This method acts as both accessor and mutator for the back end class
that does all the actual time formatting.
When called with arguments it is a mutator, setting the name of the back
end class, and any arguments that need to be passed to its C<new()>
method. The class specified should conform to the L<DateTime|DateTime>
interface. If the class name begins with C<'DateTime::Calendar::'>, this
can be omitted as in the second example above. Arguments can be
specified as comma-delimited C<'name=value'> pairs, as in the third
example, or as separate name/value arguments, as in the fourth example.
When called with no arguments this method is an accessor. If called in
list context it returns the class name and argument/value pairs as
separate items. If called in scalar context the arguments are
concatenated to the class name as comma-delimited C<'name=value'> pairs.
=head2 __preprocess_strftime_format
my $mod = $self->__preprocess_strftime_format( $dt_obj, $fmt );
The functionality documented below is supported, but B<this method is
not,> and may be changed or revoked without notice at any time. This
method will in fact throw an exception unless called from a subclass of
this class.
This package-private method pre-processes a format, finding and
potentially replacing substrings that look like C<'%{name:modifiers}'>.
This is a further extension of the L<DateTime|DateTime> extension,
providing more control of the output.
The arguments are a L<DateTime|DateTime> or C<DateTime-ish> object and
the format that is to be pre-processed. The return is the pre-processed
format.
In the substrings that are (potentially) replaced, the C<'name'>
represents either a special-case string or the name of a method on the
C<$dt_obj> object. If it is neither, the substring is left unmodified.
The special-case names are:
=over
=item %
This causes a literal C<'%'> to be inserted.
=item calendar_name
This causes either C<'Gregorian'> or C<'Julian'> to be inserted. You get
C<'Julian'> only if C<$dt_obj> has an C<is_julian()> method, and that
method returns a true value. Otherwise, if the class name of the back
end object begins with C<'DateTime::Calendar::'> you get the shortened
name. Otherwise you get C<'Gregorian'>. There is no provision for
localization, unfortunately.
=back
The colon and modifiers are optional. If present, the modifiers consist
of, in order:
=over
=item zero or more single-character flags;
These modify the formatting of the value, and may appear in any order.
The following flags are implemented:
=over
=item * C<'-'>
This flag causes the output to be left-justified in its field. It is
only effective if the field width (see below) is positive.
=item * C<'0'>
This flag causes the output to be zero-filled on the left. It is only
effective if the field width (see below) is positive, and C<'-'> is not
specified.
=item * C<'t'>
This flag causes the output to be truncated on the right to the field
width (see below). It is only effective if the field width is positive.
=back
=item a field width.
This is a non-negative integer, not beginning with zero, which specifies
the width of the output. Output will be at least this width, but may be
wider unless the C<'t'> flag was specified.
=back
For example, if the C<$dt_obj> represents the Ides of March, 44 BC, and
the template is C<'%{year_with_christian_era:06}-%m-%d'>, the returned
value will be C<'0044BC-%m-%d'>.
$dt_obj->strftime(
$self->__preprocess_strftime_format(
$dt_obj, '%{year_with_christian_era:06}-%m-%d' ) );
would therefore produce C<'0044BC-03-15'>.
=head1 SUPPORT
( run in 1.329 second using v1.01-cache-2.11-cpan-39bf76dae61 )