| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Labyrinth::DTUtils; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 7 |  |  | 7 |  | 15849 | use warnings; | 
|  | 7 |  |  |  |  | 8 |  | 
|  | 7 |  |  |  |  | 219 |  | 
| 4 | 7 |  |  | 7 |  | 24 | use strict; | 
|  | 7 |  |  |  |  | 8 |  | 
|  | 7 |  |  |  |  | 188 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 | 7 |  |  | 7 |  | 22 | use vars qw($VERSION @ISA %EXPORT_TAGS @EXPORT @EXPORT_OK); | 
|  | 7 |  |  |  |  | 7 |  | 
|  | 7 |  |  |  |  | 797 |  | 
| 7 |  |  |  |  |  |  | $VERSION = '5.31'; | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | =head1 NAME | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | Labyrinth::DTUtils - Date & Time Utilities for Labyrinth | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | use Labyrinth::DTUtils; | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | Various date & time utilities. | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | =head1 EXPORT | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | everything | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | =cut | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | # ------------------------------------- | 
| 28 |  |  |  |  |  |  | # Export Details | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | require Exporter; | 
| 31 |  |  |  |  |  |  | @ISA = qw(Exporter); | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | %EXPORT_TAGS = ( | 
| 34 |  |  |  |  |  |  | 'all' => [ qw( | 
| 35 |  |  |  |  |  |  | DaySelect MonthSelect YearSelect PeriodSelect | 
| 36 |  |  |  |  |  |  | formatDate unformatDate isMonth | 
| 37 |  |  |  |  |  |  | ) ] | 
| 38 |  |  |  |  |  |  | ); | 
| 39 |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  | @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); | 
| 41 |  |  |  |  |  |  | @EXPORT    = ( @{ $EXPORT_TAGS{'all'} } ); | 
| 42 |  |  |  |  |  |  |  | 
| 43 |  |  |  |  |  |  | ############################################################################# | 
| 44 |  |  |  |  |  |  | #Libraries | 
| 45 |  |  |  |  |  |  | ############################################################################# | 
| 46 |  |  |  |  |  |  |  | 
| 47 | 7 |  |  | 7 |  | 5487 | use DateTime; | 
|  | 7 |  |  |  |  | 739917 |  | 
|  | 7 |  |  |  |  | 244 |  | 
| 48 | 7 |  |  | 7 |  | 3492 | use Time::Local; | 
|  | 7 |  |  |  |  | 9148 |  | 
|  | 7 |  |  |  |  | 388 |  | 
| 49 | 7 |  |  | 7 |  | 360 | use Labyrinth::Audit; | 
|  | 7 |  |  |  |  | 14 |  | 
|  | 7 |  |  |  |  | 999 |  | 
| 50 | 7 |  |  | 7 |  | 3510 | use Labyrinth::MLUtils; | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | use Labyrinth::Variables; | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | ############################################################################# | 
| 54 |  |  |  |  |  |  | #Variables | 
| 55 |  |  |  |  |  |  | ############################################################################# | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | my @months = ( | 
| 58 |  |  |  |  |  |  | { 'id' =>  1,   'value' => "January",   }, | 
| 59 |  |  |  |  |  |  | { 'id' =>  2,   'value' => "February",  }, | 
| 60 |  |  |  |  |  |  | { 'id' =>  3,   'value' => "March",     }, | 
| 61 |  |  |  |  |  |  | { 'id' =>  4,   'value' => "April",     }, | 
| 62 |  |  |  |  |  |  | { 'id' =>  5,   'value' => "May",       }, | 
| 63 |  |  |  |  |  |  | { 'id' =>  6,   'value' => "June",      }, | 
| 64 |  |  |  |  |  |  | { 'id' =>  7,   'value' => "July",      }, | 
| 65 |  |  |  |  |  |  | { 'id' =>  8,   'value' => "August",    }, | 
| 66 |  |  |  |  |  |  | { 'id' =>  9,   'value' => "September", }, | 
| 67 |  |  |  |  |  |  | { 'id' => 10,   'value' => "October",   }, | 
| 68 |  |  |  |  |  |  | { 'id' => 11,   'value' => "November",  }, | 
| 69 |  |  |  |  |  |  | { 'id' => 12,   'value' => "December"   }, | 
| 70 |  |  |  |  |  |  | ); | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | my @dotw = (    "Sunday", "Monday", "Tuesday", "Wednesday", | 
| 73 |  |  |  |  |  |  | "Thursday", "Friday", "Saturday" ); | 
| 74 |  |  |  |  |  |  |  | 
| 75 |  |  |  |  |  |  | my @days = map {{'id'=>$_,'value'=> $_}} (1..31); | 
| 76 |  |  |  |  |  |  | my @periods = ( | 
| 77 |  |  |  |  |  |  | {act => 'evnt-month', value => 'Month'}, | 
| 78 |  |  |  |  |  |  | {act => 'evnt-week',  value => 'Week'}, | 
| 79 |  |  |  |  |  |  | {act => 'evnt-day',   value => 'Day'} | 
| 80 |  |  |  |  |  |  | ); | 
| 81 |  |  |  |  |  |  |  | 
| 82 |  |  |  |  |  |  | my %formats = ( | 
| 83 |  |  |  |  |  |  | 1 => 'YYYY', | 
| 84 |  |  |  |  |  |  | 2 => 'MONTH YYYY', | 
| 85 |  |  |  |  |  |  | 3 => 'DD/MM/YYYY', | 
| 86 |  |  |  |  |  |  | 4 => 'DABV MABV DD TIME24 YYYY', | 
| 87 |  |  |  |  |  |  | 5 => 'DAY, DD MONTH YYYY', | 
| 88 |  |  |  |  |  |  | 6 => 'DAY, DDEXT MONTH YYYY', | 
| 89 |  |  |  |  |  |  | 7 => 'DAY, DD MONTH YYYY (TIME12)', | 
| 90 |  |  |  |  |  |  | 8 => 'DAY, DDEXT MONTH YYYY (TIME12)', | 
| 91 |  |  |  |  |  |  | 9 => 'YYYY/MM/DD', | 
| 92 |  |  |  |  |  |  | 10 => 'DDEXT MONTH YYYY', | 
| 93 |  |  |  |  |  |  | 11 => 'YYYYMMDDThhmmss',        # iCal date string | 
| 94 |  |  |  |  |  |  | 12 => 'YYYY-MM-DDThh:mm:ssZ',   # RSS date string | 
| 95 |  |  |  |  |  |  | 13 => 'YYYYMMDD',               # backwards date | 
| 96 |  |  |  |  |  |  | 14 => 'DABV, DDEXT MONTH YYYY', | 
| 97 |  |  |  |  |  |  | 15 => 'DD MABV YYYY', | 
| 98 |  |  |  |  |  |  | 16 => 'DABV, dd MABV YYYY hh:mm:ss TZ', # RFC-822 date string | 
| 99 |  |  |  |  |  |  | 17 => 'DAY, DD MONTH YYYY hh:mm:ss', | 
| 100 |  |  |  |  |  |  | 18 => 'DD/MM/YYYY hh:mm:ss', | 
| 101 |  |  |  |  |  |  | 19 => 'DDEXT MONTH YYYY', | 
| 102 |  |  |  |  |  |  | 20 => 'DABV, DD MABV YYYY hh:mm:ss', | 
| 103 |  |  |  |  |  |  | 21 => 'YYYY-MM-DD hh:mm:ss', | 
| 104 |  |  |  |  |  |  | 22 => 'YYYYMMDDhhmm', | 
| 105 |  |  |  |  |  |  | ); | 
| 106 |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  | my %unformats = ( | 
| 108 |  |  |  |  |  |  | 11 => '(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})',        # iCal date string | 
| 109 |  |  |  |  |  |  | 12 => '(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z',   # ISO 8601 date string | 
| 110 |  |  |  |  |  |  | 13 => '(\d{4})(\d{2})(\d{2})',                              # backwards date | 
| 111 |  |  |  |  |  |  | 22 => '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})', | 
| 112 |  |  |  |  |  |  | ); | 
| 113 |  |  |  |  |  |  |  | 
| 114 |  |  |  |  |  |  | # decrees whether the date format above should be UTC | 
| 115 |  |  |  |  |  |  | # time based, or allow for any Summer Time variations. | 
| 116 |  |  |  |  |  |  | my %zonetime = (12 => 1, 16 => 1); | 
| 117 |  |  |  |  |  |  |  | 
| 118 |  |  |  |  |  |  | ############################################################################# | 
| 119 |  |  |  |  |  |  | #Subroutines | 
| 120 |  |  |  |  |  |  | ############################################################################# | 
| 121 |  |  |  |  |  |  |  | 
| 122 |  |  |  |  |  |  | =head1 FUNCTIONS | 
| 123 |  |  |  |  |  |  |  | 
| 124 |  |  |  |  |  |  | =head2 Dropdown Boxes | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | =over 4 | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | =item DaySelect($opt,$blank) | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | Provides a Day dropdown selection box. | 
| 131 |  |  |  |  |  |  |  | 
| 132 |  |  |  |  |  |  | The option $opt allows the given day (numerical 1 - 31) to be the selected | 
| 133 |  |  |  |  |  |  | option in the dropdown. If blank is true, a 'Select Day' option is added as | 
| 134 |  |  |  |  |  |  | the first option to the dropdown. | 
| 135 |  |  |  |  |  |  |  | 
| 136 |  |  |  |  |  |  | =item MonthSelect($opt,$blank) | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  | Provides a Month dropdown selection box. | 
| 139 |  |  |  |  |  |  |  | 
| 140 |  |  |  |  |  |  | The option $opt allows the given month (numerical 1 - 12) to be the selected | 
| 141 |  |  |  |  |  |  | option in the dropdown. If blank is true, a 'Select Month' option is added as | 
| 142 |  |  |  |  |  |  | the first option to the dropdown. | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | =item YearSelect($opt,$range,$blank,$dates) | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | Provides a Year dropdown selection box. | 
| 147 |  |  |  |  |  |  |  | 
| 148 |  |  |  |  |  |  | The option $opt allows the given month (numerical 1 - 12) to be the selected | 
| 149 |  |  |  |  |  |  | option in the dropdown. If blank is true, a 'Select Month' option is added as | 
| 150 |  |  |  |  |  |  | the first option to the dropdown. | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | If is specified, then the following criteria is used: | 
| 153 |  |  |  |  |  |  |  | 
| 154 |  |  |  |  |  |  | 0 - default | 
| 155 |  |  |  |  |  |  | 1 - given dates, see $dates list | 
| 156 |  |  |  |  |  |  | 2 - oldest year to current year | 
| 157 |  |  |  |  |  |  | 3 - current year to future year | 
| 158 |  |  |  |  |  |  |  | 
| 159 |  |  |  |  |  |  | For oldest year, this is determined by the configuration setting | 
| 160 |  |  |  |  |  |  | 'year_past_offset' or 'year_past'. For the future year, this is determined by | 
| 161 |  |  |  |  |  |  | the configuration setting 'year_future_offset'. | 
| 162 |  |  |  |  |  |  |  | 
| 163 |  |  |  |  |  |  | If the range is set to 1, the list of dates given in the $dates array | 
| 164 |  |  |  |  |  |  | reference will be used. | 
| 165 |  |  |  |  |  |  |  | 
| 166 |  |  |  |  |  |  | =item PeriodSelect($opt,$blank) | 
| 167 |  |  |  |  |  |  |  | 
| 168 |  |  |  |  |  |  | Provides a Period dropdown selection box. | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | The option $opt allows the given period to be the selected option in the | 
| 171 |  |  |  |  |  |  | dropdown. If blank is true, a 'Select Period' option is added as the first | 
| 172 |  |  |  |  |  |  | option to the dropdown. | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | Current valid periods are: | 
| 175 |  |  |  |  |  |  |  | 
| 176 |  |  |  |  |  |  | opt           value | 
| 177 |  |  |  |  |  |  | ------------------- | 
| 178 |  |  |  |  |  |  | evnt-month    Month | 
| 179 |  |  |  |  |  |  | evnt-week     Week | 
| 180 |  |  |  |  |  |  | evnt-day      Day | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | =back | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  | =cut | 
| 185 |  |  |  |  |  |  |  | 
| 186 |  |  |  |  |  |  | sub DaySelect { | 
| 187 |  |  |  |  |  |  | my ($opt,$blank) = @_; | 
| 188 |  |  |  |  |  |  | my @list = @days; | 
| 189 |  |  |  |  |  |  | unshift @list, {id=>0,value=>'Select Day'}  if(defined $blank && $blank == 1); | 
| 190 |  |  |  |  |  |  | DropDownRows($opt,'day','id','value',@list); | 
| 191 |  |  |  |  |  |  | } | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | sub MonthSelect { | 
| 194 |  |  |  |  |  |  | my ($opt,$blank) = @_; | 
| 195 |  |  |  |  |  |  | my @list = @months; | 
| 196 |  |  |  |  |  |  | unshift @list, {id=>0,value=>'Select Month'}    if(defined $blank && $blank == 1); | 
| 197 |  |  |  |  |  |  | DropDownRows($opt,'month','id','value',@list); | 
| 198 |  |  |  |  |  |  | } | 
| 199 |  |  |  |  |  |  |  | 
| 200 |  |  |  |  |  |  | sub YearSelect { | 
| 201 |  |  |  |  |  |  | my ($opt,$range,$blank,$dates) = @_; | 
| 202 |  |  |  |  |  |  | my $year = formatDate(1); | 
| 203 |  |  |  |  |  |  |  | 
| 204 |  |  |  |  |  |  | my $past_offset   = $settings{year_past_offset} || 0; | 
| 205 |  |  |  |  |  |  | my $future_offset = defined $settings{year_future_offset} ? $settings{year_future_offset} : 4; | 
| 206 |  |  |  |  |  |  | my $past   = $past_offset ? $year - $past_offset : $settings{year_past}; | 
| 207 |  |  |  |  |  |  | my $future = $year + $future_offset; | 
| 208 |  |  |  |  |  |  | $past ||= $year; | 
| 209 |  |  |  |  |  |  |  | 
| 210 |  |  |  |  |  |  | my @range = ($past .. $future); | 
| 211 |  |  |  |  |  |  | if(defined $range) { | 
| 212 |  |  |  |  |  |  | if($range == 1)     { @range = @$dates } | 
| 213 |  |  |  |  |  |  | elsif($range == 2)  { @range = ($past .. $year) } | 
| 214 |  |  |  |  |  |  | elsif($range == 3)  { @range = ($year .. $future) } | 
| 215 |  |  |  |  |  |  | } | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  | my @years = map {{'id'=>$_,'value'=> $_}} @range; | 
| 218 |  |  |  |  |  |  | unshift @years, {id=>0,value=>'Select Year'}    if(defined $blank && $blank == 1); | 
| 219 |  |  |  |  |  |  | DropDownRows($opt,'year','id','value',@years); | 
| 220 |  |  |  |  |  |  | } | 
| 221 |  |  |  |  |  |  |  | 
| 222 |  |  |  |  |  |  | sub PeriodSelect { | 
| 223 |  |  |  |  |  |  | my ($opt,$blank) = @_; | 
| 224 |  |  |  |  |  |  | my @list = @periods; | 
| 225 |  |  |  |  |  |  | unshift @list, {act=>'',value=>'Select Period'}   if(defined $blank && $blank == 1); | 
| 226 |  |  |  |  |  |  | DropDownRowsText($opt,'period','act','value',@list); | 
| 227 |  |  |  |  |  |  | } | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | ## ------------------------------------ | 
| 230 |  |  |  |  |  |  | ## Date Functions | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | =head2 Date Formatting | 
| 233 |  |  |  |  |  |  |  | 
| 234 |  |  |  |  |  |  | =over 4 | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | =item formatDate | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | =item unformatDate | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | =item isMonth | 
| 241 |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  | =back | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | =cut | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | sub formatDate { | 
| 247 |  |  |  |  |  |  | my ($format,$time) = @_; | 
| 248 |  |  |  |  |  |  | my $now = $time ? 0 : 1; | 
| 249 |  |  |  |  |  |  |  | 
| 250 |  |  |  |  |  |  | my $dt; | 
| 251 |  |  |  |  |  |  | my $timezone = $settings{timezone} || 'Europe/London'; | 
| 252 |  |  |  |  |  |  | if($time) { | 
| 253 |  |  |  |  |  |  | $dt = DateTime->from_epoch( epoch => $time, time_zone => $timezone ); | 
| 254 |  |  |  |  |  |  | } else { | 
| 255 |  |  |  |  |  |  | $dt = DateTime->now( time_zone => $timezone ); | 
| 256 |  |  |  |  |  |  | } | 
| 257 |  |  |  |  |  |  |  | 
| 258 |  |  |  |  |  |  | return $dt->epoch   unless($format); | 
| 259 |  |  |  |  |  |  |  | 
| 260 |  |  |  |  |  |  | #LogDebug("formatDate format=$format, time=".$dt->epoch); | 
| 261 |  |  |  |  |  |  |  | 
| 262 |  |  |  |  |  |  | # create date mini strings | 
| 263 |  |  |  |  |  |  | my $fmonth  = $dt->month_name; | 
| 264 |  |  |  |  |  |  | my $amonth  = $dt->month_abbr; | 
| 265 |  |  |  |  |  |  | my $fdotw   = $dt->day_name; | 
| 266 |  |  |  |  |  |  | my $adotw   = $dt->day_abbr; | 
| 267 |  |  |  |  |  |  | my $fsday   = sprintf "%d",   $dt->day; # short form, ie 6 | 
| 268 |  |  |  |  |  |  | my $fday    = sprintf "%02d", $dt->day; # long form, ie 06 | 
| 269 |  |  |  |  |  |  | my $fmon    = sprintf "%02d", $dt->month; | 
| 270 |  |  |  |  |  |  | my $fyear   = sprintf "%04d", $dt->year; | 
| 271 |  |  |  |  |  |  | my $fddext  = sprintf "%d%s", $dt->day, _ext($dt->day); | 
| 272 |  |  |  |  |  |  | my $time12  = sprintf "%d:%02d%s", $dt->hour_12, $dt->minute, lc $dt->am_or_pm; | 
| 273 |  |  |  |  |  |  | my $time24  = sprintf "%d:%02d:%02d", $dt->hour, $dt->minute, $dt->second; | 
| 274 |  |  |  |  |  |  | my $fhour   = sprintf "%02d", $dt->hour; | 
| 275 |  |  |  |  |  |  | my $fminute = sprintf "%02d", $dt->minute; | 
| 276 |  |  |  |  |  |  | my $fsecond = sprintf "%02d", $dt->second; | 
| 277 |  |  |  |  |  |  | my $tz      = 'UTC'; | 
| 278 |  |  |  |  |  |  | eval { $tz = $dt->time_zone->short_name_for_datetime }; | 
| 279 |  |  |  |  |  |  |  | 
| 280 |  |  |  |  |  |  | my $fmt = $formats{$format}; | 
| 281 |  |  |  |  |  |  |  | 
| 282 |  |  |  |  |  |  | # transpose format string into a date string | 
| 283 |  |  |  |  |  |  | $fmt =~ s/hh/$fhour/; | 
| 284 |  |  |  |  |  |  | $fmt =~ s/mm/$fminute/; | 
| 285 |  |  |  |  |  |  | $fmt =~ s/ss/$fsecond/; | 
| 286 |  |  |  |  |  |  | $fmt =~ s/DMY/$fday-$fmon-$fyear/; | 
| 287 |  |  |  |  |  |  | $fmt =~ s/MDY/$fmon-$fday-$fyear/; | 
| 288 |  |  |  |  |  |  | $fmt =~ s/YMD/$fyear-$fmon-$fday/; | 
| 289 |  |  |  |  |  |  | $fmt =~ s/MABV/$amonth/; | 
| 290 |  |  |  |  |  |  | $fmt =~ s/DABV/$adotw/; | 
| 291 |  |  |  |  |  |  | $fmt =~ s/MONTH/$fmonth/; | 
| 292 |  |  |  |  |  |  | $fmt =~ s/DAY/$fdotw/; | 
| 293 |  |  |  |  |  |  | $fmt =~ s/DDEXT/$fddext/; | 
| 294 |  |  |  |  |  |  | $fmt =~ s/YYYY/$fyear/; | 
| 295 |  |  |  |  |  |  | $fmt =~ s/MM/$fmon/; | 
| 296 |  |  |  |  |  |  | $fmt =~ s/DD/$fday/; | 
| 297 |  |  |  |  |  |  | $fmt =~ s/dd/$fsday/; | 
| 298 |  |  |  |  |  |  | $fmt =~ s/TIME12/$time12/; | 
| 299 |  |  |  |  |  |  | $fmt =~ s/TIME24/$time24/; | 
| 300 |  |  |  |  |  |  | $fmt =~ s/TZ/$tz/; | 
| 301 |  |  |  |  |  |  |  | 
| 302 |  |  |  |  |  |  | return $fmt; | 
| 303 |  |  |  |  |  |  | } | 
| 304 |  |  |  |  |  |  |  | 
| 305 |  |  |  |  |  |  | sub unformatDate { | 
| 306 |  |  |  |  |  |  | my ($format,$time) = @_; | 
| 307 |  |  |  |  |  |  |  | 
| 308 |  |  |  |  |  |  | return time unless($format && $time); | 
| 309 |  |  |  |  |  |  |  | 
| 310 |  |  |  |  |  |  | my (@fields,@values); | 
| 311 |  |  |  |  |  |  | my @basic  = qw(ss mm hh DD MM YYYY); | 
| 312 |  |  |  |  |  |  | my %forms  = map {$_ => 0 } @basic, 'dd'; | 
| 313 |  |  |  |  |  |  |  | 
| 314 |  |  |  |  |  |  | if($unformats{$format}) { | 
| 315 |  |  |  |  |  |  | @fields = reverse @basic; | 
| 316 |  |  |  |  |  |  | @values = $time =~ /$unformats{$format}/; | 
| 317 |  |  |  |  |  |  | } else { | 
| 318 |  |  |  |  |  |  | my $pattern = $formats{$format}; | 
| 319 |  |  |  |  |  |  | $pattern =~ s!TIME24!hh::mm:ss!; | 
| 320 |  |  |  |  |  |  | $pattern =~ s!TIME12!hh::ampm!; | 
| 321 |  |  |  |  |  |  |  | 
| 322 |  |  |  |  |  |  | @fields = split(qr![ ,/:()-]+!,$pattern); | 
| 323 |  |  |  |  |  |  | @values = split(qr![ ,/:()-]+!,$time); | 
| 324 |  |  |  |  |  |  | } | 
| 325 |  |  |  |  |  |  |  | 
| 326 |  |  |  |  |  |  | @forms{@fields} = @values; | 
| 327 |  |  |  |  |  |  | $forms{$_} = int($forms{$_}||0)    for(@basic); | 
| 328 |  |  |  |  |  |  |  | 
| 329 |  |  |  |  |  |  | #use Data::Dumper; | 
| 330 |  |  |  |  |  |  | #LogDebug("format=[$format], time=[$time]"); | 
| 331 |  |  |  |  |  |  | #LogDebug("fields=[@fields], values=[@values]"); | 
| 332 |  |  |  |  |  |  | #LogDebug("before=".Dumper(\%forms)); | 
| 333 |  |  |  |  |  |  |  | 
| 334 |  |  |  |  |  |  | ($forms{DD}) = $forms{dd} =~ /(\d+)/        if($forms{dd}); | 
| 335 |  |  |  |  |  |  | ($forms{DD}) = $forms{DDEXT} =~ /(\d+)/     if($forms{DDEXT}); | 
| 336 |  |  |  |  |  |  | $forms{MM} = isMonth($forms{MONTH})         if($forms{MONTH}); | 
| 337 |  |  |  |  |  |  | $forms{MM} = isMonth($forms{MABV})          if($forms{MABV}); | 
| 338 |  |  |  |  |  |  | ($forms{mm},$forms{AMPM}) = ($forms{ampm} =~ /(\d+)(am|pm)/)  if($forms{ampm}); | 
| 339 |  |  |  |  |  |  | $forms{hh}+=12  if($forms{AMPM} && $forms{AMPM} eq 'pm'); | 
| 340 |  |  |  |  |  |  |  | 
| 341 |  |  |  |  |  |  | @values = map {$forms{$_}||0} @basic; | 
| 342 |  |  |  |  |  |  |  | 
| 343 |  |  |  |  |  |  | my $timezone = $settings{timezone} || 'Europe/London'; | 
| 344 |  |  |  |  |  |  | my $dt = DateTime->new( | 
| 345 |  |  |  |  |  |  | year => $values[5], month  => $values[4] || 1, day    => $values[3] || 1, | 
| 346 |  |  |  |  |  |  | hour => $values[2], minute => $values[1],      second => $values[0], | 
| 347 |  |  |  |  |  |  | time_zone => $timezone ); | 
| 348 |  |  |  |  |  |  |  | 
| 349 |  |  |  |  |  |  | return $dt->epoch; | 
| 350 |  |  |  |  |  |  | } | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | sub _ext { | 
| 353 |  |  |  |  |  |  | my $day = shift; | 
| 354 |  |  |  |  |  |  | my $ext = "th"; | 
| 355 |  |  |  |  |  |  | if($day == 1 || $day == 21 || $day == 31)   {   $ext = "st" } | 
| 356 |  |  |  |  |  |  | elsif($day == 2 || $day == 22)              {   $ext = "nd" } | 
| 357 |  |  |  |  |  |  | elsif($day == 3 || $day == 23)              {   $ext = "rd" } | 
| 358 |  |  |  |  |  |  | return $ext; | 
| 359 |  |  |  |  |  |  | } | 
| 360 |  |  |  |  |  |  |  | 
| 361 |  |  |  |  |  |  | sub isMonth { | 
| 362 |  |  |  |  |  |  | my $month = shift; | 
| 363 |  |  |  |  |  |  | return (localtime)[4]+1 unless(defined $month && $month); | 
| 364 |  |  |  |  |  |  |  | 
| 365 |  |  |  |  |  |  | foreach (@months) { | 
| 366 |  |  |  |  |  |  | return $_->{id} if($_->{value} =~ /$month/); | 
| 367 |  |  |  |  |  |  | return $_->{value} if($month eq $_->{id}); | 
| 368 |  |  |  |  |  |  | } | 
| 369 |  |  |  |  |  |  | return 0; | 
| 370 |  |  |  |  |  |  | } | 
| 371 |  |  |  |  |  |  |  | 
| 372 |  |  |  |  |  |  | 1; | 
| 373 |  |  |  |  |  |  |  | 
| 374 |  |  |  |  |  |  | __END__ |