【问题标题】:How to get the time difference in human format (time ago ... etc) but in multilingual style如何以人类格式(时间前......等)但以多语言风格获得时差
【发布时间】:2012-07-30 14:23:29
【问题描述】:

zend 中是否有任何视图助手或库,例如,我可以使用它来获取两个时间戳之间的差异,但会自动将 'y li a' 放在时间前面。例如,前一段时间的法国标准...

【问题讨论】:

    标签: php zend-framework


    【解决方案1】:

    答案是否定的,但也许这会有所帮助:

    <?php
    
    /**
     * Return a human readable diff between two times (e.g. 3 years 4 months 8 days 3 hours)
     * This is locale aware and supports automatic translation
     *
     * @category   View Helpers
     * @author     Drew Phillips <drew [at] drew [.] co.il>
     * @copyright  None
     * @license    BSD License http://opensource.org/licenses/bsd-3-clause
     * @version    1.0
     * @link       http://drew.co.il
     */
    class My_View_Helper_TimeDiff extends Zend_View_Helper_Abstract
    {
        protected static $_locale       = null;
        protected static $_translations = null;
    
        /**
         * Return the diff between two times in human readable format
         * @param int    $timestamp    The timestamp of the time to diff
         * @param string $format       The format string used to control which date units are output (TODO: improve by incrementing lower values (i.e. add 12 to months if there is 1 year but years are not displayed))
         * @param int    $now          The timestamp used as the current time, if null, the current time is used
         * @return string              The human readable date diff in the language of the locale
         */
        public function timeDiff($timestamp, $format = null, $now = null)
        {
            if (null === $format) $format = '%y %m %d %h %i';
            if (null === $now)    $now    = time();
    
            if (!$this->isValidTimestamp($timestamp)) {
                throw new InvalidArgumentException('$timestamp parameter to timeDiff is not a valid timestamp');
            } else if (!$this->isValidTimestamp($now)) {
                throw new InvalidArgumentException('$now parameter to timeDiff is not a valid timestamp');
            } else if ($timestamp > $now) {
                throw new InvalidArgumentException('The value given for $timestamp cannot be greater than $now');
            }
    
            if (self::$_locale == null) {
                $locale = null;
                $list   = array();
    
                try {
                    $locale = Zend_Registry::get('Zend_Locale');
                } catch (Zend_Exception $ex) {
                    $default = Zend_Locale::getDefault(); // en if nothing set
    
                    try {
                        $locale = new Zend_Locale();
                    } catch (Zend_Locale_Exception $ex) {
                        $locale = new Zend_Locale($default);
                    }
                }
    
                self::$_locale = $locale;
                self::$_translations = Zend_Locale::getTranslationList('unit', $locale);
            }
    
            $table    = self::$_translations;
            $past     = new DateTime(date('Y-m-d H:i:s', $timestamp));
            $current  = new DateTime(date('Y-m-d H:i:s', $now));
            $interval = $current->diff($past);
    
            $parts = $interval->format('%y %m %d %h %i %s %a');
    
            $weeks = 0;
            list($years, $months, $days, $hours, $minutes, $seconds, $total_days) = explode(' ', $parts);
    
            /* uncomment to handle weeks
            if ($days >= 7) {
                $weeks = (int)($days / 7);
                $days  %= 7;
            }
            */
    
            $diff = array();
    
            if (strpos($format, '%y') !== false && $years > 0) {
                $diff[] = str_replace('{0}', $years, $table['year'][($years != 1 || !isset($table['year']['one']) ? 'other' : 'one')]);
            }
    
            if (strpos($format, '%m') !== false && $months > 0) {
                $diff[] = str_replace('{0}', $months, $table['month'][($months != 1 || !isset($table['month']['one']) ? 'other' : 'one')]);
            }
    
            if (strpos($format, '%d') !== false && $days > 0) {
                $diff[] = str_replace('{0}', $days, $table['day'][($days != 1 || !isset($table['day']['one']) ? 'other' : 'one')]);
            }
    
            if (strpos($format, '%h') !== false && $hours > 0) {
                $diff[] = str_replace('{0}', $hours, $table['hour'][($hours != 1 || !isset($table['hour']['one']) ? 'other' : 'one')]);
            }
    
            if (strpos($format, '%i') !== false && $minutes > 0) {
                $diff[] = str_replace('{0}', $minutes, $table['minute'][($minutes != 1 || !isset($table['minute']['one']) ? 'other' : 'one')]);
            }
    
            return implode(' ', $diff);
        }
    
        protected function isValidTimestamp($timestamp)
        {
            $ts = (int)$timestamp;
            $d  = date('Y-m-d H:i:s', $ts);
    
            return strtotime($d) === $ts;
        }
    }
    

    一旦注册,从你的角度这样称呼它:

    <?php echo $this->timeDiff($object->pastTimestamp) ?> $this->_xlate('ago');
    

    示例输出:

    1 année 5 mois 15 jours 21 heures 56 minutes il ya
    1 год 5 месяца 15 дня 22 часа 1 минута назад
    

    请注意,助手不处理“之前”部分,在某些语言(法语)中,它位于差异之前,而在其他语言(英语)中,它位于末尾。您还需要在自己的翻译文件中定义此翻译字符串,ZF 没有针对它的翻译。理想情况下,该逻辑将内置到帮助程序中,但我没有这样做。

    希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      时间戳是一个数字,您可以简单地从结束时间减去开始时间来获得差值。你可以这样做:

      public function timeDiff($timestampFrom, $timestampTo) {
      
      $timeDiff = new Zend_Date($timestampTo - $timestampFrom, Zend_Date::TIMESTAMP);
      
      $output = "il y a ";
      
      //Check the number of days:
      if($timeDiff->getTimestamp > 60*60*24) $output .= $timeDiff->get(Zend_Date::DAY).' jours, ';
      //Check the hours
      if($timeDiff->getTimestamp > 60*60) $output .= $timeDiff->get(Zend_Date::HOUR).' heures, ';
      //Check the minutes
      if($timeDiff->getTimestamp > 60) $output .= $timeDiff->get(Zend_Date::MINUTE).' minutes et ';
      //Check the seconds
      $output .= $timeDiff->get(Zend_Date::SECOND)." secondes";
      
      return $output;
      }
      

      Matthieu 的评论是对的,法语中没有“y li a”这样的词。您可能的意思是“il y a”。 ;)

      【讨论】:

      • 感谢您的回答,是的,您是对的,我之前在法语中完全拼错了
      猜你喜欢
      • 2014-06-16
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多