15.4. Working with Dates and Times

Zend_Locale_Format provides several methods for working with dates and times to help convert and normalize between different formats for different locales. Use Zend_Date for manipulating dates, and working with date strings that already conform to one of the many internationally recognized standard formats, or one of the localized date formats supported by Zend_Date . Using an existing, pre-defined format offers advantages, including the use of well-tested code, and the assurance of some degree of portability and interoperability (depending on the standard used). The examples below do not follow these recommendations, since using non-standard date formats would needlessly increase the difficulty of understanding these examples.

15.4.1. Normalizing Dates and Times

The getDate() method parses strings containing dates in localized formats. The results are returned in a structured array, with well-defined keys for each part of the date. In addition, the array will contain a key 'format' showing the format string used to parse the input date string. Since a localized date string may not contain all parts of a date/time, the key-value pairs are optional. For example, if only the year, month, and day is given, then all time values are supressed from the returned array, and vice-versa if only hour, minute, and second were given as input. If no date or time can be found within the given input, an exception will be thrown.

Also, the sister method getFixedDate() adds a key 'fixed' with a whole number value indicating if the input date string required "fixing" by rearranging the day, month, or year in the input to fit the format used.

Таблица 15.2. 'fixed' key values

value meaning    
0 nothing to fix    
1 fixed false month    
2 swapped day and year    
3 swapped month and year    
4 swapped month and day    

The following return values are possible, when the BCMath extension is available:

Таблица 15.3. Return values

getDate() format character Array key Returned value Minimum Maximum
d day integer 1 31
M month integer 1 12
y year integer no limit PHP integer's maximum
h hour integer 0 PHP integer's maximum
m minute integer 0 PHP integer's maximum
s second integer 0 PHP integer's maximum

Пример 15.28. Normalizing a date

<?php
require_once 'Zend/Locale.php';

$date = Zend_Locale_Format::getDate('13.04.2006', 'dd.MM.yyyy');
$dateObject = Zend_Date('13.04.2006', 'dd.MM.yyyy'); // creates a Zend_Date object for this date

print_r($date); // outputs:

Array
(
    [format] => dd.MM.yyyy
    [day] => 13
    [month] => 4
    [year] => 2006
)

// alternatively, some types of problems with input data can be automatically corrected
$date2 = Zend_Locale_Format::getFixedDate('04.13.2006', 'dd.MM.yyyy');

print_r($date); // outputs:

Array
(
    [format] => dd.MM.yyyy
    [day] => 13
    [month] => 4
    [year] => 2006
    [fixed] => 4
)
?>

Since getDate() is "locale-aware", specifying the $locale is sufficient for date strings adhering to that locale's format. The method getFixedDate() uses simple tests to determine if the day or month is not valid, and then applies heuristics to try and correct any detected problems.

Пример 15.29. Normalizing a date by locale

<?php
require_once 'Zend/Locale.php';

$locale = new Zend_Locale('de_AT');
$date = Zend_Locale_Format::getDate('13.04.2006', null, $locale);

print_r ($date);
?>

A complete date and time is returned when the input contains both a date and time in the expected format.

Пример 15.30. Normalizing a date with time

<?php
require_once 'Zend/Locale.php';

$locale = new Zend_Locale('de_AT');
$date = Zend_Locale_Format::getDate('13.04.2005 22:14:55', false, $locale);

print_r ($date);
?>

If a specific format is desired, specify the $format argument, without giving a $locale. Only single-letter codes (H, m, s, y, M, d), and MMMM and EEEE are supported in the $format.

Пример 15.31. Normalizing a userdefined date

<?php
require_once 'Zend/Locale.php';

$date = Zend_Locale_Format::getDate('13200504T551422', 'ddyyyyMM ssmmHH');

print_r ($date);
?>

The format can include the following signs :

Таблица 15.4. Format definition

Format Letter Description
d or dd 1 or 2 digit day
M or MM 1 or 2 digit month
y or yy 1 or 2 digit year
yyyy 4 digit year
h 1 or 2 digit hour
m 1 or 2 digit minute
s 1 or 2 digit second

Examples for proper formats are

Таблица 15.5. Example formats

Formats Input Output
dd.MM.yy 1.4.6 ['day'] => 1, ['month'] => 4, ['year'] => 6
dd.MM.yy 01.04.2006 ['day'] => 1, ['month'] => 4, ['year'] => 2006
yyyyMMdd 1.4.6 ['day'] => 6, ['month'] => 4, ['year'] => 1
[Замечание] Database date format

To parse a database date value (f.e. MySql or MsSql), use Zend_Date's ISO_8601 format instead of getDate().

The method getFixedDate() uses simple tests to determine if the day or month is not valid, and then applies heuristics to try and correct any detected problems. getDate() automatically detects and corrects some kinds of problems with input, such as misplacing the year:

Пример 15.32. Automatic correction of input dates

<?php
require_once 'Zend/Locale.php';

$date = Zend_Locale_Format::getFixedDate('41.10.20', 'ddMMyy');

// instead of 41 for the day, the 41 will be returned as year value
print_r ($date);
?>

15.4.2. Testing Dates

Use isDate() to check if a given string contains a valid date. The isDate() method uses getDate(), not getFixedDate() to avoid returning true when the input fails to conform to the date format.

Пример 15.33. Date testing

<?php
require_once 'Zend/Locale.php';

$locale = new Zend_Locale('de_AT');
if (Zend_Locale_Format::isDate('13.Apr.2006', $locale) {
    print "date";
} else {
    print "not a date";
} 
?>

15.4.3. Normalizing a Time

Normally, a time will be returned with a date, if the input contains both. If the proper format is not known, but the locale relevant to the user input is known, then getTime() should be used, because it uses the default time format for the selected locale.

Пример 15.34. Normalize an unknown time

<?php
require_once 'Zend/Locale.php';

$locale = new Zend_Locale('de_AT');
if (Zend_Locale_Format::getTime('13:44:42', $locale) {
    print "time";
} else {
    print "not a time";
} 
?>

15.4.4. Testing Times

Use isTime() to check if a given string contains a proper time.

Пример 15.35. Testing a time

<?php
require_once 'Zend/Locale.php';

$locale = new Zend_Locale('de_AT');
if (Zend_Locale_Format::isTime('13:44:42', $locale) {
    print "time";
} else {
    print "not a time";
} 
?>