View | Details | Raw Unified | Return to bug 13601
Collapse All | Expand All

(-)a/Koha/DateUtils.pm (-49 / +97 lines)
Lines 20-26 use strict; Link Here
20
use warnings;
20
use warnings;
21
use 5.010;
21
use 5.010;
22
use DateTime;
22
use DateTime;
23
use DateTime::Format::DateParse;
24
use C4::Context;
23
use C4::Context;
25
24
26
use base 'Exporter';
25
use base 'Exporter';
Lines 54-109 to the system preferences. If the date string is empty DateTime->now is returned Link Here
54
sub dt_from_string {
53
sub dt_from_string {
55
    my ( $date_string, $date_format, $tz ) = @_;
54
    my ( $date_string, $date_format, $tz ) = @_;
56
55
57
    # FIXME: see bug 13242 => no TZ for dates 'infinite'
56
    return if $date_string and $date_string =~ m|^0000-0|;
58
    return DateTime::Format::DateParse->parse_datetime($date_string)
57
59
        if $date_string and $date_string =~ /^9999-/;
58
    $tz = C4::Context->tz unless $tz;;
60
59
61
    my $dt;
60
    return DateTime->now( time_zone => $tz ) unless $date_string;
62
    $tz ||= C4::Context->tz;
61
63
    if ( !$date_format ) {
62
    $date_format = C4::Context->preference('dateformat') unless $date_format;
64
        $date_format = C4::Context->preference('dateformat');
63
65
    }
64
    if ( ref($date_string) eq 'DateTime' ) {    # already a dt return it
66
    if ($date_string) {
65
        return $date_string;
67
        if ( ref($date_string) eq 'DateTime' ) {    # already a dt return it
68
            return $date_string;
69
        }
70
71
        if ( $date_format eq 'metric' ) {
72
            $date_string =~ s#-#/#g;
73
            $date_string =~ s/^00/01/;    # system allows the 0th of the month
74
            $date_string =~ s#^(\d{1,2})/(\d{1,2})#$2/$1#;
75
        } else {
76
            if ( $date_format eq 'iso' ) {
77
                $date_string =~ s/-00/-01/;
78
                if ( $date_string =~ m/^0000-0/ ) {
79
                    return;               # invalid date in db
80
                }
81
            } elsif ( $date_format eq 'us' ) {
82
                $date_string =~ s#-#/#g;
83
                $date_string =~ s[/00/][/01/];
84
            } elsif ( $date_format eq 'sql' ) {
85
                $date_string =~
86
s/(\d{4})(\d{2})(\d{2})\s+(\d{2})(\d{2})(\d{2})/$1-$2-$3T$4:$5:$6/;
87
                return if ($date_string =~ /^0000-00-00/);
88
                $date_string =~ s/00T/01T/;
89
            }
90
        }
91
92
        $dt = eval {
93
            DateTime::Format::DateParse->parse_datetime( $date_string,
94
                $tz->name() );
95
        };
96
        if ($@) {
97
            $tz = DateTime::TimeZone->new( name => 'floating' );
98
            $dt = DateTime::Format::DateParse->parse_datetime( $date_string,
99
                $tz->name() );
100
        }
101
    } else {
102
        $dt = DateTime->now( time_zone => $tz );
103
    }
66
    }
104
67
105
    return $dt;
68
    my $regex;
69
    if ( $date_format eq 'metric' ) {
70
        # metric format is "dd/mm/yyyy[ hh:mm:ss]"
71
        $regex = qr|
72
            (?<day>\d{2})
73
            /
74
            (?<month>\d{2})
75
            /
76
            (?<year>\d{4})
77
        |xms;
78
    }
79
    elsif ( $date_format eq 'us' ) {
80
        # us format is "mm/dd/yyyy[ hh:mm:ss]"
81
        $regex = qr|
82
            (?<month>\d{2})
83
            /
84
            (?<day>\d{2})
85
            /
86
            (?<year>\d{4})
87
        |xms;
88
    }
89
    elsif ( $date_format eq 'iso' or $date_format eq 'sql' ) {
90
        # iso format is yyyy-dd-mm[ hh:mm:ss]"
91
        $regex = qr|
92
            (?<year>\d{4})
93
            -
94
            (?<month>\d{2})
95
            -
96
            (?<day>\d{2})
97
        |xms;
98
    }
99
    else {
100
        die "Invalid dateformat parameter ($date_format)";
101
    }
106
102
103
    # Add the faculative time part [hh:mm[:ss]]
104
    $regex .= qr|
105
            (
106
                \s*
107
                (?<hour>\d{2})
108
                :
109
                (?<minute>\d{2})
110
                (
111
                    :
112
                    (?<second>\d{2})
113
                )?
114
            )?
115
    |xms;
116
117
    my %dt_params;
118
    if ( $date_string =~ $regex ) {
119
        %dt_params = (
120
            year   => $+{year},
121
            month  => $+{month},
122
            day    => $+{day},
123
            hour   => $+{hour},
124
            minute => $+{minute},
125
            second => $+{second},
126
        );
127
    }
128
    else {
129
        die "The given date ($date_string) does not match the date format ($date_format)";
130
    }
131
132
    # system allows the 0th of the month
133
    $dt_params{day} = '01' if $dt_params{day} eq '00';
134
135
    # Set default hh:mm:ss to 00:00:00
136
    $dt_params{hour}   = 00 unless defined $dt_params{hour};
137
    $dt_params{minute} = 00 unless defined $dt_params{minute};
138
    $dt_params{second} = 00 unless defined $dt_params{second};
139
140
    my $dt = eval {
141
        DateTime->new(
142
            %dt_params,
143
            # No TZ for dates 'infinite' => see bug 13242
144
            ( $dt_params{year} < 9999 ? ( time_zone => $tz->name ) : () ),
145
        );
146
    };
147
    if ($@) {
148
        $tz = DateTime::TimeZone->new( name => 'floating' );
149
        $dt = DateTime->new(
150
            %dt_params,
151
            # No TZ for dates 'infinite' => see bug 13242
152
            ( $dt_params{year} < 9999 ? ( time_zone => $tz->name ) : () ),
153
        );
154
    }
155
    return $dt;
107
}
156
}
108
157
109
=head2 output_pref
158
=head2 output_pref
110
- 

Return to bug 13601