2016-04-08 49 views
2

我使用的是在使用一些文本,如「2016年4月15日,」日期DateTime::createFromFormat()PHP的DateTime :: createFromFormat和多語言

這是完全只要工作作爲我使用的是英語文化。

April 15, 2016 -> ok

我的代碼被設置爲WordPress插件。請理解,我無法控制給我日期(如文本)和WordPress設置的組件。如果用戶使用其他語言設置WordPress安裝,日期將從「2016年4月15日」更改爲(如法語)「Avril 15,2016」。

它看起來像DateTime::createFromFormat()不支持其他語言比英語,所以「2016年4月15日」將結束:

"Fatal error: Call to a member function format() on boolean"

有沒有人有一個想法,我們如何能處理年月日爲文本幾種語言?在PHP中使用DateTime::createFromFormat()或另一種方法?

感謝

+0

您可否詳細說明「我無法控制給出日期的組件」?如果您描述插件,也許我們可以找到更好的解決方案。我認爲實際上你可以獲得關於你的日期的非本地化信息。 – fusion3k

+0

您好,我從http://amsul.ca/pickadate.js/的POST值中獲取信息,並且文化由WP管理員設置。 – Iteration

+0

如果你看看[pickadate.js文檔](http://amsul.ca/pickadate.js/date/#formats),你可以看到它有一個'formatSubmit'選項:使用這個選項和你的問題解決了。 – fusion3k

回答

2

有兩種方法可以做到這一點,但都取決於如何精確地產生輸入...

  1. 維持月份名稱翻譯

這數組是簡單/天真和最明顯的方式,我不認爲這樣做需要解釋。

但是,根據WordPress(和/或您使用的插件)的工作方式,它也可能是您唯一的選擇。

  • IntlDateFormatter
  • 這是純粹的編程方式,因此什麼將被認爲是「正確」的之一,但不幸的是這類來作爲PECL的一部分擴展名 - intl - 並未與PHP捆綁在一起。

    它還要求您在解析日期之前知道使用的語言,但這不應該是一個問題,因爲這是所有本地化解決方案應該如何工作的原因,因此我假定這些信息可供您使用在WordPress中。
    pickdate.js也seems to work with standard locales by default

    話雖這麼說,這裏是它的工作原理是:

     
    // See http://userguide.icu-project.org/formatparse/datetime 
    $inputFormat = 'MMMM dd, yyyy'; 
    $inputDate = 'Avril 15, 2016'; 
    $locale  = 'fr_FR'; 
    
    // Here comes the magic ... 
    $dateFormatter = new IntlDateFormatter(
        $locale, 
        IntlDateFormatter::LONG, // Not really important, may even be NONE 
        IntlDateFormatter::NONE, // Time ... we're not using it 
        NULL, // Will use date_default_timezone_get() 
        NULL, // Calendar; we don't need it 
        $inputFormat 
    ); 
    
    // Will return bool(false) on failure, use getErrorMessage() for debugging 
    $unixTimestamp = $dateFormatter->parse($inputDate); 
    

    值得一提的是,IntlDateFormatter主要設計用於創建本地化輸出(這是正確的 - 你不應該分析在翻譯月份名第一名,或者就此而言一個名字;數字FTW),所以我們確實在這裏寫了很多不相關的東西。 對於您的用例,只有$locale$inputFormat參數很重要。我們需要時區
    您可以通過得到它(最好)$dateFormatter->getTimeZone()或在這種情況下只是date_default_timezone_get(),但你需要的時區的原因有兩個:

    1. 你沒有時間值在你的輸入,因此IntlDateFormatter::parse()假定「00:00:00」。
    2. UNIX時間戳是始終是UTC的,所以IntlDateFormatter::parse()將考慮到這一點,DateTime::createFromFormat('U', $unixTimestamp)會將對象的時區設置爲UTC!

    如果你在另一個時區的時候,更具體地說在一個對世界的東側,會出現這種情況:

     
    $dateTime = DateTime::createFromFormat('U', $unixTimestamp); 
    var_dump($dateTime->format('Y-m-d')); // string(10) "2016-04-14" !!! 
    
    $dateTime->setTimeZone(new DateTimeZone($timezone)); 
    var_dump($dateTime->format('Y-m-d')); // string(10) "2016-04-15" 
    

    可以告訴IntlDateFormatter您在UTC是首先,但這在技術上是作弊(眨眼),並且取決於你以後使用的是什麼$dateTime,這可能會導致副作用。