TigerZF
🌐Español

43.4. Trabajar con fechas y horas

Zend_Locale_Format proporciona varios métodos para trabajar con fechas y horas, para ayudar a convertir y normalizar entre distintos formatos para distintas configuraciones regionales. Use Zend_Date para manipular fechas, y para trabajar con cadenas de fecha que ya se ajusten a uno de los muchos formatos estándar reconocidos internacionalmente, o uno de los formatos de fecha localizados admitidos por Zend_Date. Usar un formato existente y predefinido ofrece ventajas, incluyendo el uso de código bien probado, y la garantía de cierto grado de portabilidad e interoperabilidad (según el estándar utilizado). Los ejemplos siguientes no siguen estas recomendaciones, ya que usar formatos de fecha no estándar aumentaría innecesariamente la dificultad para entender estos ejemplos.

43.4.1. Normalizar fechas y horas

El método getDate() analiza cadenas que contienen fechas en formatos localizados. Los resultados se devuelven en un array estructurado, con claves bien definidas para cada parte de la fecha. Además, el array contendrá una clave 'date_format' que muestra la cadena de formato usada para analizar la cadena de fecha de entrada. Dado que una cadena de fecha localizada puede no contener todas las partes de una fecha/hora, los pares clave-valor son opcionales. Por ejemplo, si solo se proporcionan el año, el mes y el día, entonces todos los valores de hora se suprimen del array devuelto, y viceversa si solo se proporcionaron la hora, el minuto y el segundo como entrada. Si no se puede encontrar ninguna fecha u hora dentro de la entrada dada, se lanzará una excepción.

Si se establece setOption(array('fix_date' => true)), el método getDate() añade una clave 'fixed' con un valor numérico entero que indica si la cadena de fecha de entrada requirió "arreglos" reorganizando el día, el mes o el año en la entrada para ajustarse al formato utilizado.

Tabla 43.5. Valores clave para getDate() con la opción 'fix_date'

valor significado
0 nada que arreglar
1 mes incorrecto arreglado
2 día y año intercambiados
3 mes y año intercambiados
4 mes y día intercambiados

Para quienes necesiten especificar explícitamente el formato de la cadena de fecha, se admiten los siguientes especificadores de token de formato. Si se usa un especificador de formato no válido, como el especificador 'i' de PHP en el modo de formato ISO, entonces se lanzará un error por los métodos de Zend_Locale_Format que admiten formatos definidos por el usuario.

Estos especificadores (a continuación) son un pequeño subconjunto del conjunto "ISO" completo admitido por toString() de Zend_Date. Si necesita usar especificadores de formato compatibles con date() de PHP, primero llame a setOptions(array('format_type' => 'php')). Y si desea convertir solo una cadena de formato especial del formato compatible con date() de PHP al formato "ISO", use convertPhpToIsoFormat(). Actualmente, la única diferencia práctica se refiere al especificador de minutos ('m' usando el valor predeterminado ISO, y 'i' usando el formato de fecha de PHP).

Tabla 43.6. Valores de retorno

carácter de formato de getDate() Clave del array Valor devuelto Mínimo Máximo
d day entero 1 31
M month entero 1 12
y year entero sin límite Máximo de un entero de PHP
h hour entero 0 Máximo de un entero de PHP
m minute entero 0 Máximo de un entero de PHP
s second entero 0 Máximo de un entero de PHP

Ejemplo 43.43. Normalizar una fecha

$dateString = Zend_Locale_Format::getDate(
    '13.04.2006',
    array(
        'date_format' => 'dd.MM.yyyy',
    )
);

print_r($dateString); // outputs:

Array
(
    [date_format] => dd.MM.yyyy
    [locale] => de_DE
    [day] => 13
    [month] => 04
    [year] => 2006
)

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

print_r($dateObject); // outputs:

Zend_Date Object
(
    [_locale:Zend_Date:private] => de_DE
    [_fractional:Zend_Date:private] => 0
    [_precision:Zend_Date:private] => 3
    [_unixTimestamp:Zend_Date_DateObject:private] => 1144879200
    [_timezone:Zend_Date_DateObject:private] => Europe/Berlin
    [_offset:Zend_Date_DateObject:private] => -3600
    [_syncronised:Zend_Date_DateObject:private] => 0
    [_dst:protected] => 1
)

// alternatively, some types of problems with input data can be
// automatically corrected
$date = Zend_Locale_Format::getDate(
    '04.13.2006',
    array(
        'date_format' => 'dd.MM.yyyy',
        'fix_date'    => true,
    )
);

print_r($date); // outputs:

Array
(
    [date_format] => dd.MM.yyyy
    [locale] => de_DE
    [day] => 13
    [month] => 04
    [year] => 2006
    [fixed] => 4
)

Dado que getDate() "tiene en cuenta la configuración regional", especificar $locale es suficiente para cadenas de fecha que se ajusten al formato de esa configuración regional. La opción 'fix_date' usa pruebas simples para determinar si el día o el mes no son válidos, y luego aplica heurísticas para intentar corregir cualquier problema detectado. Observe el uso de 'Zend_Locale_Format::STANDARD' como el valor de 'date_format' para evitar el uso de un formato de fecha predeterminado a nivel de clase establecido mediante setOptions(). Esto obliga a getDate a usar el formato de fecha predeterminado para $locale.

Ejemplo 43.44. Normalizar una fecha según la configuración regional

$locale = new Zend_Locale('de_AT');
$date = Zend_Locale_Format::getDate('13.04.2006',
                                    array('date_format' =>
                                              Zend_Locale_Format::STANDARD,
                                          'locale' => $locale)
                                   );

print_r ($date);

Se devuelve una fecha y hora completa cuando la entrada contiene tanto una fecha como una hora en el formato esperado.

Ejemplo 43.45. Normalizar una fecha con hora

$locale = new Zend_Locale('de_AT');
$date = Zend_Locale_Format::getDate('13.04.2005 22:14:55',
                                    array('date_format' =>
                                                Zend_Locale_Format::STANDARD,
                                          'locale' => $locale)
                                    );

print_r ($date);

Si se desea un formato específico, especifique el argumento $format, sin proporcionar un $locale. Solo se admiten los códigos de una sola letra (H, m, s, y, M, d), así como MMMM y EEEE, en $format.

Ejemplo 43.46. Normalizar una fecha definida por el usuario

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

print_r ($date);

El formato puede incluir los siguientes signos:

Tabla 43.7. Definición de formato

Letra de formato Descripción
d o dd día de 1 o 2 dígitos
M o MM mes de 1 o 2 dígitos
y o yy año de 1 o 2 dígitos
yyyy año de 4 dígitos
h hora de 1 o 2 dígitos
m minuto de 1 o 2 dígitos
s segundo de 1 o 2 dígitos

Ejemplos de formatos correctos son

Tabla 43.8. Ejemplos de formato

Formatos Entrada Salida
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

[Note] Formato de fecha de base de datos

Para analizar un valor de fecha de base de datos (por ejemplo, MySql o MsSql), use el formato ISO_8601 de Zend_Date en lugar de getDate().

La opción 'fix_date' usa pruebas simples para determinar si el día o el mes no son válidos, y luego aplica heurísticas para intentar corregir cualquier problema detectado. getDate() detecta y corrige automáticamente algunos tipos de problemas con la entrada, como colocar el año en la posición incorrecta:

Ejemplo 43.47. Corrección automática de fechas de entrada

$date = Zend_Locale_Format::getDate('41.10.20',
                                    array('date_format' => 'ddMMyy',
                                          'fix_date' => true)
                                   );

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

43.4.2. Probar fechas

Use checkDateFormat($inputString, array('date_format' => $format, $locale)) para comprobar si una cadena dada contiene todas las partes de fecha esperadas. El método checkDateFormat() usa getDate(), pero sin la opción 'fixdate' para evitar devolver TRUE cuando la entrada no se ajusta al formato de fecha. Si se detectan errores en la entrada, como valores intercambiados de meses y días, el método con la opción 'fixdate' aplicará heurísticas para "corregir" las fechas antes de determinar su validez.

Ejemplo 43.48. Prueba de fecha

$locale = new Zend_Locale('de_AT');
// using the default date format for 'de_AT', is this a valid date?
if (Zend_Locale_Format::checkDateFormat('13.Apr.2006',
                                        array('date_format' =>
                                                  Zend_Locale_Format::STANDARD,
                                              $locale)
                                       ) {
    print "date";
} else {
    print "not a date";
}

43.4.3. Normalizar una hora

Normalmente, se devolverá una hora junto con una fecha, si la entrada contiene ambas. Si no se conoce el formato adecuado, pero sí la configuración regional relevante para la entrada del usuario, entonces debe usarse getTime(), porque utiliza el formato de hora predeterminado para la configuración regional seleccionada.

Ejemplo 43.49. Normalizar una hora desconocida

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

43.4.4. Probar horas

Use checkDateFormat() para comprobar si una cadena dada contiene una hora correcta. El uso es exactamente el mismo que al comprobar fechas, solo que date_format debe contener las partes que se espera tener.

Ejemplo 43.50. Probar una hora

$locale = new Zend_Locale('de_AT');
if (Zend_Locale_Format::checkDateFormat('13:44:42',
                                        array('date_format' => 'HH:mm:ss',
                                              'locale' => $locale)) {
    print "time";
} else {
    print "not a time";
}