missing sprintf around string
[squirrelmail.git] / functions / date.php
CommitLineData
59177427 1<?php
7350889b 2
35586184 3/**
4 * date.php
5 *
6c84ba1e 6 * Copyright (c) 1999-2005 The SquirrelMail Project Team
35586184 7 * Licensed under the GNU GPL. For full terms see the file COPYING.
8 *
9 * Takes a date and parses it into a usable format. The form that a
10 * date SHOULD arrive in is:
11 * <Tue,> 29 Jun 1999 09:52:11 -0500 (EDT)
12 * (as specified in RFC 822) -- 'Tue' is optional
13 *
31841a9e 14 * @version $Id$
d6c32258 15 * @package squirrelmail
371e2a0d 16 * @subpackage date
35586184 17 */
18
d6c32258 19/** Load up some useful constants */
b68edc75 20require_once(SM_PATH . 'functions/constants.php');
35586184 21
8b096f0a 22/**
23 * Corrects a time stamp to be the local time.
24 *
25 * @param int stamp the timestamp to adjust
26 * @param string tzc the timezone correction
27 * @return int the corrected timestamp
28 */
d5c4ae7c 29function getGMTSeconds($stamp, $tzc) {
dc06f88c 30 /* date couldn't be parsed */
913ed9a3 31 if ($stamp == -1) {
32 return -1;
33 }
d5c4ae7c 34 /* timezone correction, expressed as `shhmm' */
35 switch($tzc)
dc06f88c 36 {
37 case 'Pacific':
38 case 'PST':
d5c4ae7c 39 $tzc = '-0800';
dc06f88c 40 break;
c2e29558 41 case 'Mountain':
42 case 'MST':
43 case 'PDT':
44 $tzc = '-0700';
dc06f88c 45 break;
46 case 'Central':
47 case 'CST':
c2e29558 48 case 'MDT':
49 $tzc = '-0600';
dc06f88c 50 break;
51 case 'Eastern':
52 case 'EST':
c2e29558 53 case 'CDT':
54 $tzc = '-0500';
dc06f88c 55 break;
56 case 'EDT':
d5c4ae7c 57 $tzc = '-0400';
dc06f88c 58 break;
c2e29558 59 case 'GMT':
60 $tzc = '+0000';
dc06f88c 61 break;
62 case 'BST':
d5c4ae7c 63 case 'MET':
64 case 'CET':
65 $tzc = '+0100';
66 break;
dc06f88c 67 case 'EET':
c2e29558 68 case 'IST':
69 case 'MET DST':
70 case 'METDST':
71 $tzc = '+0200';
dc06f88c 72 break;
c2e29558 73 case 'HKT':
74 $tzc = '+0800';
dc06f88c 75 break;
c2e29558 76 case 'JST':
dc06f88c 77 case 'KST':
c2e29558 78 $tzc = '+0900';
dc06f88c 79 break;
0e4ae91a 80 }
d5c4ae7c 81 $neg = false;
82 if (substr($tzc, 0, 1) == '-') {
0e4ae91a 83 $neg = true;
d5c4ae7c 84 } else if (substr($tzc, 0, 1) != '+') {
85 $tzc = '+'.$tzc;
0e4ae91a 86 }
d5c4ae7c 87 $hh = substr($tzc,1,2);
88 $mm = substr($tzc,3,2);
89 $iTzc = ($hh * 60 + $mm) * 60;
c2e29558 90 if ($neg) $iTzc = -1 * (int) $iTzc;
d5c4ae7c 91 /* stamp in gmt */
92 $stamp -= $iTzc;
0e4ae91a 93 /** now find what the server is at **/
94 $current = date('Z', time());
d5c4ae7c 95 /* stamp in local timezone */
96 $stamp += $current;
c2e29558 97
0e4ae91a 98 return $stamp;
99}
0f1835f3 100
0e4ae91a 101/**
8b096f0a 102 * Returns the (localized) string for a given day number.
103 * Switch system has been intentionaly chosen for the
104 * internationalization of month and day names. The reason
105 * is to make sure that _("") strings will go into the
106 * main po.
107 *
108 * @param int day_number the day number
109 * @return string the day in human readable form
110 */
0e4ae91a 111function getDayName( $day_number ) {
0f1835f3 112
0e4ae91a 113 switch( $day_number ) {
114 case 0:
115 $ret = _("Sunday");
116 break;
117 case 1:
118 $ret = _("Monday");
119 break;
120 case 2:
121 $ret = _("Tuesday");
122 break;
123 case 3:
124 $ret = _("Wednesday");
125 break;
126 case 4:
127 $ret = _("Thursday");
128 break;
129 case 5:
130 $ret = _("Friday");
131 break;
132 case 6:
133 $ret = _("Saturday");
134 break;
135 default:
136 $ret = '';
137 }
138 return( $ret );
139}
d59837cf 140
8b096f0a 141/**
142 * Like getDayName, but returns the short form
143 * @param int day_number the day number
144 * @return string the day in short human readable form
145 */
22d73941 146function getDayAbrv( $day_number ) {
147
148 switch( $day_number ) {
149 case 0:
150 $ret = _("Sun");
151 break;
152 case 1:
153 $ret = _("Mon");
154 break;
155 case 2:
156 $ret = _("Tue");
157 break;
158 case 3:
159 $ret = _("Wed");
160 break;
161 case 4:
162 $ret = _("Thu");
163 break;
164 case 5:
165 $ret = _("Fri");
166 break;
167 case 6:
168 $ret = _("Sat");
169 break;
170 default:
171 $ret = '';
172 }
173 return( $ret );
174}
175
8b096f0a 176
177/**
178 * Returns the (localized) string for a given month number.
179 *
c2e29558 180 * @param string month_number the month number (01..12)
8b096f0a 181 * @return string the month name in human readable form
182 */
0e4ae91a 183function getMonthName( $month_number ) {
184 switch( $month_number ) {
185 case '01':
186 $ret = _("January");
187 break;
188 case '02':
189 $ret = _("February");
190 break;
191 case '03':
192 $ret = _("March");
193 break;
194 case '04':
195 $ret = _("April");
196 break;
197 case '05':
198 $ret = _("May");
199 break;
200 case '06':
201 $ret = _("June");
202 break;
203 case '07':
204 $ret = _("July");
205 break;
206 case '08':
207 $ret = _("August");
208 break;
209 case '09':
210 $ret = _("September");
211 break;
212 case '10':
213 $ret = _("October");
214 break;
215 case '11':
216 $ret = _("November");
217 break;
218 case '12':
219 $ret = _("December");
220 break;
221 default:
222 $ret = '';
223 }
224 return( $ret );
225}
d59837cf 226
8b096f0a 227/**
228 * Returns the (localized) string for a given month number,
229 * short representation.
230 *
c2e29558 231 * @param string month_number the month number (01..12)
8b096f0a 232 * @return string the shortened month in human readable form
233 */
22d73941 234function getMonthAbrv( $month_number ) {
235 switch( $month_number ) {
236 case '01':
237 $ret = _("Jan");
238 break;
239 case '02':
240 $ret = _("Feb");
241 break;
242 case '03':
243 $ret = _("Mar");
244 break;
245 case '04':
246 $ret = _("Apr");
247 break;
248 case '05':
249 $ret = _("Ma&#121;");
250 break;
251 case '06':
252 $ret = _("Jun");
253 break;
254 case '07':
255 $ret = _("Jul");
256 break;
257 case '08':
258 $ret = _("Aug");
259 break;
260 case '09':
261 $ret = _("Sep");
262 break;
263 case '10':
264 $ret = _("Oct");
265 break;
266 case '11':
267 $ret = _("Nov");
268 break;
269 case '12':
270 $ret = _("Dec");
271 break;
272 default:
273 $ret = '';
274 }
275 return( $ret );
276}
277
8b096f0a 278/**
279 * Returns the localized representation of the date/time.
280 *
281 * @param string date_format The format for the date, like the input for the PHP date() function.
282 * @param int stamp the timestamp to convert
283 * @return string a full date representation
284 */
0e4ae91a 285function date_intl( $date_format, $stamp ) {
e6b76811 286 $ret = str_replace( array('D','F','l','M'), array('$1','$2','$3','$4'), $date_format );
8b096f0a 287 // to reduce the date calls we retrieve m and w in the same call
288 $ret = date('w#m#'. $ret, $stamp );
289 // extract day and month in order to replace later by intl day and month
c2e29558 290 $aParts = explode('#',$ret);
e6b76811 291 $ret = str_replace(array('$1','$4','$2','$3',), array(getDayAbrv($aParts[0]),
15d49d77 292 getMonthAbrv($aParts[1]),
91e0dccc 293 getMonthName($aParts[1]),
294 getDayName($aParts[0])),
295 $aParts[2]);
8b096f0a 296 return( $ret );
0e4ae91a 297}
d59837cf 298
8b096f0a 299/**
300 * This returns a date of the format "Wed, Oct 29, 2003 9:52 am",
301 * or the same in 24H format (depending on the user's settings),
302 * and taking localization into accout.
303 *
304 * @param int stamp the timestamp
305 * @return string the long date string
306 */
0e4ae91a 307function getLongDateString( $stamp ) {
d59837cf 308
0e4ae91a 309 global $hour_format;
c2e29558 310
913ed9a3 311 if ($stamp == -1) {
312 return '';
313 }
314
0e4ae91a 315 if ( $hour_format == SMPREF_TIME_12HR ) {
316 $date_format = _("D, F j, Y g:i a");
317 } else {
3f7e6af3 318 $date_format = _("D, F j, Y H:i");
0e4ae91a 319 }
c2e29558 320
0e4ae91a 321 return( date_intl( $date_format, $stamp ) );
0f1835f3 322
0e4ae91a 323}
d205a7bf 324
8b096f0a 325/**
326 * Returns a short representation of the date,
327 * taking timezones and localization into account.
328 * Depending on user's settings, this string can be
329 * of the form: "14:23" or "Jun 14, 2003" depending
330 * on whether the stamp is "today" or not.
331 *
332 * @param int stamp the timestamp
333 * @return string the date string
334 */
0e4ae91a 335function getDateString( $stamp ) {
d68a3926 336
3e3b60e3 337 global $invert_time, $hour_format, $show_full_date;
dc06f88c 338
339 if ( $stamp == -1 ) {
340 return '';
341 }
c2e29558 342
0e4ae91a 343 $now = time();
c2e29558 344
0e4ae91a 345 $dateZ = date('Z', $now );
3f298968 346
347 // FIXME: isn't this obsolete and introduced as a terrible workaround
c2e29558 348 // for bugs at other places which are fixed a long time ago?
0e4ae91a 349 if ($invert_time) {
350 $dateZ = - $dateZ;
351 }
b0d8461b 352
353 // calculate when it was midnight and when it will be,
354 // in order to display dates differently if they're 'today'
0e4ae91a 355 $midnight = $now - ($now % 86400) - $dateZ;
b0d8461b 356 // this is to correct if after calculations midnight is more than
357 // one whole day away.
358 if ($now - $midnight > 86400) {
359 $midnight += 86400;
360 }
361 $nextmid = $midnight + 86400;
c2e29558 362
7e27023f 363 if (($show_full_date == 1) || ($nextmid < $stamp)) {
3e3b60e3 364 $date_format = _("M j, Y");
365 } else if ($midnight < $stamp) {
0e4ae91a 366 /* Today */
367 if ( $hour_format == SMPREF_TIME_12HR ) {
368 $date_format = _("g:i a");
369 } else {
3f7e6af3 370 $date_format = _("H:i");
0e4ae91a 371 }
372 } else if ($midnight - 518400 < $stamp) {
373 /* This week */
374 if ( $hour_format == SMPREF_TIME_12HR ) {
375 $date_format = _("D, g:i a");
376 } else {
3f7e6af3 377 $date_format = _("D, H:i");
0e4ae91a 378 }
379 } else {
380 /* before this week */
381 $date_format = _("M j, Y");
382 }
c2e29558 383
0e4ae91a 384 return( date_intl( $date_format, $stamp ) );
385}
0f1835f3 386
8b096f0a 387/**
388 * Decodes a RFC 822 Date-header into a timestamp
389 *
390 * @param array dateParts the Date-header split by whitespace
391 * @return int the timestamp calculated from the header
392 */
0e4ae91a 393function getTimeStamp($dateParts) {
394 /** $dateParts[0] == <day of week> Mon, Tue, Wed
395 ** $dateParts[1] == <day of month> 23
396 ** $dateParts[2] == <month> Jan, Feb, Mar
397 ** $dateParts[3] == <year> 1999
398 ** $dateParts[4] == <time> 18:54:23 (HH:MM:SS)
399 ** $dateParts[5] == <from GMT> +0100
400 ** $dateParts[6] == <zone> (EDT)
401 **
402 ** NOTE: In RFC 822, it states that <day of week> is optional.
403 ** In that case, dateParts[0] would be the <day of month>
404 ** and everything would be bumped up one.
405 **/
d5c4ae7c 406
c2e29558 407 /*
0e4ae91a 408 * Simply check to see if the first element in the dateParts
409 * array is an integer or not.
dc06f88c 410 * Since the day of week is optional, this check is needed.
0e4ae91a 411 */
50457d45 412 if (count($dateParts) <2) {
2a9b0fad 413 return -1;
c2e29558 414 } else if (count($dateParts) ==3) {
415 if (substr_count($dateParts[0],'-') == 2 &&
416 substr_count($dateParts[1],':') == 2) {
417 // dd-Month-yyyy 23:19:05 +0200
418 // redefine the date
419 $aDate = explode('-',$dateParts[0]);
420 $newDate = array($aDate[0],$aDate[1],$aDate[2],$dateParts[1],$dateParts[2]);
421 $dateParts = $newDate;
422 }
50457d45 423 }
3302d0d4 424
d5c4ae7c 425 /* remove day of week */
426 if (!is_numeric(trim($dateParts[0]))) {
427 $dataParts = array_shift($dateParts);
0e4ae91a 428 }
d5c4ae7c 429 /* calculate timestamp separated from the zone and obs-zone */
430 $stamp = strtotime(implode (' ', array_splice ($dateParts,0,4)));
431 if (!isset($dateParts[0])) {
432 $dateParts[0] = '+0000';
0e4ae91a 433 }
dc06f88c 434
d5c4ae7c 435 if (!preg_match('/^[+-]{1}[0-9]{4}$/',$dateParts[0])) {
436 /* zone in obs-zone format */
437 if (preg_match('/\((.+)\)/',$dateParts[0],$regs)) {
438 $obs_zone = $regs[1];
439 } else {
440 $obs_zone = $dateParts[0];
441 }
442 return getGMTSeconds($stamp, $obs_zone);
443 } else {
444 return getGMTSeconds($stamp, $dateParts[0]);
0e4ae91a 445 }
0e4ae91a 446}
5e90d34a 447
0e4ae91a 448/* I use this function for profiling. Should never be called in
598294a7 449 actual versions of SquirrelMail released to public. */
d205a7bf 450/*
5e90d34a 451 function getmicrotime() {
452 $mtime = microtime();
b9bfd165 453 $mtime = explode(' ',$mtime);
5e90d34a 454 $mtime = $mtime[1] + $mtime[0];
455 return ($mtime);
9774bdef 456 }
d205a7bf 457*/
3f7e6af3 458?>