fix image text
[pear] / I18N / DateTime.php
1 <?php
2 // +----------------------------------------------------------------------+
3 // | PHP version 4.0                                                      |
4 // +----------------------------------------------------------------------+
5 // | Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003 The PHP Group       |
6 // +----------------------------------------------------------------------+
7 // | This source file is subject to version 2.0 of the PHP license,       |
8 // | that is bundled with this package in the file LICENSE, and is        |
9 // | available at through the world-wide-web at                           |
10 // | http://www.php.net/license/2_02.txt.                                 |
11 // | If you did not receive a copy of the PHP license and are unable to   |
12 // | obtain it through the world-wide-web, please send a note to          |
13 // | license@php.net so we can mail you a copy immediately.               |
14 // +----------------------------------------------------------------------+
15 // | Authors: Wolfram Kriesing <wk@visionp.de>                            |
16 // |                                                                      |
17 // +----------------------------------------------------------------------+//
18 // $Id: DateTime.php 136857 2003-08-07 07:46:23Z cain $
19
20 require_once 'I18N/Format.php';
21
22 define( 'I18N_DATETIME_SHORT' ,         1 );
23 define( 'I18N_DATETIME_DEFAULT' ,       2 );
24 define( 'I18N_DATETIME_MEDIUM' ,        3 );
25 define( 'I18N_DATETIME_LONG' ,          4 );
26 define( 'I18N_DATETIME_FULL' ,          5 );
27
28
29   
30 /**
31 *
32 *   @package    I18N 
33 *
34 */
35 class I18N_DateTime extends I18N_Format
36 {
37
38     // for ZE2 :-)
39 /*
40     const SHORT =   1;
41     const DEFAULT = 2;
42     const MEDIUM =  3;
43     const LONG =    4;
44     const FULL =    5;
45
46     const CUSTOM_FORMATS_OFFSET = 100;
47 */
48
49     var $days = array( 'Sunday' , 'Monday' , 'Tuesday' , 'Wednesday' , 'Thursday' , 'Friday' , 'Saturday' );
50
51     var $daysAbbreviated = array( 'Sun','Mon','Tue','Wed','Thu','Fri','Sat');
52
53     var $monthsAbbreviated = array( 'Jan' , 'Feb' , 'Mar' , 'Apr' , 'May' , 'Jun' ,'Jul' , 'Aug' , 'Sep' , 'Oct' , 'Nov' , 'Dec' );
54
55     var $months = array(
56                             'January',
57                             'February',
58                             'March',
59                             'April',
60                             'May',
61                             'June',
62                             'July',
63                             'August',
64                             'September',
65                             'October',
66                             'November',
67                             'December'
68                          );
69
70     /**
71     *   this var contains the current locale this instace works with
72     *
73     *   @access     protected
74     *   @var        string  this is a string like 'de_DE' or 'en_US', etc.
75     */
76     var $_locale;
77
78     /**
79     *   the locale object which contains all the formatting specs
80     *
81     *   @access     protected
82     *   @var        object
83     */
84     var $_localeObj = null;
85
86     
87     var $_currentFormat = I18N_DATETIME_DEFAULT;
88     var $_currentDateFormat = I18N_DATETIME_DEFAULT;
89     var $_currentTimeFormat = I18N_DATETIME_DEFAULT;
90
91     var $_customFormats = array();
92
93     /**
94     *   Use this method to setup and to retreive the static instance of the I18N_DateTime.
95     *   <code>
96     *   // setup the object with the proper locale
97     *   I18N_DateTime::singleton($locale);
98     *   // and anywhere in your code you can call the following
99     *   // and you get the instance for this very locale, you specified via singleton()
100     *   $dateTime = I18N_DateTime::singleton();
101     *   </code>
102     *
103     *   @static 
104     *   @access public
105     *   @param  string  the locale to use, i.e. 'de_DE'
106     *   @return object  an instance of this class
107     */
108     function &singleton($locale=null)
109     {
110         return I18N_Format::_singleton($locale,__CLASS__);
111     }
112     
113     /**
114     *   returns the timestamp formatted according to the locale and the format-mode
115     *   use this method to format a date and time timestamp
116     *
117     *   @see        setFormat()
118     *   @version    02/11/20
119     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
120     *   @param      int     a timestamp
121     *   @param      int     the formatting mode, using setFormat you can add custom formats
122     *   @return     string  the formatted timestamp
123     *   @access     public
124     */
125     function format($timestamp=null,$format=null)
126     {
127         return $this->_format($timestamp,$format);
128     }
129
130     /**
131     *   returns the timestamp formatted according to the locale and the format-mode
132     *   use this method to get a formatted date only
133     *
134     *   @see        setDateFormat()
135     *   @version    02/11/20
136     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
137     *   @param      int     a timestamp
138     *   @param      int     the formatting mode, use setDateFormat to add custom formats
139     *   @return     string  the formatted timestamp
140     *   @access     public
141     */
142     function formatDate( $timestamp=null , $format=null )
143     {
144         return $this->_formatDateTime($timestamp,$format,'date');
145     }
146
147     /**
148     *   returns the timestamp formatted according to the locale and the format-mode
149     *   use this method to get a formatted time only
150     *
151     *   @see        setTimeFormat()
152     *   @version    02/11/20
153     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
154     *   @param      int     a timestamp
155     *   @param      int     the formatting mode, use setTimeFormat to add custom formats
156     *   @return     string  the formatted timestamp
157     *   @access     public
158     */
159     function formatTime( $timestamp=null , $format=null )
160     {
161         return $this->_formatDateTime($timestamp,$format,'time');
162     }
163
164     /**
165     *   formats a timestamp consisting of date and time
166     *   or a custom timestamp, which was set using setFormat
167     *
168     *   @see        setFormat()
169     *   @version    02/11/20
170     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
171     *   @param      int     a timestamp
172     *   @param      int     the format
173     *   @return     string  the formatted timestamp
174     *   @access     private
175     */
176     function _format( $timestamp , $format )
177     {
178         if ($format == null){
179             $format = $this->getFormat();
180         }
181         if ($timestamp == null){
182             $timestamp = time();
183         }
184
185         if ($format >= I18N_CUSTOM_FORMATS_OFFSET) {
186             if (isset($this->_customFormats[$format])) {
187                 return $this->_translate(date($this->_customFormats[$format],$timestamp));
188             } else {
189                 $format = I18N_DATETIME_DEFAULT;
190             }
191         }
192         return  $this->_formatDateTime($timestamp,$format,'date').' '.
193                 $this->_formatDateTime($timestamp,$format,'time');
194     }
195
196     /**
197     *   this method formats the given timestamp into the given format
198     *
199     *   @see        setFormat()
200     *   @see        setDateFormat()
201     *   @see        setTimeFormat()
202     *   @version    02/11/20
203     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
204     *   @param      int     a timestamp
205     *   @param      int     the formatting mode, use setTimeFormat to add custom formats
206     *   @param      string  either 'date' or 'time' so this method knows what it is currently formatting
207     *   @return     string  the formatted timestamp
208     *   @access     private
209     */
210     function _formatDateTime($timestamp,$format,$what)
211     {
212         $getFormatMethod = 'get'.ucfirst($what).'Format';
213         if ($format == null){
214             $format = $this->$getFormatMethod();
215         }
216         if ($timestamp == null){
217             $timestamp = time();
218         }
219                  
220         $curFormat = I18N_DATETIME_DEFAULT;// just in case the if's below dont find nothing
221         $formatArray = $what.'Formats';
222         if (isset($this->_localeObj->{$formatArray}[$format])) {
223             $curFormat = $this->_localeObj->{$formatArray}[$format];
224         } elseif(isset($this->_customFormats[$format])) {
225             $curFormat = $this->_customFormats[$format];
226         }
227         return $this->_translate(date($curFormat,$timestamp));
228     }
229
230     /**
231     *   this simply translates the formatted timestamp into the locale-language
232     *
233     *   @version    02/11/20
234     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
235     *   @param      string  a human readable timestamp, such as 'Monday, August 7 2002'
236     *   @return     string  the formatted timestamp
237     *   @access     private
238     */
239     function _translate( $string )
240     {
241 //FIXXME optimize this array, use only those that are in the format string, i.e. if no abbreviated formats are used
242 // dont put the abbreviated's in this array ....
243         $translateArrays = array('days','months','daysAbbreviated','monthsAbbreviated');
244
245         // this seems a bit difficult i guess,
246         // but i had problems with the way i did it before, which way simply str_replace the
247         // src-lang array and the dest-lang array, this caused stuff like
248         // translating 'Monday' => 'Montag' and then 'Montag' => 'Motag', since 'Mon'
249         // is the abbreviated weekday for Monday. 
250         // if i would turn it around and translate the abbreviated words first it would screw up worse
251         
252         // so what i do now is searching for the position of words which can be translated and
253         // remember the position (using strpos) and dont translate a word at this position a second
254         // time. this at least prevents the case described above. i hope it covers everything else too
255         // for me it works quite well now
256         $translateSrc =  array();
257         $translateDest = array();
258         $prevPositions = array();
259         foreach ($translateArrays as $aArray) {
260             if (isset($this->_localeObj->{$aArray})) {
261                 foreach ($this->{$aArray} as $index=>$aWord) {
262                     if (($pos=strpos($string,$aWord))!==false && !in_array($pos,$prevPositions)) {
263                         $translateSrc[] = $aWord;
264                         $translateDest[] = $this->_localeObj->{$aArray}[$index];
265                         $prevPositions[] = $pos;
266                     }
267                 }
268             }
269         }
270         // here we actually replace the strings (translate:-)) that we found, when checking for their position
271         $string = str_replace($translateSrc,$translateDest,$string);
272         return $string;
273     }
274
275     /**
276     *   define a custom format given by $format and return the $format-id
277     *   the format-id can be used to call format( x , format-id ) to
278     *   tell the method you want to use the format with that id
279     *
280     *   @see        format()
281     *   @version    02/11/20
282     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
283     *   @param      string  defines a custom format
284     *   @return     int     the format-id, to be used with the format-method
285     */
286     function setFormat( $format=I18N_DATETIME_DEFAULT )
287     {
288         return parent::setFormat( $format );
289     }
290
291     /**
292     *   define a custom format given by $format and return the $format-id
293     *   the format-id can be used to call formatDate( x , format-id ) to
294     *   tell the method you want to use the format with that id
295     *
296     *   @see        formatDate()
297     *   @version    02/11/20
298     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
299     *   @param      string  defines a custom format
300     *   @return     int     the format-id, to be used with the format-method
301     */
302     function setDateFormat( $format=I18N_DATETIME_DEFAULT )
303     {
304         return $this->_setFormat( $format , 'date' );
305     }
306
307     /**
308     *   define a custom format given by $format and return the $format-id
309     *   the format-id can be used to call formatTime( x , format-id ) to
310     *   tell the method you want to use the format with that id
311     *
312     *   @see        formatTime()
313     *   @version    02/11/20
314     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
315     *   @param      string  defines a custom format
316     *   @return     int     the format-id, to be used with the format-method
317     */
318     function setTimeFormat( $format=I18N_DATETIME_DEFAULT )
319     {
320         return $this->_setFormat( $format , 'time' );
321     }
322
323     /**
324     *
325     */
326     function getDateFormat()
327     {
328         return $this->_currentDateFormat;
329     }
330     function getTimeFormat()
331     {
332         return $this->_currentTimeFormat;
333     }  
334                           
335     /**
336     *   get either the current or the given month name
337     *
338     */
339     function getMonthName( $which=null , $abbreviated=false )
340     {
341         if ($which==null) {
342             $which = $date('n')-1;
343         }
344         $monthNames = $this->getMonthNames( $abbreviated );
345         return $monthNames[$which];
346     }
347
348     /**
349     *   get all month names for the current locale
350     *
351     *   get all month names for the current locale,
352     *   fallback to english if not defined
353     *
354     */
355     function getMonthNames($abbreviated=false)
356     {                                          
357         $propName = 'months'.($abbreviated ? 'Abbreviated' : '' );
358         return isset($this->_localeObj->$propName) ? $this->_localeObj->$propName : $this->$propName;
359     }
360
361     function getDayNames($abbreviated=false)
362     {
363         $propName = 'days'.($abbreviated ? 'Abbreviated' : '' );
364         return isset($this->_localeObj->$propName) ? $this->_localeObj->$propName : $this->$propName;
365     }
366
367     //
368     //  all the following are simply convienence methods
369     //  which make it shorter to call the format methods with the default
370     //  formats,
371     //  FIXXME we should use overloading here, well with ZE2 we will!!!!
372     //
373     //  i am not really happy with the following, since it only bloats the code,
374     //  but the methods make sense :-)
375     //
376
377     /**
378     *   convinience method, same as format( $timestamp , I18N_DATETIME_SHORT )
379     *
380     *   this method exists, to have a shorter call to the method
381     *   with a default format I18N_DATETIME_SHORT
382     *
383     *   @see        format()
384     *   @version    02/11/28
385     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
386     *   @param      int     a timestamp
387     *   @return     string  the formatted timestamp
388     *   @access     public
389     */
390     function formatShort( $timestamp=null )
391     {
392         return $this->format( $timestamp , I18N_DATETIME_SHORT );
393     }
394
395     /**
396     *   convinience method, same as format( $timestamp , I18N_DATETIME_DEFAULT )
397     *
398     *   this method exists, to have a shorter call to the method
399     *   with a default format I18N_DATETIME_DEFAULT
400     *
401     *   @see        format()
402     *   @version    02/11/28
403     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
404     *   @param      int     a timestamp
405     *   @return     string  the formatted timestamp
406     *   @access     public
407     */
408     function formatDefault( $timestamp=null )
409     {
410         return $this->format( $timestamp , I18N_DATETIME_DEFAULT );
411     }
412
413     /**
414     *   convinience method, same as format( $timestamp , I18N_DATETIME_MEDIUM )
415     *
416     *   this method exists, to have a shorter call to the method
417     *   with a default format I18N_DATETIME_MEDIUM
418     *
419     *   @see        format()
420     *   @version    02/11/28
421     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
422     *   @param      int     a timestamp
423     *   @return     string  the formatted timestamp
424     *   @access     public
425     */
426     function formatMedium( $timestamp=null )
427     {
428         return $this->format( $timestamp , I18N_DATETIME_MEDIUM );
429     }
430
431     /**
432     *   convinience method, same as format( $timestamp , I18N_DATETIME_LONG )
433     *
434     *   this method exists, to have a shorter call to the method
435     *   with a default format I18N_DATETIME_LONG
436     *
437     *   @see        format()
438     *   @version    02/11/28
439     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
440     *   @param      int     a timestamp
441     *   @return     string  the formatted timestamp
442     *   @access     public
443     */
444     function formatLong( $timestamp=null )
445     {
446         return $this->format( $timestamp , I18N_DATETIME_LONG );
447     }
448
449     /**
450     *   convinience method, same as format( $timestamp , I18N_DATETIME_FULL )
451     *
452     *   this method exists, to have a shorter call to the method
453     *   with a default format I18N_DATETIME_FULL
454     *
455     *   @see        format()
456     *   @version    02/11/28
457     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
458     *   @param      int     a timestamp
459     *   @return     string  the formatted timestamp
460     *   @access     public
461     */
462     function formatFull( $timestamp=null )
463     {
464         return $this->format( $timestamp , I18N_DATETIME_FULL );
465     }
466
467
468
469
470     /**
471     *   convinience method, same as formatDate( $timestamp , I18N_DATETIME_SHORT )
472     *
473     *   this method exists, to have a shorter call to the method
474     *   with a default format I18N_DATETIME_SHORT
475     *
476     *   @see        formatDate()
477     *   @version    02/11/28
478     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
479     *   @param      int     a timestamp
480     *   @return     string  the formatted timestamp
481     *   @access     public
482     */
483     function formatDateShort( $timestamp=null )
484     {
485         return $this->formatDate( $timestamp , I18N_DATETIME_SHORT );
486     }
487
488     /**
489     *   convinience method, same as formatDate( $timestamp , I18N_DATETIME_DEFAULT )
490     *
491     *   this method exists, to have a shorter call to the method
492     *   with a default format I18N_DATETIME_DEFAULT
493     *
494     *   @see        formatDate()
495     *   @version    02/11/28
496     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
497     *   @param      int     a timestamp
498     *   @return     string  the formatted timestamp
499     *   @access     public
500     */
501     function formatDateDefault( $timestamp=null )
502     {
503         return $this->formatDate( $timestamp , I18N_DATETIME_DEFAULT );
504     }
505
506     /**
507     *   convinience method, same as formatDate( $timestamp , I18N_DATETIME_MEDIUM )
508     *
509     *   this method exists, to have a shorter call to the method
510     *   with a default format I18N_DATETIME_MEDIUM
511     *
512     *   @see        formatDate()
513     *   @version    02/11/28
514     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
515     *   @param      int     a timestamp
516     *   @return     string  the formatted timestamp
517     *   @access     public
518     */
519     function formatDateMedium( $timestamp=null )
520     {
521         return $this->formatDate( $timestamp , I18N_DATETIME_MEDIUM );
522     }
523
524     /**
525     *   convinience method, same as formatDate( $timestamp , I18N_DATETIME_LONG )
526     *
527     *   this method exists, to have a shorter call to the method
528     *   with a default format I18N_DATETIME_LONG
529     *
530     *   @see        formatDate()
531     *   @version    02/11/28
532     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
533     *   @param      int     a timestamp
534     *   @return     string  the formatted timestamp
535     *   @access     public
536     */
537     function formatDateLong( $timestamp=null )
538     {
539         return $this->formatDate( $timestamp , I18N_DATETIME_LONG );
540     }
541
542     /**
543     *   convinience method, same as formatDate( $timestamp , I18N_DATETIME_FULL )
544     *
545     *   this method exists, to have a shorter call to the method
546     *   with a default format I18N_DATETIME_FULL
547     *
548     *   @see        formatDate()
549     *   @version    02/11/28
550     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
551     *   @param      int     a timestamp
552     *   @return     string  the formatted timestamp
553     *   @access     public
554     */
555     function formatDateFull( $timestamp=null )
556     {
557         return $this->formatDate( $timestamp , I18N_DATETIME_FULL );
558     }
559
560
561
562
563
564     /**
565     *   convinience method, same as formatTime( $timestamp , I18N_DATETIME_SHORT )
566     *
567     *   this method exists, to have a shorter call to the method
568     *   with a default format I18N_DATETIME_SHORT
569     *
570     *   @see        formatTime()
571     *   @version    02/11/28
572     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
573     *   @param      int     a timestamp
574     *   @return     string  the formatted timestamp
575     *   @access     public
576     */
577     function formatTimeShort( $timestamp=null )
578     {
579         return $this->formatTime( $timestamp , I18N_DATETIME_SHORT );
580     }
581
582     /**
583     *   convinience method, same as formatTime( $timestamp , I18N_DATETIME_DEFAULT )
584     *
585     *   this method exists, to have a shorter call to the method
586     *   with a default format I18N_DATETIME_DEFAULT
587     *
588     *   @see        formatTime()
589     *   @version    02/11/28
590     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
591     *   @param      int     a timestamp
592     *   @return     string  the formatted timestamp
593     *   @access     public
594     */
595     function formatTimeDefault( $timestamp=null )
596     {
597         return $this->formatTime( $timestamp , I18N_DATETIME_DEFAULT );
598     }
599
600     /**
601     *   convinience method, same as formatTime( $timestamp , I18N_DATETIME_MEDIUM )
602     *
603     *   this method exists, to have a shorter call to the method
604     *   with a default format I18N_DATETIME_MEDIUM
605     *
606     *   @see        formatTime()
607     *   @version    02/11/28
608     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
609     *   @param      int     a timestamp
610     *   @return     string  the formatted timestamp
611     *   @access     public
612     */
613     function formatTimeMedium( $timestamp=null )
614     {
615         return $this->formatTime( $timestamp , I18N_DATETIME_MEDIUM );
616     }
617
618     /**
619     *   convinience method, same as formatTime( $timestamp , I18N_DATETIME_LONG )
620     *
621     *   this method exists, to have a shorter call to the method
622     *   with a default format I18N_DATETIME_LONG
623     *
624     *   @see        formatTime()
625     *   @version    02/11/28
626     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
627     *   @param      int     a timestamp
628     *   @return     string  the formatted timestamp
629     *   @access     public
630     */
631     function formatTimeLong( $timestamp=null )
632     {
633         return $this->formatTime( $timestamp , I18N_DATETIME_LONG );
634     }
635
636     /**
637     *   convinience method, same as formatTime( $timestamp , I18N_DATETIME_FULL )
638     *
639     *   this method exists, to have a shorter call to the method
640     *   with a default format I18N_DATETIME_FULL
641     *
642     *   @see        formatTime()
643     *   @version    02/11/28
644     *   @author     Wolfram Kriesing <wolfram@kriesing.de>
645     *   @param      int     a timestamp
646     *   @return     string  the formatted timestamp
647     *   @access     public
648     */
649     function formatTimeFull( $timestamp=null )
650     {
651         return $this->formatTime( $timestamp , I18N_DATETIME_FULL );
652     }
653
654
655 }
656
657 ?>