]>
jfr.im git - irc/SurrealServices/srsv.git/blob - branches/erry-devel/SrSv/Time.pm
1 # This file is part of SurrealServices.
3 # SurrealServices is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # SurrealServices is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with SurrealServices; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 use Exporter
'import';
24 BEGIN { our @EXPORT = qw( @months @days
25 gmtime2 tz_time gmt_date local_date
26 time_ago time_rel time_rel_long_all
28 get_nextday get_nextday_time get_monthdays
29 get_nexthour get_nexthour_time
33 our @months = ( 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' );
34 our @days = ( 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' );
37 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime(shift);
38 return $mday.'/'.$months[$mon].'/'. substr($year, -2, 2).' '.
39 sprintf("%02d:%02d", $hour, $min);
44 $time = time() unless $time;
45 return _time_text
($time) . ' GMT';
49 my ($tzoffset, $time) = @_;
50 return _time_text
(($time ? $time : time()) + tz_to_offset
($tzoffset));
55 # offset is a signed integer corresponding to 1/4 hr increments
56 # or 900 seconds (15 minutes)
57 return ($offset * 900);
61 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime(shift);
62 return (!wantarray ? ($year+1900).' '.$months[$mon].' '.$mday : ($year + 1900, $mon+1, $months[$mon], $mday));
67 $time = time() unless $time;
68 return _date_text
($time);
72 my ($tzoffset, $time) = @_;
73 return _date_text
(($time ? $time : time()) + tz_to_offset
($tzoffset));
82 my @vals = split(/(?<!\d)(?=\d+\w)/, $str);
84 foreach my $val (@vals) {
86 my ($num, $pos) = ($1, $2);
88 if($pos eq 'w') { $num *= (86400*7) }
89 elsif($pos eq 'd') { $num *= 86400 }
90 elsif($pos eq 'h') { $num *= 3600 }
91 elsif($pos eq 'm') { $num *= 60 }
92 elsif($pos ne 's') { return undef }
101 no integer
; # We might want to pass in a float value for $difference
102 my ($difference) = @_;
103 my ($weeks, $days, $hours, $minutes, $seconds);
104 $seconds = $difference % 60;
105 $difference = ($difference - $seconds) / 60;
106 $minutes = $difference % 60;
107 $difference = ($difference - $minutes) / 60;
108 $hours = $difference % 24;
109 $difference = ($difference - $hours) / 24;
110 $days = $difference % 7;
111 $weeks = ($difference - $days) / 7;
113 return ($weeks, $days, $hours, $minutes, $seconds);
117 return time_rel
(time() - $_[0], $_[1]);
121 my ($time, $all) = @_;
123 if ($time >= 2419200) { # 86400 * 7 * 4
124 my ($years, $months, $weeks, $days) = __time_rel_long
(time() - $time);
125 if($years or $months or $weeks or $days) {
128 $text = "$years year".($years !=1 ? 's' : '');
131 $text .= (length($text) ? ' ' : '')."$months month".($months !=1 ? 's' : '');
132 if ($years && !$all) {
137 $text .= (length($text) ? ' ' : '')."$weeks week".($weeks !=1 ? 's' : '');
138 if ($months && !$all) {
143 $text .= (length($text) ? ' ' : '')."$days day".($days !=1 ? 's' : '');
145 if ($weeks && !$all) {
152 return ( $years ? "$years year".($years !=1 ? 's' : '') : '' ).
153 ( $months ? ($years ? ', ' : '')."$months month".( $months!=1 ? 's' : '' ) : '').
154 ( $weeks ? (($years or $months) ? ', ' : '')."$weeks week".( $weeks!=1 ? 's' : '' ) : '').
155 ( $days ? (($months or $years or $weeks) ? ', ' : '')."$days day".($days!=1 ? 's' : '') : '' )
161 my ($weeks, $days, $hours, $minutes, $seconds) = split_time
($time);
164 # if($time >= 604800) { # 86400 * 7 }
166 $text = "$weeks week".($weeks!=1 ? 's' : '');
168 return "$weeks week".
169 ($weeks!=1 ? 's' : '').
171 ($days!=1 ? 's' : '');
175 $text .= (length($text) ? ' ' : '')."$days day".($days!=1 ? 's' : '');
176 return $text if $weeks && !$all;
179 ($days!=1 ? 's' : '').
181 ($hours!=1 ? 's' : '');
185 $text .= (length($text) ? ' ' : '')."$hours hour".($hours!=1 ? 's' : '');
186 return $text if $days && !$all;
188 return "$hours hour".
189 ($hours!=1 ? 's' : '').
191 ($minutes!=1 ? 's' : '');
195 $text .= (length($text) ? ' ' : '')."$minutes minute".($minutes!=1 ? 's' : '');
196 return $text if $hours && !$all;
197 =cut
return "$minutes minute".
198 ($minutes!=1 ? 's' : '').
200 ($seconds!=1 ? 's' : '');
204 $text .= (length($text) ? ' ' : '')."$seconds second".($seconds!=1 ? 's' : '');
206 return "$seconds second".
207 ($seconds!=1 ? 's' : '');
213 # This is for cases over 4 weeks, when we need years, months, weeks, and days
214 sub __time_rel_long
($;$) {
215 my ($lesser_time, $greater_time) = @_;
216 $greater_time = time() unless $greater_time;
218 my ($sec1, $min1, $hour1, $mday1, $month1, $year1, undef, undef, undef) = gmtime($lesser_time);
219 my ($sec2, $min2, $hour2, $mday2, $month2, $year2, undef, undef, undef) = gmtime($greater_time);
221 my ($result_years, $result_months, $result_weeks, $result_days,
222 $result_hours, $result_mins, $result_secs);
223 $result_secs = $sec2 - $sec1;
224 $result_mins = $min2 - $min1;
225 if($result_secs < 0) {
226 $result_secs += 60; $result_mins--;
228 $result_hours = $hour2 - $hour1;
229 if($result_mins < 0) {
230 $result_mins += 60; $result_hours--;
232 $result_days = $mday2 - $mday1;
233 if($result_hours < 0) {
234 $result_hours += 24; $result_days--;
236 $result_months = $month2 - $month1;
237 if($result_days < 0) {
238 $result_days += get_monthdays
(
239 ($month2 == 0 ? 11 : $month2 - 1),
240 ($month2 == 0 ? $year2 - 1: $year2));
243 # The following division relies on integer division, as 'use integer' is decl'd above.
244 $result_weeks = $result_days / 7;
245 $result_days = $result_days % 7;
246 $result_years = $year2 - $year1;
247 if($result_months < 0) {
248 $result_months += 12; $result_years--
250 return ($result_years, $result_months, $result_weeks, $result_days, $result_hours, $result_mins, $result_secs);
253 # Apologize about the unreadability, but the alternative is about 4 times as long
254 # This is for use when we want as precise a time-difference as possible.
255 sub time_rel_long_all
($;$) {
256 my ($lesser_time, $greater_time) = @_;
257 $greater_time = time() unless $greater_time;
258 my ($years, $months, $weeks, $days, $hours, $minutes, $seconds) = __time_rel_long
($lesser_time);
259 return ( $years ? "$years year".($years !=1 ? 's' : '') : '' ).
260 ( $months ? ($years ? ', ' : '')."$months month".( $months!=1 ? 's' : '' ) : '').
261 ( $weeks ? (($years or $months) ? ', ' : '')."$weeks week".( $weeks!=1 ? 's' : '' ) : '').
262 ( $days ? (($months or $years or $weeks) ? ', ' : '')."$days day".($days!=1 ? 's' : '') : '' ).
263 ( $hours ? (($days or $months or $years or $weeks) ? ', ' : '')."$hours hour".($hours!=1 ? 's' : '') : '' ).
264 ( $minutes ? (($hours or $days or $months or $years or $weeks) ? ', ' : '')."$minutes minute".($minutes!=1 ? 's' : '') : '' ).
265 ( $seconds ? (($minutes or $days or $months or $years or $weeks) ? ', ' : '')."$seconds second".($seconds!=1 ? 's' : '') : '' )
270 sub get_nextday
($$$) {
271 my ($mday, $mon, $year) = @_;
272 $year += 1900 if $year < 1582; #Gregorian calendar was somewhere around here...
274 my $monthdays = get_monthdays
($mon, $year);
276 if($mday > $monthdays) {
284 return ($mday, $mon, $year);
286 sub get_nextday_time
(;$) {
288 $time = time() unless $time;
289 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($time);
290 return Time
::Local
::timegm
(0,0,0,get_nextday
($mday, $mon, $year));
293 sub get_nexthour
($$$$) {
294 my ($hour, $mday, $mon, $year) = @_;
296 # if($minute >= 60) {
303 ($mday, $mon, $year) = get_nextday
($mday, $mon, $year)
305 return ($hour, $mday, $mon, $year);
307 sub get_nexthour_time
(;$) {
309 $time = time() unless $time;
310 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($time);
311 return Time
::Local
::timegm
(0,0,get_nexthour
($hour, $mday, $mon, $year));
314 # This function is only correct/valid for Gregorian dates.
317 # $month is 0-11 not 1-12
318 my ($month, $year) = @_;
319 sub m30
($) { return 30; }
320 sub m31
($) { return 31; }
323 if(($year % 100 and !($year % 4)) or !($year % 400)) {
329 # this is the common table, but note +1 below
330 # as gmtime() and friends return months from 0-11 not 1-12
348 $year += 1900 if $year < 1582; #Gregorian calendar was somewhere around here...
349 return $months{$month+1}($year);