Bug fixing and complete removal of Date::Manip
[koha.git] / C4 / Date.pm
1 #!/usr/bin/perl
2 ## written by T Garip 2006-10-10 tgarip@neu.edu.tr
3 # Copyright 2000-2002 Katipo Communications
4 #
5 # This file is part of Koha.
6 #
7 # Koha is free software; you can redistribute it and/or modify it under the
8 # terms of the GNU General Public License as published by the Free Software
9 # Foundation; either version 2 of the License, or (at your option) any later
10 # version.
11 #
12 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License along with
17 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18 # Suite 330, Boston, MA  02111-1307 USA
19
20 # $Id$
21
22 package C4::Date;
23
24 use strict;
25 use C4::Context;
26 use DateTime;
27 use DateTime::Format::ISO8601;
28 use DateTime::Format::Strptime;
29 use DateTime::Format::Duration;
30
31 require Exporter;
32
33 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
34
35 $VERSION = do { my @v = '$Revision$' =~ /\d+/g; shift(@v) . "." . join( "_", map { sprintf "%03d", $_ } @v ); };
36
37 @ISA = qw(Exporter);
38
39 @EXPORT = qw(
40   &display_date_format
41   &format_date
42   &format_date_in_iso
43   &get_date_format_string_for_DHTMLcalendar
44   &DATE_diff &DATE_Add
45 &get_today &DATE_Add_Duration &DATE_obj &get_duration
46 &DATE_subtract
47 );
48
49 sub get_date_format {
50
51     #Get the database handle
52     my $dbh = C4::Context->dbh;
53     return C4::Context->preference('dateformat');
54 }
55
56 sub display_date_format {
57     my $dateformat = get_date_format();
58
59     if ( $dateformat eq "us" ) {
60         return "mm/dd/yyyy";
61     }
62     elsif ( $dateformat eq "metric" ) {
63         return "dd/mm/yyyy";
64     }
65     elsif ( $dateformat eq "iso" ) {
66         return "yyyy-mm-dd";
67     }
68     else {
69         return
70 "Invalid date format: $dateformat. Please change in system preferences";
71     }
72 }
73
74 sub get_date_format_string_for_DHTMLcalendar {
75     my $dateformat = get_date_format();
76
77     if ( $dateformat eq 'us' ) {
78         return '%m/%d/%Y';
79     }
80     elsif ( $dateformat eq 'metric' ) {
81         return '%d/%m/%Y';
82     }
83     elsif ( $dateformat eq "iso" ) {
84         return '%Y-%m-%d';
85     }
86     else {
87         return 'Invalid date format: '
88           . $dateformat . '.'
89           . ' Please change in system preferences';
90     }
91 }
92
93 sub format_date {
94     my $olddate = shift;
95     my $newdate;
96     if ( !$olddate || $olddate eq "0000-00-00" ) {
97         return "";
98     }
99                 $olddate=~s/-//g;
100                 my $olddate=substr($olddate,0,8);
101     my $dateformat = get_date_format();
102 eval{$newdate =DateTime::Format::ISO8601->parse_datetime($olddate);};
103 if ($@ || !$newdate){
104 ##MARC21 tag 008 has this format YYMMDD
105 my $parser =    DateTime::Format::Strptime->new( pattern => '%y%m%d' );
106         $newdate =$parser->parse_datetime($olddate);
107 }
108 if (!$newdate){
109 return ""; #### some script call format_date more than once --FIX scripts
110 }
111
112     if ( $dateformat eq "us" ) {
113       return $newdate->mdy('/');
114     
115     }
116     elsif ( $dateformat eq "metric" ) {
117         return $newdate->dmy('/');
118     }
119     elsif ( $dateformat eq "iso" ) {
120         return $newdate->ymd;
121     }
122     else {
123         return
124 "Invalid date format: $dateformat. Please change in system preferences";
125     }
126
127 }
128
129 sub format_date_in_iso {
130     my $olddate = shift;
131     my $newdate;
132   my $parser;
133     if ( !$olddate || $olddate eq "0000-00-00" ) {
134         return "";
135     }
136
137 $parser =    DateTime::Format::Strptime->new( pattern => '%d/%m/%Y' );
138         $newdate =$parser->parse_datetime($olddate);
139 if (!$newdate){
140 $parser =    DateTime::Format::Strptime->new( pattern => '%m/%d/%Y' );
141 $newdate =$parser->parse_datetime($olddate);
142 }
143 if (!$newdate){
144  $parser =    DateTime::Format::Strptime->new( pattern => '%Y-%m-%d' );
145 $newdate =$parser->parse_datetime($olddate);
146 }
147  if (!$newdate){
148  $parser =    DateTime::Format::Strptime->new( pattern => '%y-%m-%d' );
149 $newdate =$parser->parse_datetime($olddate);
150 }
151   
152     return $newdate->ymd if $newdate;
153 }
154 sub DATE_diff {
155 ## returns 1 if date1>date2 0 if date1==date2 -1 if date1<date2
156 my ($date1,$date2)=@_;
157 my $dt1=DateTime::Format::ISO8601->parse_datetime($date1);
158 my $dt2=DateTime::Format::ISO8601->parse_datetime($date2);
159 my $diff=DateTime->compare( $dt1, $dt2 );
160 return $diff;
161 }
162 sub DATE_Add {
163 ## $amount in days
164 my ($date,$amount)=@_;
165 my $dt1=DateTime::Format::ISO8601->parse_datetime($date);
166 $dt1->add( days=>$amount );
167 return $dt1->ymd;
168 }
169 sub DATE_Add_Duration {
170 ## Similar as above but uses Duration object as amount --used heavily in serials
171 my ($date,$amount)=@_;
172 my $dt1=DateTime::Format::ISO8601->parse_datetime($date);
173 $dt1->add_duration($amount) ;
174 return $dt1->ymd;
175 }
176 sub get_today{
177 my $dt=DateTime->today;
178 return $dt->ymd;
179 }
180
181 sub DATE_obj{
182 # only send iso dates to this
183 my $date=shift;
184    my $parser =    DateTime::Format::Strptime->new( pattern => '%Y-%m-%d' );
185       my  $newdate =$parser->parse_datetime($date);
186 return $newdate;
187 }
188 sub get_duration{
189 my $period=shift;
190 my $parse;
191 if ($period=~/day/){
192 $parse="\%e days";
193 }elsif ($period=~/week/){
194 $parse="\%W weeks";
195 }elsif ($period=~/year/){
196 $parse="\%Y years";
197 }elsif ($period=~/month/){
198 $parse="\%m months";
199 }
200 my $parser=DateTime::Format::Duration->new(pattern => $parse  );
201         my $duration=$parser->parse_duration($period);
202 return $duration;
203
204 }
205 sub DATE_subtract{
206 my ($date1,$date2)=@_;
207 my $dt1=DateTime::Format::ISO8601->parse_datetime($date1);
208 my $dt2=DateTime::Format::ISO8601->parse_datetime($date2);
209 my $dur=$dt2->subtract_datetime_absolute($dt1);## in seconds
210 my $days=$dur->seconds/(60*60*24);
211 return int($days);
212 }
213 1;