【问题标题】:strtotime With Different Languages?strtotime 使用不同的语言?
【发布时间】:2022-01-13 00:18:40
【问题描述】:

strtotime 是否只能以服务器上的默认语言工作?以下代码应解析为 2005 年 8 月 11 日,但它使用法语“aout”而不是英语“aug”。

任何想法如何处理?

<?php
    $date = strtotime('11 aout 05');
    echo date('d M Y',$date);
?>

【问题讨论】:

    标签: php localization strtotime


    【解决方案1】:

    法国月份日期是:

    janvier février mars avril mai juin juillet août septembre octobre 十二月十一月

    因此,对于月份是法语的非常具体的情况,您可以使用

    function myStrtotime($date_string) { return strtotime(strtr(strtolower($date_string), array('janvier'=>'jan','février'=>'feb','mars'=>'march','avril'=>'apr','mai'=>'may','juin'=>'jun','juillet'=>'jul','août'=>'aug','septembre'=>'sep','octobre'=>'oct','novembre'=>'nov','décembre'=>'dec'))); }
    

    如果您传递英文的 $date_string,该函数无论如何都不会中断,因为它不会进行任何替换。

    【讨论】:

      【解决方案2】:

      来自docs

      将任何英文文本日期时间描述解析为 Unix 时间戳

      编辑:现在已经过去了六年,关于为什么 strtotime() 是手头问题的不合适解决方案的旁注变成了公认的答案?

      为了更好地回答实际问题,我想回应 Marc B 的回答:尽管有反对意见,date_create_from_format 与自定义 Month 解释器配对将提供最可靠的解决方案

      但是,目前看来,PHP 还没有内置的国际日期解析的灵丹妙药。

      【讨论】:

      • 它没有回答“任何想法如何处理这个问题?”
      • 没有解决问题
      • 不提供解决方案
      • 我总是听“英语”....请存在更多语言!任何解析到西班牙语/加泰罗尼亚语?任何如 strtotime("16 Març 2016","ca") 或类似的?
      • 你的答案不知道。
      【解决方案3】:

      正如提到的strtotime 不考虑语言环境。但是你可以使用strptime(参见http://ca1.php.net/manual/en/function.strptime.php),因为根据文档:

      Month and weekday names and other language dependent strings respect the current locale set with setlocale() (LC_TIME).

      请注意,根据您的系统、区域设置和编码,您必须考虑重音字符。

      【讨论】:

      • 另请注意,文档中指出:此功能未在 Windows 平台上实现,此功能在不同操作系统上可能具有不同的行为,您至少需要 php 5.1。
      • 这有点没用,因为strptime() 不接受语言环境日期格式作为参数,所以你不能用strptime() 以另一种格式编码语言环境日期。您可以做的是将通用格式编码到语言环境中(反之亦然)
      【解决方案4】:

      这个方法应该适合你使用strftime:

      setlocale (LC_TIME, "fr_FR.utf8"); //Setting the locale to French with UTF-8
      
      echo strftime(" %d %h %Y",strtotime($date));
      

      strftime

      【讨论】:

        【解决方案5】:

        我写了一个简单的函数部分解决了这个问题。 它不能作为完整的 strtotme() 工作,但它决定了日期中的月份名称。

        <?php
        // For example, I get the name of the month from a 
        // date "1 January 2015" and set him (with different languages):
        
        echo month_to_number('January').PHP_EOL;           // returns "01" (January)
        echo month_to_number('Января', 'ru_RU').PHP_EOL;   // returns "01" (January)
        echo month_to_number('Мая', 'ru_RU').PHP_EOL;      // returns "05" (May)
        echo month_to_number('Gennaio', 'it_IT').PHP_EOL;  // returns "01" (January)
        echo month_to_number('janvier', 'fr_FR').PHP_EOL;  // returns "01" (January)
        echo month_to_number('Août', 'fr_FR').PHP_EOL;     // returns "08" (August)
        echo month_to_number('Décembre', 'fr_FR').PHP_EOL; // returns "12" (December)
        

        同样,我们可以继续确定一周中的数字和天数等。

        功能:

        <?php
        
        function month_to_number($month, $locale_set = 'ru_RU')
        {
            $month  = mb_convert_case($month, MB_CASE_LOWER, 'UTF-8');
            $month  = preg_replace('/я$/', 'й', $month); // fix for 'ru_RU'
            $locale =
                setlocale(LC_TIME, '0');
                setlocale(LC_TIME, $locale_set.'.UTF-8');
        
            $month_number = FALSE;
        
            for ($i = 1; $i <= 12; $i++)
            {
                $time_month     = mktime(0, 0, 0, $i, 1, 1970);
                $short_month    = date('M', $time_month);
                $short_month_lc = strftime('%b', $time_month);
        
                if (stripos($month, $short_month) === 0 OR
                    stripos($month, $short_month_lc) === 0)
                {
                    $month_number = sprintf("%02d", $i);
        
                    break;
                }
            }
        
            setlocale(LC_TIME, $locale); // return locale back
        
            return $month_number;
        }
        

        【讨论】:

          【解决方案6】:

          解决这个问题的关键是将外国文本表示转换为英语对应。我也需要这个,所以受到已经给出的答案的启发,我编写了一个漂亮而干净的函数,可以用于检索英文月份名称。

          function getEnglishMonthName($foreignMonthName,$setlocale='nl_NL'){
          
            setlocale(LC_ALL, 'en_US');
          
            $month_numbers = range(1,12);
          
            foreach($month_numbers as $month)
              $english_months[] = strftime('%B',mktime(0,0,0,$month,1,2011));
          
            setlocale(LC_ALL, $setlocale);
          
            foreach($month_numbers as $month)
              $foreign_months[] = strftime('%B',mktime(0,0,0,$month,1,2011));
          
            return str_replace($foreign_months, $english_months, $foreignMonthName);
          
          }
          
          echo getEnglishMonthName('juli');
          // Outputs July
          

          您也可以在一周中的几天以及任何其他语言环境中进行调整。

          【讨论】:

          • 将完整的日期字符串传递给它后,我发现您可以在同一个函数中进行月份名称替换和日期名称替换。
          【解决方案7】:

          将此添加为Marco Demaio answer 的扩展版本。添加了法语星期几和月份的缩写:

          <?php
          public function frenchStrtotime($date_string) {
            $date_string = str_replace('.', '', $date_string); // to remove dots in short names of months, such as in 'janv.', 'févr.', 'avr.', ...
            return strtotime(
              strtr(
                strtolower($date_string), [
                  'janvier'=>'jan',
                  'février'=>'feb',
                  'mars'=>'march',
                  'avril'=>'apr',
                  'mai'=>'may',
                  'juin'=>'jun',
                  'juillet'=>'jul',
                  'août'=>'aug',
                  'septembre'=>'sep',
                  'octobre'=>'oct',
                  'novembre'=>'nov',
                  'décembre'=>'dec',
                  'janv'=>'jan',
                  'févr'=>'feb',
                  'avr'=>'apr',
                  'juil'=>'jul',
                  'sept'=>'sep',
                  'déc'=>'dec',
                  'lundi' => 'monday',
                  'mardi' => 'tuesday',
                  'mercredi' => 'wednesday',
                  'jeudi' => 'thursday',
                  'vendredi' => 'friday',
                  'samedi' => 'saturday',
                  'dimanche' => 'sunday',
                ]
              )
            );
          }
          

          【讨论】:

            【解决方案8】:

            这取决于语言环境。如果它必须为每次解析检查每种语言,那么即使是最简单的日期字符串也需要永远解析。

            如果您有一个已知格式的字符串,请考虑使用date_create_from_format(),这样效率更高,错误打印更少

            【讨论】:

            • 这是错误的。 DateTime 不会解析非英语数据。即这将失败: setlocale(LC_TIME, "fr_FR"); $dt = DateTime::createFromFormat('d F Y', "12 Août 2013");
            【解决方案9】:

            尝试在转换前设置语言环境:

            setlocale(LC_TIME, "fr_FR");
            

            【讨论】:

              猜你喜欢
              • 2011-02-07
              • 1970-01-01
              • 2015-08-17
              • 2023-03-04
              • 1970-01-01
              • 1970-01-01
              • 2015-08-12
              • 1970-01-01
              相关资源
              最近更新 更多