无法在Wordpress中选择旧日期


13

我无法将年份设置为1899年以下。如果我将年份设置为低于1899,则会自动设置为当前年份。

屏幕截图

我已经购买了时间轴主题,并在他们的支持论坛中进行了询问。他们回答:

这听起来像是您的托管服务提供商创建的限制。主题没有什么妨碍您分配日期–如您所见,演示中的帖子使用的日期是1400年代。尝试与您的托管服务提供商联系,看看他们是否对解决该问题有任何见解。


2
您的问题是什么?那里有成千上万的主题-假设有人会知道您购买的主题,这是一个漫长的过程。您至少必须提供相关代码。
Johannes Pille 2013年

1
我怀疑这是主人的错。我假设这是关于保存到数据库的值。打开WP_DEBUG并将错误消息编辑为您的问题。我可能看起来像这样,但是链接到所讨论主题的有效版本确实没有多大帮助。
Johannes Pille 2013年

1
这是一个合法的问题。它与主题无关。我可以重现此问题。看到这个动画的屏幕截图
fuxia

1
1900年和1901年都有同样的问题,但1902年有效;-)
birgire

1
我可以重现这一点,顺便说一下,在Unix时间戳范围(2038)以上也存在问题。Win7x64上的PHP 5.4
Rarst 2013年

Answers:


10

这并不是真正的答案,而只是试图找到此问题的特定上下文。请在您的网站上安装以下插件,尝试设置三个日期并将结果添加到<pre>下表中的第二个日期。

/* Plugin Name: WPSE Sysinfo */
add_action( 'admin_footer', 'wpse_sysinfo' );
function wpse_sysinfo() {

    $bit         = 4 === PHP_INT_SIZE ? 32 : 64; // PHP version, not OS!
    $php_version = PHP_VERSION;
    $db_version  = $GLOBALS['wpdb']->db_version();

    print "<pre>$bit | $php_version | $db_version</pre>";
}

插件的要领可以在这里查看

操作系统| 操作系统位| PHP | PHP位| MySQL | 999 | 1899 | 2020 | 2039 | 用户
WIN7 | 64 | 5.4.4 | ?? | 5.5.25 | ✘| ✘| ✔| ✘| 托斯科
Linux | ?? | 5.3.18-nmm1 | ?? | 5.1.70 | ✔| ✔| ✔| ✔| 托斯科
CentOS 6 | 64 | 5.5.4 | ?? | 5.0.95 | ✔| ✔| ✔| ✔| 托斯科
WIN7 | 64 | 5.4.15 | 32 | 5.5.31 | ✘| ✘| ✔| ✘| rarst
Ubuntu 12.04 | 64 | 5.3.10-1 | 64 | 5.5.32 | ✔| ✔| ✔| ✔| 皮尔
CloudLinux | 64 | 5.2.17 | 64 | 5.0.96 | ✔| ✔| ✔| ✔| 皮尔
Ubuntu 12.10 | 64 | 5.4.6 | 64 | 5.5.32 | ✔| ✔| ✔| ✔| 迈克尔·埃克伦德
CENTOS 5.9 | 32 | 5.3.27 | 32 | 5.5.32 | ✘| ✘| ✔| ✘| 迈克尔·埃克伦德
WIN7 | 64 | 5.4.7 | 64 | 5.5.27 | ✘| ✘| ✔| ✘| 凯撒
OSX 10.7.5 | 64 | 5.3.6 | 64 | 5.5.9 | ✔| ✔| ✔| ✔| 鬼吐司
Centos 6.4 | 64 | 5.4.17 | 32 | 5.1.59 | ✘| ✘| ✔| ✘| 比尔吉雷
Debian 6 | 64 | 5.4.19 | 64 | 5.1.66 | ✘| ✘| ✔| ✘| 比尔吉雷
WIN7 | 64 | 5.5.0 | 64 | 5.5.22 | ✘| ✘| ✔| ✘| 通用汽车
OSX 10.7.4 | 64 | 5.3.6 | 64 | 5.5.9 | ✔| ✔| ✔| ✔| 布拉索菲洛
CentOS 5 | 64 | 5.3.22 | 64 | 5.1.68 | ✔| ✔| ✔| ✔| 布拉索菲洛
Mac 10.8.5 | 64 | 5.3.26 | 64 | 5.5.25 | ✔| ✔| ✔| ✔| 芬蒂尼
WIN7 | 64 | 5.3.27 | 64 | 5.5.31 | ✔| ✔| ✔| ✔| 萨莎·克劳斯(Sascha Krause)
Win7SP1 | 64 | 5.3.8 | 64 | 5.5.28 | ✔| ✔| ✔| ✔| 曼努埃尔·西科尔德(Manuel Sychold)
  1. 创建一个新帖子。保存。
  2. 将日期设置为1月1日0999,然后点击更新。它是否已保存或更改为当前日期?
  3. 重复的日期设置189920202039
  4. 从管理页脚中的插件输出中获取信息,然后更新表。

7

问题与期望

尽管此问题的字面形式在上下文中是可行的(1899年),但从理论意义上讲还是有点模糊。几岁了?我们可能想走多远?未来呢?

由于WordPress最初是作为博客引擎开始的,因此从上下文的角度来说,它可以处理以下时间跨度:

  • WP存在的日期(显然可以使用它)
  • 可能的历史帖子范围(隐式地追溯到互联网存在的年代)
  • 尽可能不费吹灰之力就到未来(直到崩溃为止)

随着WordPress的使用演变为非博客应用程序,此类项目(通常是历史和艺术,我从报告中看到)开始遇到日期超出此范围的各种问题。

为了我的研究目的,我提出了以下问题:

  1. 最早和最近的两个完整日历年是什么,可以与WordPress本地发布的日期可靠地结合使用?
  2. 什么是低悬垂的水果(如果有的话),以将可用范围扩展到原生范围之外?

平台限制

由于WordPress是PHP应用程序,并且使用MySQL进行数据存储,因此受其限制。

的MySQL

WordPress将发布日期存储在MySQL post_dateDATETIME类型列中。

根据文档,此类型支持1000到9999年

DATETIME类型用于包含日期和时间部分的值。MySQL检索并DATETIME'YYYY-MM-DD HH:MM:SS'格式显示值。支持的范围是'1000-01-01 00:00:00''9999-12-31 23:59:59'

但是,它也表示较早的值可能有效,而没有提及较晚的值:

对于DATE and DATETIME范围描述,“受支持”表示尽管较早的值可能有效,但不能保证。

虽然从经验上我观察到的值超出范围,但这是轶事,不符合我们的可靠性条件。

的PHP

在PHP编程中,日期的时间戳记表示形式被广泛使用。根据用于我们目的的文档(PHP 5.2+和通用的32位环境),它(完整)支持1902年至2037年

时间戳记的有效范围通常是从Fri, 13 Dec 1901 20:45:54 UTCTue, 19 Jan 2038 03:14:07 UTC。(这些日期对应于32位带符号整数的最小值和最大值。)此外,并非所有平台都支持负时间戳,因此,日期范围不得超过Unix纪元。这意味着,例如,之前的日期Jan 1, 1970将不适用于Windows,某些Linux发行版和其他一些操作系统。PHP 5.1.0和更高版本克服了此限制。

除了Date/Time基于64位的较新处理之外,其处理范围约为-2920亿至2920亿年,这可能超出了当前的人类需求。

WordPress限制

WordPress在其代码库中引入并继承了一些其他限制。

数据流

从基本用户工作流程的角度来看,有两个与日期相关的处理:

  • 必须正确处理以后期编辑形式输入的日期并将其保存在数据库中
  • 必须正确读取数据库中保存的日期并在界面中显示

请注意,这些是技术上完全不同且独立的过程。如进一步说明,它们的范围不重叠,并且保存正确的日期并不等同于在WordPress环境中正确读取它的能力。

明确限制

  • 管理员中的WordPress帖子编辑器允许范围的年份,可以作为发布日期提交,范围为100到9999
  • _wp_translate_postdata() 处理年份(以与表格不同的编号提交),并且:

隐式限制

  • strtotime()PHP函数已被多次使用,并受到上述Unix时间戳的影响,其最低级别mysql2date()会影响从数据库中读取的所有日期,从1902年到2037年的继承范围
  • WordPress将使用正则表达式进行日期解析get_gmt_from_date(),预计年份将([0-9]{1,4})限制为1到9999,其他功能中类似处理的可能性很高,这需要枚举更彻底的代码审核

解决方法的可能性

  • wp_checkdate()具有wp_checkdate过滤器,可以覆盖此验证检查
  • 输出针对终端用户经过date_i18n()其具有date_i18n过滤器,理论上允许完全日期截距和重新处理输出到接口然而如果挑战函数传递范围(已经出false)时间戳输入

结论

出于实际目的和数据的可移植性,WordPress发布日期范围似乎等于32位Unix时间戳,范围包括1902年至2037年(含两端)

对于超出此范围的任何发布日期操作,都必须进行审核(Unix时间戳的64位范围,实际运行的MySQL或值的备用数据库存储)。对于更远的范围(低于1000,高于9999),可能需要大量的自定义代码。

对于任意日期的任何实现,有意义的是:

  • 将它们以不受数据库限制的格式存储在MySQL中
  • 使用完全自定义Date/Time的代码和/或经过审核不受Unix时间戳限制影响的WordPress函数在PHP中进行处理

代码测试台

以下代码和精选的年份集已用于上述研究和结论检验:

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,
        ) );
    }
}

+1仅剩问题:什么是r()
kaiser 2013年

1
@kaiser php-ref,替换为所选的转储功能:)
最早
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.