Pergunta e expectativas
Embora a forma literal desta questão seja prática no contexto (ano de 1899), é um pouco vaga no sentido teórico. Quantos anos tem a idade? Até onde no passado podemos querer ir? E o futuro?
Desde que o WordPress começou como mecanismo de blog, nesse sentido contextual , ele evoluiu para lidar com o seguinte período de tempo:
- datas em que o WP existia (obviamente, para poder usá-lo)
- gama de possíveis postagens históricas (implicitamente já na Internet)
- o mais longe possível no futuro, sem esforço especial (trabalhe até que se quebre)
À medida que o uso do WordPress evoluiu para aplicativos que não são de blog, esses projetos (geralmente história e arte, como eu já vi nos relatórios) começaram a atingir vários problemas com datas fora desse período.
Para o propósito de minha pesquisa, formulei as seguintes perguntas:
- Quais são os dois primeiros e mais recentes anos civis completos, que podem ser usados com as datas de postagem do WordPress de forma nativa e confiável?
- O que são frutas baixas (se houver) para estender a extensão disponível além da faixa nativa?
Limitações da plataforma
Como o WordPress é um aplicativo PHP e usa o MySQL para armazenamento de dados, está sujeito às suas limitações.
MySQL
O WordPress armazena as datas de postagem na post_date
coluna do DATETIME
tipo no MySQL.
De acordo com a documentação, esse tipo suporta os anos 1000 a 9999 :
O DATETIME
tipo é usado para valores que contêm partes de data e hora. O MySQL recupera e exibe DATETIME
valores em 'YYYY-MM-DD HH:MM:SS'
formato. O intervalo suportado é '1000-01-01 00:00:00'
para '9999-12-31 23:59:59'
.
No entanto, também diz que valores anteriores podem funcionar, sem menção de valores posteriores:
Para as DATE and DATETIME
descrições de intervalo, "suportado" significa que, embora os valores anteriores possam funcionar, não há garantia.
Embora empiricamente eu tenha observado valores fora do intervalo de trabalho, isso é anedótico e fica fora da nossa condição de confiabilidade.
PHP
Na programação PHP, a representação de data e hora do Unix é amplamente usada. De acordo com a documentação para nossos propósitos (PHP 5.2+ e ambiente genérico de 32 bits), ele suporta os anos (na íntegra) de 1902 a 2037 :
O intervalo válido de um carimbo de data / hora é tipicamente de Fri, 13 Dec 1901 20:45:54 UTC
até Tue, 19 Jan 2038 03:14:07 UTC
. (Essas são as datas que correspondem aos valores mínimo e máximo para um número inteiro assinado de 32 bits.) Além disso, nem todas as plataformas oferecem suporte a carimbos de data e hora negativos, portanto, o período pode ser limitado a não mais cedo do que a época do Unix. Isso significa que, por exemplo, datas anteriores a Jan 1, 1970
não funcionarão no Windows, em algumas distribuições Linux e em alguns outros sistemas operacionais. O PHP 5.1.0 e versões mais recentes superam essa limitação.
Além disso, o Date/Time
manuseio mais recente é de 64 bits e varia de aproximadamente -292 a 292 bilhões de anos , o que provavelmente excede as necessidades da humanidade no momento.
Limitações do WordPress
O WordPress introduz e herda algumas limitações adicionais em sua base de código.
Fluxo de dados
Do ponto de vista básico do fluxo de trabalho do usuário, existem dois processados relacionados à data:
- A entrada de data no formulário pós-edição deve ser corretamente processada e salva no banco de dados
- A data salva no banco de dados deve ser corretamente lida e mostrada na interface
Observe que esses são processos tecnicamente completamente diferentes e independentes. Como explicado mais detalhadamente, seus intervalos não se sobrepõem e salvar a data correta não é igual à capacidade de lê-la corretamente no ambiente do WordPress.
Limites explícitos
- O editor de postagem do WordPress em admin permite um intervalo de anos, que pode ser enviado como data de postagem, de 100 a 9999
_wp_translate_postdata()
processa o ano (enviado como número distinto do formulário) e:
- desinfeta para não-negativo > 0
- valida usando
wp_checkdate()
, que chama PHP nativo checkdate()
, que impõe limite de 1 a 32767
Limites implícitos
strtotime()
A função PHP é usada várias vezes e está sujeita ao carimbo de data e hora do Unix acima mencionado, no nível mais baixo mysql2date()
que afeta todas as leituras de datas do banco de dados, intervalo herdado de 1902 a 2037
- O WordPress volta à expressão regular para a análise de datas
get_gmt_from_date()
, que espera que o ano seja ([0-9]{1,4})
, limitando de 1 a 9999 , forte possibilidade de processamento semelhante em outras funções que exigirão que uma auditoria de código mais completa seja enumerada
Possibilidade de soluções alternativas
wp_checkdate()
possui wp_checkdate
filtro, o que permite substituir essa verificação de validação
- a saída destinada ao usuário final através da
date_i18n()
qual possui date_i18n
filtro, teoricamente permite interceptar e reprocessar completamente a saída de datas para fazer a interface, por mais desafiador que seja se a função já for ultrapassada (fora da faixa ( false
))
Conclusões
Para propósitos práticos e portabilidade dos dados, o período de postagem do WordPress parece ser igual ao carimbo de data e hora do Unix de 32 bits e consiste nos anos de 1902 a 2037, inclusive .
Para qualquer operação pós-data fora deste intervalo, o ambiente deve ser auditado (intervalo de 64 bits de registros de data e hora Unix, MySQL funcionando de fato ou armazenamento de banco de dados alternativo para os valores). Para intervalos maiores ( abaixo de 1000, acima de 9999 ), é provável que sejam necessárias quantidades consideráveis de código personalizado.
Para qualquer implementação de datas arbitrárias, faz sentido:
- armazená-los no MySQL em formato não sujeito a limitações do banco de dados
- processo em PHP usando
Date/Time
código completamente personalizado e / ou funções do WordPress auditadas para não serem afetadas pelos limites de carimbo de data / hora do Unix
Cama de teste de código
O código a seguir e o conjunto de anos escolhido a dedo foram usados para a pesquisa acima e o teste de conclusões:
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,
) );
}
}