Pregunta y expectativas
Si bien la forma literal de esta pregunta es práctica en su contexto (año 1899), es un poco vaga en sentido teórico. ¿Qué edad tiene edad? ¿Qué tan lejos en el pasado podríamos querer llegar? ¿Qué pasa con el futuro?
Desde que WordPress comenzó como motor de blogs, en ese sentido contextual evolucionó para manejar el siguiente período de tiempo:
- fechas en que WP existió (obviamente para poder usarlo)
- gama de posibles publicaciones históricas (implícitamente desde Internet)
- Lo más lejos posible en el futuro sin un esfuerzo especial (trabajar hasta que se rompa)
A medida que el uso de WordPress evolucionó hacia aplicaciones que no son de blogs, tales proyectos (comúnmente historia y arte, como he visto en los informes) comenzaron a atacar varios problemas con fechas fuera de este lapso.
A los fines de mi investigación, formulé las siguientes preguntas:
- ¿Cuáles son los dos primeros y más completos años calendario completos, que se pueden usar con las fechas de publicación de WordPress de forma nativa y confiable?
- ¿Qué son las frutas bajas (si las hay) para extender el alcance disponible más allá del rango nativo?
Limitaciones de la plataforma
Dado que WordPress es una aplicación PHP y usa MySQL para el almacenamiento de datos, está sujeto a sus limitaciones.
MySQL
WordPress almacena las fechas de publicación en una post_date
columna de DATETIME
tipo en MySQL.
Según la documentación, este tipo admite los años 1000 a 9999 :
El DATETIME
tipo se utiliza para valores que contienen partes de fecha y hora. MySQL recupera y muestra DATETIME
valores en 'YYYY-MM-DD HH:MM:SS'
formato. El rango admitido es '1000-01-01 00:00:00'
a '9999-12-31 23:59:59'
.
Sin embargo, también dice que los valores anteriores podrían funcionar, sin mencionar los valores posteriores:
Para las DATE and DATETIME
descripciones de rango, "compatible" significa que aunque los valores anteriores podrían funcionar, no hay garantía.
Si bien empíricamente he observado valores fuera de rango, esto es anecdótico y cae fuera de nuestra condición de confiabilidad.
PHP
En la programación PHP, la representación de fecha y hora de Unix es ampliamente utilizada. De acuerdo con la documentación para nuestros fines (PHP 5.2+ y entorno genérico de 32 bits) es compatible con años (en su totalidad) 1902 a 2037 :
El rango válido de una marca de tiempo es típicamente de Fri, 13 Dec 1901 20:45:54 UTC
a Tue, 19 Jan 2038 03:14:07 UTC
. (Estas son las fechas que corresponden a los valores mínimos y máximos para un entero con signo de 32 bits). Además, no todas las plataformas admiten marcas de tiempo negativas, por lo tanto, su rango de fechas puede estar limitado a no antes de la época de Unix. Esto significa que, por ejemplo, las fechas anteriores Jan 1, 1970
no funcionarán en Windows, algunas distribuciones de Linux y algunos otros sistemas operativos. Sin embargo, PHP 5.1.0 y las versiones más nuevas superan esta limitación.
Además de ese Date/Time
manejo basado más nuevo, es de 64 bits y tiene un rango de aproximadamente -292 mil millones a 292 mil millones de años , lo que probablemente excede las necesidades de la humanidad en este momento.
Limitaciones de WordPress
WordPress presenta y hereda algunas limitaciones adicionales en su base de código.
Flujo de datos
Desde el punto de vista del flujo de trabajo básico del usuario, hay dos procesados relacionados con la fecha:
- La entrada de fecha en el formulario de edición posterior debe procesarse correctamente y guardarse en la base de datos
- la fecha guardada en la base de datos debe leerse correctamente y mostrarse en la interfaz
Tenga en cuenta que estos son procesos técnicamente completamente diferentes e independientes. Como se explicó más adelante, sus rangos no se superponen y guardar la fecha correcta no equivale a la capacidad de leerlo correctamente en el entorno de WordPress.
Límites explícitos
- El editor de publicaciones de WordPress en administración permite un rango de años, que se pueden enviar como fecha de publicación, 100 a 9999
_wp_translate_postdata()
procesa el año (presentado como un número distinto del formulario) y:
- lo desinfecta a no negativo > 0
- lo valida usando
wp_checkdate()
, que llama PHP nativo checkdate()
, que impone un límite de 1 a 32767
Límites implícitos
strtotime()
La función PHP se usa varias veces y está sujeta a la marca de tiempo Unix mencionada anteriormente, en el nivel más bajo mysql2date()
que afecta a todas las lecturas de fechas de la base de datos, rango heredado de 1902 a 2037
- WordPress recurre a la expresión regular para el análisis de fechas
get_gmt_from_date()
, que espera que el año sea ([0-9]{1,4})
, limitando de 1 a 9999 , una fuerte posibilidad de procesamiento similar en otras funciones que requerirán una auditoría de código más exhaustiva para enumerarse
Posibilidad de soluciones alternativas
wp_checkdate()
tiene wp_checkdate
filtro, que permite anular esta verificación de validación
- la salida dirigida al usuario final atraviesa
date_i18n()
y tiene date_i18n
filtro, teóricamente permite interceptar y reprocesar completamente la salida de fechas para la interfaz, sin embargo, es un desafío si la función ya se pasa fuera de rango ( false
) entrada de marca de tiempo
Conclusiones
A efectos prácticos y de portabilidad de datos, el intervalo de fechas de publicación de WordPress parece ser igual al de la marca de tiempo Unix de 32 bits y consta de los años 1902 a 2037 inclusive .
Para cualquier operación posterior a la fecha, se debe auditar el entorno fuera de este rango (rango de 64 bits de marcas de tiempo Unix, MySQL que funciona de facto o almacenamiento de base de datos alternativo para los valores). Para rangos más lejanos ( por debajo de 1000, por encima de 9999 ) es probable que se requieran cantidades considerables de código personalizado.
Para cualquier implementación de fechas arbitrarias tiene sentido:
- almacenarlos en MySQL en formato no sujeto a limitaciones de la base de datos
- proceso en PHP usando
Date/Time
código completamente personalizado y / o funciones de WordPress auditadas para no verse afectadas por los límites de marca de tiempo de Unix
Código de prueba de cama
El siguiente código y el conjunto de años seleccionados a mano se han utilizado para la investigación anterior y la prueba de conclusiones:
require ABSPATH . '/wp-admin/includes/post.php';
$timestamp_size_info = array(
'PHP_INT_SIZE' => PHP_INT_SIZE,
'PHP_INT_MAX' => number_format( PHP_INT_MAX ),
'min timestamp' => date( DATE_ISO8601, - PHP_INT_MAX ),
'zero timestamp' => date( DATE_ISO8601, 0 ),
'max timestamp' => date( DATE_ISO8601, PHP_INT_MAX ),
);
r( $timestamp_size_info );
// hand picked set of years to test for assorted limits
$years = array(
'negative' => - 1,
'zero' => 0,
'one' => 1,
'wp min' => 100,
'mysql first' => 1000,
'before unix' => 1899,
'unix first' => 1902,
'current' => 2013,
'unix last' => 2037,
'after unix' => 2039,
'mysql last, wp max' => 9999,
'after checkdate' => 33000,
);
// simulates form submission data
$post = array(
'post_type' => 'post', // shut notice
'edit_date' => 1,
'aa' => 1,
'mm' => '01',
'jj' => '01',
'hh' => '00',
'mn' => '00',
'ss' => '00',
);
// add_filter( 'wp_checkdate', '__return_true' );
foreach ( $years as $name => $year ) {
$post['aa'] = $year;
$translated = _wp_translate_postdata( false, $post );
if ( is_wp_error( $translated ) ) { // wp_checkdate() failed
r( array( 'year' => $year . " ({$name})", 'translated valid' => false ) );
}
else {
$post_date = $translated['post_date'];
$post_date_gmt = $translated['post_date_gmt'];
$translated_valid = (string) $year == substr( $post_date, 0, strpos( $post_date, '-' ) );
$mysql2date = mysql2date( DATE_ISO8601, $post_date );
$mysql2date_valid = (string) $year == substr( $mysql2date, 0, strpos( $mysql2date, '-' ) );
r( array(
'year' => $year . " ({$name})",
'post_date' => $post_date,
'translated valid' => $translated_valid,
'post_date_gmt' => $post_date_gmt,
'mysql2date' => $mysql2date,
'from sql valid' => $mysql2date_valid,
) );
}
}