ไม่สามารถเลือกวันที่เก่าในเวิร์ดเพรส


13

ฉันไม่สามารถตั้งปีต่ำกว่า 1899 สำหรับโพสต์ หากฉันตั้งปีต่ำกว่า 1899 จะถูกตั้งเป็นปีปัจจุบันโดยอัตโนมัติ

ภาพหน้าจอ

ฉันซื้อธีมไทม์ไลน์และถามในฟอรัมสนับสนุนของพวกเขา พวกเขาตอบว่า:

ดูเหมือนว่าข้อ จำกัด ที่สร้างโดยผู้ให้บริการโฮสต์ของคุณ ไม่มีสิ่งใดในชุดรูปแบบที่ป้องกันวันที่คุณกำหนด - อย่างที่คุณเห็นการสาธิตมีการโพสต์โดยใช้วันที่ในช่วง 1400s ลองติดต่อผู้ให้บริการโฮสต์ของคุณและดูว่าพวกเขามีข้อมูลเชิงลึกเกี่ยวกับวิธีแก้ไขปัญหาดังกล่าวหรือไม่


2
และคำถามของคุณคืออะไรกันแน่? มีธีมอยู่นับพันที่ - มันเป็นเวลานานพอที่จะคิดว่าใครจะรู้จักธีมที่คุณซื้อ อย่างน้อยคุณจะต้องให้รหัสที่เกี่ยวข้อง
Johannes Pille

1
ฉันสงสัยว่ามันเป็นความผิดของ hoster นี่เป็นเรื่องของค่าที่บันทึกไว้ในฐานข้อมูลฉันถือว่า เปิดWP_DEBUGและแก้ไขข้อความแสดงข้อผิดพลาดในคำถามของคุณ ฉันอาจทำให้มันดูเหมือนเป็นเช่นนั้น แต่การเชื่อมโยงไปยังเวอร์ชันที่ใช้งานได้ของคำถามที่เป็นปัญหาไม่ได้ช่วยอะไรมาก
Johannes Pille

1
นี่เป็นคำถามที่ถูกกฎหมาย ไม่เกี่ยวข้องกับธีม ฉันสามารถทำซ้ำปัญหานี้ ดูภาพหน้าจอเคลื่อนไหวนี้
fuxia

1
ปัญหาเดียวกันกับ 1900 และ 1901 แต่ 1902 ทำงาน ;-)
birgire

1
ฉันสามารถทำซ้ำนี้โดยวิธีการที่มีปัญหาดังกล่าวข้างต้นช่วงเวลา Unix (2038) เช่นกัน PHP 5.4 ใน Win7x64
Rarst

คำตอบ:


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>";
}

สรุปสาระสำคัญของปลั๊กอินสามารถตรวจสอบได้ออกจากที่นี่

ระบบปฏิบัติการ | ระบบปฏิบัติการ bit | PHP | PHP Bit | MySQL | 999 | พ.ศ. 2442 2563 | 2039 | ผู้ใช้งาน
Win7 | 64 | 5.4.4 | ?? | 5.5.25 | ✘ | ✘ | ✔ | ✘ | toscho
Linux | ?? | 5.3.18-nmm1 | ?? | 5.1.70 | ✔ | ✔ | ✔ | ✔ | toscho
CentOS 6 | 64 | 5.5.4 | ?? | 5.0.95 | ✔ | ✔ | ✔ | ✔ | toscho
Win7 | 64 | 5.4.15 | 32 | 5.5.31 | ✘ | ✘ | ✔ | ✘ | rarst
Ubuntu 12.04 | 64 | 5.3.10-1 | 64 | 5.5.32 | ✔ | ✔ | ✔ | ✔ | Pille
CloudLinux | 64 | 5.2.17 | 64 | 5.0.96 | ✔ | ✔ | ✔ | ✔ | Pille
Ubuntu 12.10 | 64 | 5.4.6 | 64 | 5.5.32 | ✔ | ✔ | ✔ | ✔ | Michael Ecklund
CENTOS 5.9 | 32 | 5.3.27 | 32 | 5.5.32 | ✘ | ✘ | ✔ | ✘ | Michael Ecklund
Win7 | 64 | 5.4.7 | 64 | 5.5.27 | ✘ | ✘ | ✔ | ✘ | ไกเซอร์
OSX 10.7.5 | 64 | 5.3.6 | 64 | 5.5.9 | ✔ | ✔ | ✔ | ✔ | GhostToast
Centos 6.4 | 64 | 5.4.17 | 32 | 5.1.59 | ✘ | ✘ | ✔ | ✘ | birgire
เดเบียน 6 | 64 | 5.4.19 | 64 | 5.1.66 | ✘ | ✘ | ✔ | ✘ | birgire
Win7 | 64 | 5.5.0 | 64 | 5.5.22 | ✘ | ✘ | ✔ | ✘ | จีเอ็ม
OSX 10.7.4 | 64 | 5.3.6 | 64 | 5.5.9 | ✔ | ✔ | ✔ | ✔ | brasofilo
CentOS 5 | 64 | 5.3.22 | 64 | 5.1.68 | ✔ | ✔ | ✔ | ✔ | brasofilo
Mac 10.8.5 | 64 | 5.3.26 | 64 | 5.5.25 | ✔ | ✔ | ✔ | ✔ | flentini
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 มกราคม, 0999คลิกปรับปรุง มันถูกบันทึกหรือเปลี่ยนเป็นวันที่ปัจจุบันหรือไม่?
  3. ทำซ้ำสำหรับการตั้งค่าวันสำหรับ1899, และ20202039
  4. ใช้ข้อมูลจากเอาต์พุตปลั๊กอินในส่วนท้ายผู้ดูแลระบบของคุณและอัปเดตตาราง

7

คำถามและความคาดหวัง

ในขณะที่รูปแบบที่แท้จริงของคำถามนี้มีประโยชน์ในบริบท (ปี 1899) มันค่อนข้างคลุมเครือเล็กน้อยในทางทฤษฎี อายุเท่าไหร่ เราอาจต้องการไปไกลแค่ไหนในอดีต? แล้วอนาคตล่ะ

ตั้งแต่ WordPress ได้เริ่มต้นเป็นเครื่องมือสร้างบล็อกในบริบทนั้นมันมีวิวัฒนาการในการจัดการกับช่วงเวลาต่อไปนี้:

  • มีวันที่ WP อยู่ (เห็นได้ชัดว่าสามารถใช้งานได้)
  • ช่วงของการโพสต์ทางประวัติศาสตร์ที่เป็นไปได้ (โดยปริยายไกลเท่าที่อินเทอร์เน็ตมีอยู่)
  • เท่าที่เป็นไปได้ในอนาคตโดยไม่ต้องใช้ความพยายามพิเศษ (ทำงานจนกว่ามันจะหยุดพัก)

เนื่องจากการใช้งาน WordPress กลายเป็นแอพพลิเคชั่นที่ไม่บล็อกเช่นโครงการ (ประวัติศาสตร์และศิลปะที่ฉันเห็นจากรายงาน) เริ่มมีปัญหาหลายอย่างกับวันที่อยู่นอกช่วงนี้

เพื่อวัตถุประสงค์ในการวิจัยของฉันฉันได้กำหนดคำถามต่อไปนี้:

  1. ปีปฏิทินและปีปฏิทินล่าสุดที่เก่าและใหม่ซึ่งสามารถใช้กับวันที่โพสต์ WordPress ได้อย่างน่าเชื่อถือ?
  2. อะไรคือผลไม้แขวนลอยต่ำ (ถ้ามี) เพื่อขยายช่วงที่ใช้ได้มากกว่าช่วงดั้งเดิม?

ข้อ จำกัด ของแพลตฟอร์ม

เนื่องจาก WordPress เป็นแอปพลิเคชั่น PHP และใช้ MySQL ในการจัดเก็บข้อมูลจึงมีข้อ จำกัด

MySQL

WordPress เก็บวันที่โพสต์ในpost_dateคอลัมน์DATETIMEประเภทใน MySQL

ตามเอกสารประเภทนี้สนับสนุนปี1,000 ถึง 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 การแสดงเวลา Unix ของวันที่มีการใช้กันอย่างแพร่หลาย ตามเอกสารสำหรับวัตถุประสงค์ของเรา (PHP 5.2+ และสภาพแวดล้อมทั่วไป 32 บิต) รองรับปี (เต็ม) 1902 ถึง 2037 :

ช่วงที่ถูกต้องของการประทับเวลาเป็นมักจะมาจากการFri, 13 Dec 1901 20:45:54 UTC Tue, 19 Jan 2038 03:14:07 UTC(เหล่านี้คือวันที่ที่สอดคล้องกับค่าต่ำสุดและสูงสุดสำหรับจำนวนเต็มที่มีลายเซ็นแบบ 32 บิต) นอกจากนี้บางแพลตฟอร์มไม่สนับสนุนการประทับเวลาเชิงลบดังนั้นช่วงวันที่ของคุณอาจถูก จำกัด ไว้ไม่เกิน Epoch ของ Unix ซึ่งหมายความว่าเช่นวันที่ก่อนหน้าJan 1, 1970นี้จะไม่ทำงานบน Windows การแจกจ่าย Linux บางระบบและระบบปฏิบัติการอื่น ๆ PHP 5.1.0 และเวอร์ชันที่ใหม่กว่าเอาชนะข้อ จำกัด นี้ได้

นอกเหนือDate/Timeจากการจัดการที่ใหม่กว่านั้นคือ 64 บิตและมีช่วงประมาณ -292 พันล้านถึง 292 พันล้านปีซึ่งอาจเกินความต้องการของมนุษยชาติในขณะนี้

ข้อ จำกัด ของ WordPress

WordPress แนะนำและสืบทอดข้อ จำกัด เพิ่มเติมบางประการในฐานของรหัส

การไหลของข้อมูล

จากมุมมองเวิร์กโฟลว์ผู้ใช้ขั้นพื้นฐานมีการประมวลผลสองรายการที่เกี่ยวข้องกับวันที่:

  • ป้อนวันที่ในแบบฟอร์มแก้ไขโพสต์จะต้องดำเนินการอย่างถูกต้องและบันทึกไว้ในฐานข้อมูล
  • วันที่บันทึกในฐานข้อมูลจะต้องอ่านและแสดงอย่างถูกต้องในส่วนต่อประสาน

โปรดทราบว่าสิ่งเหล่านี้เป็นกระบวนการทางเทคนิคที่แตกต่างและเป็นอิสระอย่างสมบูรณ์ ตามที่อธิบายเพิ่มเติมช่วงของพวกเขาไม่ทับซ้อนกันและการบันทึกวันที่ที่ถูกต้องไม่เท่ากับความสามารถในการอ่านอย่างถูกต้องในสภาพแวดล้อม WordPress

ข้อ จำกัด ที่ชัดเจน

  • บรรณาธิการโพสต์ WordPress ในผู้ดูแลระบบอนุญาตให้ช่วงของปีที่สามารถส่งเป็นวันที่โพสต์100 ถึง 9999
  • _wp_translate_postdata() กระบวนการปี (ส่งเป็นตัวเลขที่แตกต่างจากแบบฟอร์ม) และ:
    • ฆ่าเชื้อให้เป็น non-negative > 0
    • ตรวจสอบความถูกต้องโดยใช้wp_checkdate()ซึ่งเรียกภาษาเนทีฟ PHP checkdate()ซึ่งกำหนดขีด จำกัด1 ถึง 32767

ข้อ จำกัด โดยนัย

  • 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 อย่างครอบคลุม

สำหรับการดำเนินการวันที่โพสต์ใด ๆ ที่อยู่นอกช่วงของสภาพแวดล้อมนี้จะต้องได้รับการตรวจสอบ (ช่วง 64 บิตของการประทับเวลา Unix การทำงานของ MySQL หรือการจัดเก็บฐานข้อมูลสำรองสำหรับค่า) สำหรับช่วงที่ไกลออกไป ( ต่ำกว่า 1,000, มากกว่า 9999 ) รหัสที่กำหนดเองจำนวนมากน่าจะเป็นที่ต้องการ

สำหรับการติดตั้งวันที่ใด ๆ มันทำให้รู้สึกถึง:

  • เก็บไว้ใน MySQL ในรูปแบบไม่ขึ้นอยู่กับข้อ จำกัด ของฐานข้อมูล
  • กระบวนการใน PHP โดยใช้โค้ดที่กำหนดเองได้อย่างสมบูรณ์Date/Timeและ / หรือฟังก์ชั่น WordPress ที่ตรวจสอบแล้วว่าไม่ได้รับผลกระทบจากขีด จำกัด การประทับเวลา Unix

เตียงทดสอบรหัส

ชุดรหัสและมือหยิบต่อไปนี้ถูกนำมาใช้เพื่อการวิจัยข้างต้นและการทดสอบข้อสรุป:

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()อะไร
ไกเซอร์

1
@kaiser php-ref , แทนที่ด้วยฟังก์ชั่นการถ่ายโอนข้อมูลของตัวเลือก :)
Rarst
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.