1########################################################################## 2# 3# File: Project/Gantt/DateUtils.pm 4# 5# Author: Alexander Westholm 6# 7# Purpose: Collection of utility functions for manipulating 8# Class::Date objects. Contains functions for getting the 9# number of hours/days/months between two dates, getting 10# the end and beginning of hours/days/months, and looking 11# up the string name of a day of the week or month. 12# 13# Client: CPAN 14# 15# CVS: $Id: DateUtils.pm,v 1.4 2004/08/03 17:56:52 awestholm Exp $ 16# 17########################################################################## 18package Project::Gantt::DateUtils; 19use strict; 20use warnings; 21use Exporter (); 22use vars qw[@EXPORT_OK %EXPORT_TAGS @ISA]; 23 24@ISA = qw[Exporter]; 25 26@EXPORT_OK = qw[hourBegin 27 hourEnd 28 dayBegin 29 dayEnd 30 monthBegin 31 monthEnd 32 getMonth 33 getDay 34 monthsBetween 35 hoursBetween 36 daysBetween 37 ]; 38 39%EXPORT_TAGS = ( 40 compare => [qw( 41 monthsBetween 42 daysBetween 43 hoursBetween)], 44 round => [qw( 45 hourEnd 46 hourBegin 47 dayEnd 48 dayBegin 49 monthEnd 50 monthBegin)], 51 lookup => [qw( 52 getDay 53 getMonth)] ); 54 55########################################################################## 56# 57# Function: monthsBetween(date1, date2) 58# 59# Purpose: Calculates the number of months spanned by two dates. 60# This is inclusive of the rest of the months. 61# 62########################################################################## 63sub monthsBetween { 64 my $date1 = shift; 65 my $date2 = shift; 66 67 # Peter Weatherdon Jan 25, 2005 68 # Used new monthEarly and monthLate functions instead of monthBegin and 69 # monthEnd because Class::Date has some problems calculating date 70 # differences at the boundaries. For example if date1=2005-01-31 23:59:59 71 # and date2=2005-12-01 01:00:00 then the difference in months is 72 # 9.95640678332187 instead of the expected 10 plus a bit. 73 $date1 = monthEarly($date1); 74 $date2 = monthLate($date2); 75 my $rough = ($date2-$date1)->month; 76 return int($rough)+1; 77} 78 79########################################################################## 80# 81# Function: daysBetween(date1, date2) 82# 83# Purpose: Inclusive calculation of the number of days between two 84# Class::Date objects. 85# 86########################################################################## 87sub daysBetween { 88 my $date1 = shift; 89 my $date2 = shift; 90 $date1 = dayEnd($date1); 91 $date2 = dayBegin($date2); 92 my $rough = int(($date2-$date1)->day); 93 return $rough+2; 94} 95 96########################################################################## 97# 98# Function: hoursBetween(date1, date2) 99# 100# Purpose: Inclusive calculation of the number of hours between two 101# Class::Date objects. 102# 103########################################################################## 104sub hoursBetween { 105 my $date1 = shift; 106 my $date2 = shift; 107 $date1 = hourEnd($date1); 108 $date2 = hourBegin($date2); 109 my $rough = int(($date2-$date1)->hour); 110 return $rough+2; 111} 112 113########################################################################## 114# 115# Function: hourBegin(date) 116# 117# Purpose: Returns the date object, reset to the beginning of the 118# hour. 119# 120########################################################################## 121sub hourBegin { 122 my $date = shift; 123 $date -= ($date->min() - 1)."m" if $date->min > 0; 124 $date -= ($date->sec() - 1)."s" if $date->sec > 0; 125 return $date; 126} 127 128########################################################################## 129# 130# Function: hourEnd(date) 131# 132# Purpose: Returns the date object, reset to the end of the hour. 133# 134########################################################################## 135sub hourEnd { 136 my $date = shift; 137 $date += (59 - $date->min)."m" if $date->min < 59; 138 $date += (59 - $date->sec)."s" if $date->sec < 59; 139 return $date; 140} 141 142########################################################################## 143# 144# Function: dayBegin(date) 145# 146# Purpose: Returns the date object, reset to the beginning of the 147# day. 148# 149########################################################################## 150sub dayBegin { 151 my $date = shift; 152 $date -= ($date->hour() - 1)."h" if $date->hour > 0; 153 $date = hourBegin($date); 154 return $date; 155} 156 157########################################################################## 158# 159# Function: dayEnd(date) 160# 161# Purpose: Returns the date object, reset to the end of the day. 162# 163########################################################################## 164sub dayEnd { 165 my $date = shift; 166 $date += (23 - $date->hour)."h" if $date->hour < 23; 167 $date = hourEnd($date); 168 return $date; 169} 170 171########################################################################## 172# 173# Function: monthBegin(date) 174# 175# Purpose: Returns the date, reset to the beginning of the month. 176# Differs from similar function provided by Class::Date by 177# going to the very beginning of the month, and not just 178# the first day along with whatever hour was origionally 179# used. 180# 181########################################################################## 182sub monthBegin { 183 my $date= shift; 184 $date = $date->month_begin(); 185 $date = dayBegin($date); 186 return $date; 187} 188 189########################################################################## 190# 191# Function: monthEnd(date) 192# 193# Purpose: Returns the date, reset to the end of the month. Similar 194# Differs from the function provided by Class::Date in a 195# similar manner to the function above. 196# 197########################################################################## 198sub monthEnd { 199 my $date= shift; 200 $date = $date->month_end(); 201 $date = dayEnd($date); 202 return $date; 203} 204 205 206########################################################################## 207# 208# Function: monthEarly(date) 209# 210# Author: Peter Weatherdon 211# 212# Purpose: Returns the date, reset to the 5th of the month. 213# 214########################################################################## 215sub monthEarly { 216 my $date = shift; 217 return new Class::Date ($date->year . "-" . $date->month . "-" . "05"); 218} 219 220 221########################################################################## 222# 223# Function: monthLate(date) 224# 225# Author: Peter Weatherdon 226# 227# Purpose: Returns the date, reset to the 25th of the month. 228# 229########################################################################## 230sub monthLate { 231 my $date = shift; 232 return new Class::Date ($date->year . "-" . $date->month . "-" . "25"); 233} 234 235########################################################################## 236# 237# Function: getDay(date) 238# 239# Purpose: Returns the string representation of the day of the week 240# for the date passed in. 241# 242########################################################################## 243sub getDay { 244 my $day = shift; 245 my @days; 246 $days[1] = 'Sunday'; 247 $days[2] = 'Monday'; 248 $days[3] = 'Tuesday'; 249 $days[4] = 'Wednesday'; 250 $days[5] = 'Thursday'; 251 $days[6] = 'Friday'; 252 $days[7] = 'Saturday'; 253 return $days[$day]; 254} 255 256########################################################################## 257# 258# Function: getMonth(date) 259# 260# Purpose: Returns the string representation of the month for the 261# date passed in. 262# 263########################################################################## 264sub getMonth { 265 my $month = shift; 266 my @months; 267 $months[1] = 'January'; 268 $months[2] = 'February'; 269 $months[3] = 'March'; 270 $months[4] = 'April'; 271 $months[5] = 'May'; 272 $months[6] = 'June'; 273 $months[7] = 'July'; 274 $months[8] = 'August'; 275 $months[9] = 'September'; 276 $months[10] = 'October'; 277 $months[11] = 'November'; 278 $months[12] = 'December'; 279 return $months[$month]; 280} 281 2821; 283