【问题标题】:PHP: Is there a function that converts a date string in a human readable format?PHP:是否有将日期字符串转换为人类可读格式的函数?
【发布时间】:2010-12-18 07:18:33
【问题描述】:

我想将“19.11.2009 14:00”之类的日期字符串转换为现在的年龄,例如“2 分钟”或“1 周”或“2 天”

周围有代码吗?

【问题讨论】:

  • 要确定经过的时间,您需要两个时间点。您只发布了一个。
  • 第二个时间点就是现在。
  • 您的意思是要计算指定日期字符串与现在之间的经过时间吗?那将是两个时间点。有时这被称为“时间跨度”。您可以根据此处的 cmets 编辑您的问题以使其更清楚。没关系。
  • @Ben,是的,这也是我的猜测,但如果在问题中明确说明,那就太好了。
  • 对不起,我忘了第二次是“现在”

标签: php datetime


【解决方案1】:
$dateString = strtotime('19.11.2009 14.00');
$now = time();

$time = $dateString - $now;

if($time > 60 && $time < 3600) echo $time/60.' minutes remaining';
else if($time > 3600 && $time < 86400) echo $time/3600.' hours remaining';
else if($time > 86400 && $time < 604800) echo $time/86400.' days remaining';
else if($time > 604800 && $time < 18144000) echo $time/604800.' weeks remaining';
else if($time > 18144000 && $time < 217728000) echo $time/18144000.' months remaining';
else if($time > 217728000) echo $time/217728000.' years remaining';

【讨论】:

  • 你不是说$time = $dateString - $now;吗?
【解决方案2】:

类似的东西

define('MINUTE',60);
define('HOUR',60*MINUTE);
define('DAY',24*HOUR);
define('WEEK',7*DAY);
define('MONTH',30*DAY);

$pastDate=strtotime($dateString);
$seconds=time()-$pastDate;
if ($seconds>MONTH)
  return $seconds/MONTH . " months";
if ($seconds>WEEK)
  return $seconds/WEEK . " weeks";
if ($seconds>DAY)
  return $seconds/DAY . " days";
if ($seconds>HOUR)
  return $seconds/HOUR . " hours";
if ($seconds>MINUTE)
  return $seconds/MINUTE . " minutes";
return $seconds . " seconds";

【讨论】:

  • 可能没关系。如果是这样,OP 可能会以更高的精度计算(365.25/12 或其他)
【解决方案3】:

如果您使用的是 PHP 5.3,也可以使用 DateTime:diff

$start = new DateTime('now');
$time_span = $start->diff(new DateTime($dateString));
var_dump($time_span);

【讨论】:

    【解决方案4】:

    这显然不是你想要的 100% ——其他人已经给了你很好的答案——但这样的东西可能是“人类可读”日期格式的一个很好的替代品。

    我从很久以前使用的一些代码中挖掘了这个。我有一段时间没有对此进行测试,但最后我记得它工作得很好。我想复制 Facebook 使用的东西,比如“5 秒前”,但它也适用于未来,使用“in ...”而不是“... ago”。您可以修改它以获得尽可能多或尽可能少的细节。

    /**
     * Returns the amount of time that has passed from the current date
     * or the amount of time from the current date until the specified date
     *
     * Returns in the form of a partial sentence. Some examples:
     *
     * In 25 days
     * Tomorrow
     * Yesterday
     * 4 months ago
     * Next month
     * Last month
     * (etc)
     *
     * @param string $date
     * @return string
     */
    public static function calculateHowLong($date) {
      // start by converting to unix time
      $when = date("U", strtotime($date));
      $isPast = ($when < time());
    
      $how_long = abs(time() - $when);
      if ($how_long < 60) {
        $return =  "{$how_long} seconds";
        if ($isPast) $return .= " ago"; else $return = "In {$return}";
    
      } elseif ($how_long < 60 * 60) {
        $return =  (int) ($how_long / 60) . " minutes";
        if ($isPast) $return .= " ago"; else $return = "In {$return}";
    
      } elseif ($how_long < 60 * 60 * 24) {
        $return =  (int) ($how_long / (60 * 60)) . " hours";
        if ($isPast) $return .= " ago"; else $return = "In {$return}";
    
      } elseif ($how_long < 60 * 60 * 24 * 2) {
        if ($isPast) $return = "Yesterday"; else $return = "Tomorrow";
    
      } elseif ($how_long < 60 * 60 * 24 * 7) {
        $return =  (int) ($how_long / (60 * 60 * 24)) . " days";
        if ($isPast) $return .= " ago"; else $return = "In {$return}";
    
      } elseif ($how_long < 60 * 60 * 24 * 13) {
        if ($isPast) $return = "Last week"; else $return = "Next week";
    
      } elseif ($how_long < 60 * 60 * 24 * 7 * 4) {
        $return =  (int) ($how_long / (60 * 60 * 24 * 7)) . " weeks";
        if ($isPast) $return .= " ago"; else $return = "In {$return}";
    
      } elseif ($how_long < 60 * 60 * 24 * 30 * 2) {
        if ($isPast) $return = "Last month"; else $return = "Next month";
    
      } elseif ($how_long < 60 * 60 * 24 * 30 * 12) {
        $return =  (int) ($how_long / (60 * 60 * 24 * 30)) . " months";
        if ($isPast) $return .= " ago"; else $return = "In {$return}";
    
      } else {
        if ($isPast) $return = "More than 1 year ago"; else $return = "In more than 1 year";
      }
    
      return $return;
    }
    

    可能有点草率,但请随时改进。

    【讨论】:

      【解决方案5】:

      我看到较早的答案提供了冗长的“将所有内容写两次”(WET)而不是“不要重复自己”(DRY)代码。更糟糕的是,他们没有利用 PHP 的 DateTime 类的现代力量。可以避免在 unix 时间上执行数学计算的所有晦涩和冗长。 @Sergi 提示了正确的方向,但忽略了提供完整的解决方案。

      因为这个问题的范围表明传入的日期将是过去的,并且它们将与当前的日期/时间进行比较,所以我将提供以下 sn-p 来提供问题中描述的通用英语表达.

      为了涵盖需要数周的情况,需要实现一个条件,因为 DateTime 差异对象不提供w(周)的属性。这是 sn-p 中唯一需要数学计算的部分。

      代码:(Demo)

      $date = '10.11.2021 14:00';
      $diff = (new DateTime($date))->diff(new DateTime());
      
      $lookup = [
          'y' => 'year',
          'm' => 'month',
          'd' => 'day',
          'h' => 'hour',
          'i' => 'minute',
      ];
      
      foreach ($lookup as $property => $word) {
          if ($diff->$property) {
              if ($property === 'd' && $diff->$property >= 7) {
                  $diff->w = (int)($diff->$property / 7);
                  $property = 'w';
                  $word = 'week';
              }
              $output = "for {$diff->$property} $word" . ($diff->$property !== 1 ? 's' : '');
              break;
          }
      }
      echo $output ?? 'for mere seconds';
      

      输出(使用03.12.2021 13:00 作为静态当前日期时间的表格):

      input output
      03.12.2021 13:00 for mere seconds
      03.12.2021 12:59 for 1 minute
      03.12.2021 12:32 for 28 minutes
      03.12.2021 11:21 for 1 hour
      03.12.2021 09:12 for 3 hours
      02.12.2021 02:03 for 1 day
      27.11.2021 11:11 for 6 days
      25.11.2021 13:11 for 1 week
      04.11.2021 15:15 for 4 weeks
      10.10.2021 17:59 for 1 month
      27.04.2021 01:35 for 7 months
      27.04.2020 01:35 for 1 year
      27.04.2009 01:35 for 12 years

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-22
        • 1970-01-01
        • 1970-01-01
        • 2015-04-27
        • 2018-10-06
        • 2016-11-29
        • 2013-12-28
        相关资源
        最近更新 更多