A new Date.pm to use for all date calculations. Mysql date calculations removed from...
[koha.git] / C4 / Date.pm
1 #!/usr/bin/perl
2 ## written by T Garip 2006-10-10
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 );
47
48 sub get_date_format {
49
50     #Get the database handle
51     my $dbh = C4::Context->dbh;
52     return C4::Context->preference('dateformat');
53 }
54
55 sub display_date_format {
56     my $dateformat = get_date_format();
57
58     if ( $dateformat eq "us" ) {
59         return "mm/dd/yyyy";
60     }
61     elsif ( $dateformat eq "metric" ) {
62         return "dd/mm/yyyy";
63     }
64     elsif ( $dateformat eq "iso" ) {
65         return "yyyy-mm-dd";
66     }
67     else {
68         return
69 "Invalid date format: $dateformat. Please change in system preferences";
70     }
71 }
72
73 sub get_date_format_string_for_DHTMLcalendar {
74     my $dateformat = get_date_format();
75
76     if ( $dateformat eq 'us' ) {
77         return '%m/%d/%Y';
78     }
79     elsif ( $dateformat eq 'metric' ) {
80         return '%d/%m/%Y';
81     }
82     elsif ( $dateformat eq "iso" ) {
83         return '%Y-%m-%d';
84     }
85     else {
86         return 'Invalid date format: '
87           . $dateformat . '.'
88           . ' Please change in system preferences';
89     }
90 }
91
92 sub format_date {
93     my $olddate = shift;
94     my $newdate;
95     if ( !$olddate || $olddate eq "0000-00-00" ) {
96         return "";
97     }
98                 $olddate=~s/-//g;
99                 my $olddate=substr($olddate,0,8);
100     my $dateformat = get_date_format();
101 eval{$newdate =DateTime::Format::ISO8601->parse_datetime($olddate);};
102 if ($@ || !$newdate){
103 ##MARC21 tag 008 has this format YYMMDD
104 my $parser =    DateTime::Format::Strptime->new( pattern => '%y%m%d' );
105         $newdate =$parser->parse_datetime($olddate);
106 }
107 if (!$newdate){
108 return ""; #### some script call format_date more than once --FIX scripts
109 }
110
111     if ( $dateformat eq "us" ) {
112       return $newdate->mdy('/');
113     
114     }
115     elsif ( $dateformat eq "metric" ) {
116         return $newdate->dmy('/');
117     }
118     elsif ( $dateformat eq "iso" ) {
119         return $newdate->ymd;
120     }
121     else {
122         return
123 "Invalid date format: $dateformat. Please change in system preferences";
124     }
125
126 }
127
128 sub format_date_in_iso {
129     my $olddate = shift;
130     my $newdate;
131   my $parser;
132     if ( !$olddate || $olddate eq "0000-00-00" ) {
133         return "";
134     }
135
136 $parser =    DateTime::Format::Strptime->new( pattern => '%d/%m/%Y' );
137         $newdate =$parser->parse_datetime($olddate);
138 if (!$newdate){
139 $parser =    DateTime::Format::Strptime->new( pattern => '%m/%d/%Y' );
140 $newdate =$parser->parse_datetime($olddate);
141 }
142 if (!$newdate){
143  $parser =    DateTime::Format::Strptime->new( pattern => '%Y-%m-%d' );
144 $newdate =$parser->parse_datetime($olddate);
145 }
146  if (!$newdate){
147  $parser =    DateTime::Format::Strptime->new( pattern => '%y-%m-%d' );
148 $newdate =$parser->parse_datetime($olddate);
149 }
150   
151     return $newdate->ymd if $newdate;
152 }
153 sub DATE_diff {
154 ## returns 1 if date1>date2 0 if date1==date2 -1 if date1<date2
155 my ($date1,$date2)=@_;
156 my $dt1=DateTime::Format::ISO8601->parse_datetime($date1);
157 my $dt2=DateTime::Format::ISO8601->parse_datetime($date2);
158 my $diff=DateTime->compare( $dt1, $dt2 );
159 return $diff;
160 }
161 sub DATE_Add {
162 ## $amount in days
163 my ($date,$amount)=@_;
164 my $dt1=DateTime::Format::ISO8601->parse_datetime($date);
165 $dt1->add( days=>$amount );
166 return $dt1->ymd;
167 }
168 sub DATE_Add_Duration {
169 ## Similar as above but uses Duration object as amount --used heavily in serials
170 my ($date,$amount)=@_;
171 my $dt1=DateTime::Format::ISO8601->parse_datetime($date);
172 $dt1->add_duration($amount) ;
173 return $dt1->ymd;
174 }
175 sub get_today{
176 my $dt=DateTime->today;
177 return $dt->ymd;
178 }
179
180 sub DATE_obj{
181 # only send iso dates to this
182 my $date=shift;
183    my $parser =    DateTime::Format::Strptime->new( pattern => '%Y-%m-%d' );
184       my  $newdate =$parser->parse_datetime($date);
185 return $newdate;
186 }
187 sub get_duration{
188 my $period=shift;
189 my $parse;
190 if ($period=~/day/){
191 $parse="\%e days";
192 }elsif ($period=~/week/){
193 $parse="\%W weeks";
194 }elsif ($period=~/year/){
195 $parse="\%Y years";
196 }elsif ($period=~/month/){
197 $parse="\%m months";
198 }
199 my $parser=DateTime::Format::Duration->new(pattern => $parse  );
200         my $duration=$parser->parse_duration($period);
201 return $duration;
202
203 }
204 1;