###################################################################################
#
# Embperl - Copyright (c) 1997-2008 Gerald Richter / ecos gmbh www.ecos.de
# Embperl - Copyright (c) 2008-2014 Gerald Richter
#
# You may distribute under the terms of either the GNU General Public
# License or the Artistic License, as specified in the Perl README file.
#
# THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# $Id$
#
###################################################################################
package Embperl::Form::Control::datetime ;
use strict ;
use base 'Embperl::Form::Control::number' ;
use Embperl::Inline ;
use POSIX qw(strftime);
use Time::Local qw(timelocal_nocheck timegm_nocheck);
use Date::Calc qw{Delta_DHMS Add_Delta_Days} ;
use vars qw{%fdat} ;
our $tz_local = (timegm_nocheck(localtime())-time())/60;
# ---------------------------------------------------------------------------
#
# init - init the new control
#
sub init
{
my ($self) = @_ ;
$self->{unit} ||= '' ;
return $self ;
}
# ------------------------------------------------------------------------------------------
#
# init_data - daten aufteilen
#
sub init_data
{
my ($self, $req, $parentctrl, $force) = @_ ;
my $fdat = $req -> {docdata} || \%fdat ;
my $name = $self->{name} ;
my $time = $fdat->{$name} ;
return if ($time eq '' || ($req -> {"ef_datetime_init_done_$name"} && !$force)) ;
if ($self -> {dynamic} && ($time =~ /^\s*((?:d|m|y|q)(?:\+|-)?(?:\d+)?)\s*$/))
{
$fdat->{$name} = $1 ;
$req -> {"ef_datetime_init_done_$name"} = 1 ;
return ;
}
my ($y, $m, $d, $h, $min, $s, $z) = ($time =~ /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(.)/) ;
# Getting the local timezone
my $date = eval
{
my @time = gmtime(timegm_nocheck($s,$min,$h,$d,$m-1,$y-1900)+($tz_local*60));
my $format = $self -> {notime} || ($s == 0 && $h == 0 && $min == 0)?'%d.%m.%Y':'%d.%m.%Y, %H:%M' ;
strftime ($format, @time[0..5]) ;
} ;
if ($time && !$date && ($time =~ /\d+\.\d+\.\d+/))
{
$date = $time ;
}
$fdat->{$name} = $date ;
$req -> {"ef_datetime_init_done_$name"} = 1 ;
}
# ------------------------------------------------------------------------------------------
#
# prepare_fdat - daten zusammenfuehren
#
sub prepare_fdat
{
my ($self, $req) = @_ ;
return if ($self -> is_readonly ($req)) ;
my $fdat = $req -> {form} || \%fdat ;
my $name = $self->{name} ;
my $date = $fdat -> {$name} ;
return if ($date eq '') ;
if ($self -> {dynamic} && ($date =~ /^\s*((?:d|m|y|q)\s*(?:\+|-)?\s*(?:\d+)?)\s*$/))
{
$fdat->{$name} = $1 ;
$fdat->{$name} =~ s/\s//g ;
return ;
}
my ($year, $mon, $day, $hour, $min, $sec) ;
if ($date eq '*' || $date eq '.')
{
my $offset ||= 0 ;
($sec, $min, $hour, $day, $mon, $year) = gmtime (time + $offset) ;
$year += 1900 ;
$mon++ ;
}
else
{
$date =~ tr/,;/ / ;
my ($d, $t) = split (/\s+/, $date) ;
if ($d =~ /:/)
{
$t = $d ;
$d = '' ;
}
($day, $mon, $year) = map { $_ + 0 } split (/\./, $d) ;
($hour, $min, $sec) = map { $_ + 0 } split (/\:/, $t) ;
if ($year == 0 || $mon == 0 || $day == 0)
{
my ($s, $min, $h, $md, $m, $y) = localtime ;
$day ||= $md ;
$mon ||= $m + 1;
$year ||= $y + 1900 ;
}
if ($year < 70)
{
$year += 2000 ;
}
elsif ($year >= 70 && $year < 100)
{
$year += 1900 ;
}
if ($year < 1907)
{
$year = $year % 100 + 2000 ;
}
($year,$mon,$day, $hour,$min,$sec) =
Date::Calc::Add_Delta_DHMS($year,$mon,$day, $hour,$min,$sec,
0, 0, -$tz_local, 0) if ($hour || $min || $sec) ;
}
$fdat -> {$name} = $year?sprintf ('%04d%02d%02d%02d%02d%02dZ', $year, $mon, $day, $hour, $min, $sec):'' ;
}
# ---------------------------------------------------------------------------
#
# get_validate_auto_rules - get rules for validation, in case user did
# not specify any
#
sub get_validate_auto_rules
{
my ($self, $req) = @_ ;
return [ $self -> {required}?(required => 1):(emptyok => 1), -type => 'DateTime' ] ;
}
1 ;
__EMBPERL__
[# ---------------------------------------------------------------------------
#
# show_control - output the control
#]
[$ sub show_control ($self)
$self -> {size} ||= 80 / ($self -> {width} || 2) ;
my $class = $self -> {class} ||= '' ;
my $fullid = $req -> {uuid} . '_' . $self ->{id} ;
$]
get_std_control_attr($req, $fullid) } +]
[$if $self -> {size} $]size="[+ $self->{size} +]"[$endif$]
[$if $self -> {maxlength} $]maxlength="[+ $self->{maxlength} +]"[$endif$]
_ef_attach="ef_datetime" _ef_dynamic="[+ $self -> {dynamic}?'true':'' +]"
>
[#
#]
[$endsub$]
__END__
=pod
=head1 NAME
Embperl::Form::Control::price - A price input control with optional unit inside an Embperl Form
=head1 SYNOPSIS
{
type => 'price',
text => 'blabla',
name => 'foo',
unit => 'sec',
}
=head1 DESCRIPTION
Used to create a datetime input control inside an Embperl Form.
Will format number as a date/time.
See Embperl::Form on how to specify parameters.
Datetime format in %fdat is excpected as YYYYMMTTHHMMSSZ
=head2 PARAMETER
=head3 type
Needs to be 'datetime'
=head3 name
Specifies the name of the control
=head3 text
Will be used as label for the numeric input control
=head3 size
Gives the size in characters. (Default: 10)
=head3 notime
does not display time
=head3 dynamic
allows the following values to be entered:
d, m, y, d-N, d+N, m-N, m+N, y-N, y+N
N is any number. This values are simply passed through and need
to be process somewhere else.
=head1 Author
G. Richter (richter at embperl dot org)
=head1 See Also
perl(1), Embperl, Embperl::Form