Câu hỏi và mong đợi
Trong khi hình thức nghĩa đen của câu hỏi này là thực tế trong bối cảnh (năm 1899), nó hơi mơ hồ trong ý nghĩa lý thuyết. Bao nhiêu tuổi Chúng ta có thể muốn đi bao xa trong quá khứ ? Còn tương lai thì sao?
Vì WordPress đã bắt đầu như một công cụ viết blog, theo nghĩa ngữ cảnh đó, nó đã phát triển để xử lý khoảng thời gian sau:
- ngày WP tồn tại (rõ ràng là có thể sử dụng nó)
- một loạt các bài viết lịch sử có thể (hoàn toàn xa như Internet tồn tại)
- càng xa trong tương lai càng tốt mà không cần nỗ lực đặc biệt (làm việc cho đến khi nó phá vỡ)
Khi việc sử dụng WordPress phát triển thành các ứng dụng không viết blog, các dự án (thường là lịch sử và nghệ thuật như tôi đã thấy từ các báo cáo) bắt đầu gặp phải các vấn đề với các ngày nằm ngoài phạm vi này.
Với mục đích nghiên cứu của tôi, tôi đã đặt ra các câu hỏi sau:
- Hai năm đầy đủ sớm nhất và mới nhất, có thể được sử dụng với ngày đăng bài WordPress một cách tự nhiên và đáng tin cậy là gì?
- Trái cây treo thấp (nếu có) để mở rộng khoảng khả dụng ngoài phạm vi bản địa là gì?
Giới hạn nền tảng
Vì WordPress là ứng dụng PHP và sử dụng MySQL để lưu trữ dữ liệu nên nó chịu những hạn chế của chúng.
MySQL
WordPress lưu trữ ngày đăng trong post_date
cột DATETIME
loại trong MySQL.
Theo tài liệu loại này hỗ trợ năm 1000 đến 9999 :
Các DATETIME
loại được sử dụng cho các giá trị có chứa cả ngày và các bộ phận thời gian. MySQL lấy và hiển thị DATETIME
các giá trị ở 'YYYY-MM-DD HH:MM:SS'
định dạng. Phạm vi được hỗ trợ là '1000-01-01 00:00:00'
để '9999-12-31 23:59:59'
.
Tuy nhiên, nó cũng nói rằng các giá trị trước đó có thể hoạt động, không đề cập đến các giá trị sau:
Đối với các DATE and DATETIME
mô tả phạm vi, các bộ phận được hỗ trợ, có nghĩa là các giá trị trước đó có thể hoạt động, không có gì đảm bảo.
Mặc dù theo kinh nghiệm tôi đã quan sát các giá trị ngoài phạm vi hoạt động, đây là giai thoại và nằm ngoài điều kiện tin cậy của chúng tôi.
PHP
Trong lập trình PHP, biểu diễn dấu thời gian của Unix được sử dụng rộng rãi. Theo tài liệu cho các mục đích của chúng tôi (PHP 5.2+ và môi trường 32 bit chung), nó hỗ trợ nhiều năm (đầy đủ) 1902 đến 2037 :
Phạm vi hợp lệ của dấu thời gian thường là từ Fri, 13 Dec 1901 20:45:54 UTC
đến Tue, 19 Jan 2038 03:14:07 UTC
. (Đây là những ngày tương ứng với các giá trị tối thiểu và tối đa cho số nguyên có chữ ký 32 bit.) Ngoài ra, không phải tất cả các nền tảng đều hỗ trợ dấu thời gian âm, do đó phạm vi ngày của bạn có thể bị giới hạn không sớm hơn thời gian Unix. Điều này có nghĩa là ví dụ ngày trước Jan 1, 1970
sẽ không hoạt động trên Windows, một số bản phân phối Linux và một vài hệ điều hành khác. PHP 5.1.0 và các phiên bản mới hơn khắc phục hạn chế này mặc dù.
Khác với Date/Time
xử lý dựa trên mới hơn là 64 bit và có phạm vi khoảng -292 tỷ đến 292 tỷ năm , có lẽ vượt quá nhu cầu của nhân loại tại thời điểm này.
Hạn chế của WordPress
WordPress giới thiệu và kế thừa một số giới hạn bổ sung trong cơ sở mã của nó.
Dòng dữ liệu
Từ quan điểm công việc cơ bản của người dùng, có hai xử lý liên quan đến ngày:
- ngày nhập trong mẫu chỉnh sửa bài phải được xử lý và lưu chính xác trong cơ sở dữ liệu
- ngày lưu trong cơ sở dữ liệu phải được đọc và hiển thị chính xác trong giao diện
Lưu ý rằng đây là những quy trình độc lập và hoàn toàn khác nhau về mặt kỹ thuật. Như đã giải thích thêm, phạm vi của chúng không trùng nhau và lưu ngày chính xác không bằng khả năng đọc chính xác trong môi trường WordPress.
Giới hạn rõ ràng
- Trình chỉnh sửa bài đăng WordPress trong quản trị viên cho phép phạm vi nhiều năm, có thể được gửi dưới dạng ngày đăng, từ 100 đến 9999
_wp_translate_postdata()
năm quy trình (được gửi dưới dạng số khác biệt từ biểu mẫu) và:
- vệ sinh nó để không âm > 0
- xác nhận nó bằng cách sử dụng
wp_checkdate()
, gọi PHP gốc checkdate()
, áp đặt giới hạn từ 1 đến 32767
Giới hạn ngầm định
strtotime()
Hàm PHP được sử dụng nhiều lần và tuân theo dấu thời gian Unix đã đề cập ở trên, ở mức thấp nhất trong mysql2date()
đó ảnh hưởng đến tất cả các lần đọc ngày từ cơ sở dữ liệu, phạm vi 1902 đến 2037 được kế thừa
- WordPress quay trở lại biểu thức thông thường để phân tích ngày
get_gmt_from_date()
, dự kiến sẽ có năm ([0-9]{1,4})
, giới hạn từ 1 đến 9999 , khả năng xử lý tương tự mạnh mẽ trong các chức năng khác sẽ yêu cầu kiểm toán mã kỹ lưỡng hơn để được liệt kê
Khả năng giải quyết
wp_checkdate()
có wp_checkdate
bộ lọc, cho phép ghi đè kiểm tra xác thực này
- đầu ra nhằm vào người dùng cuối đi qua
date_i18n()
có date_i18n
bộ lọc, về mặt lý thuyết cho phép chặn hoàn toàn và xử lý lại đầu ra của ngày để giao diện, tuy nhiên thách thức nếu chức năng được đưa ra khỏi phạm vi false
đầu vào dấu thời gian ( )
Kết luận
Đối với các mục đích thực tế và tính di động của dữ liệu, phạm vi ngày đăng bài của WordPress dường như bằng với dấu thời gian Unix 32 bit và bao gồm các năm từ 1902 đến 2037 .
Đối với mọi hoạt động ngày đăng ngoài môi trường phạm vi này phải được kiểm tra (phạm vi dấu thời gian Unix 64 bit, MySQL thực tế hoạt động hoặc lưu trữ cơ sở dữ liệu thay thế cho các giá trị). Đối với phạm vi xa hơn ( dưới 1000, trên 9999 ), số lượng đáng kể mã tùy chỉnh có thể được yêu cầu.
Đối với bất kỳ việc thực hiện ngày tùy ý, nó có ý nghĩa:
- lưu trữ chúng trong MySQL ở định dạng không bị giới hạn cơ sở dữ liệu
- xử lý trong PHP bằng cách sử dụng
Date/Time
mã hoàn toàn tùy chỉnh và / hoặc các chức năng WordPress được kiểm toán để không bị ảnh hưởng bởi các giới hạn dấu thời gian của Unix
Mã kiểm tra giường
Bộ mã và tập hợp các năm được chọn sau đây đã được sử dụng để nghiên cứu ở trên và kiểm tra kết luận:
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,
) );
}
}