按日期的群集时间戳

时间:2014-04-20 10:34:02

标签: php algorithm

我有一个包含时间戳的数组。我想知道像Facebook等应用程序集群帖子。为清楚起见,假设您有一组时间戳,并希望通过以下方式对时间戳进行分组:

  • 今天
  • 本周
  • 本月
  • 1月,2月,3月
  • 2013
  • 2012等等

这个月的帖子非常重要'不要在本周重播'而那些反过来又不会在今天重复#39;此外,我已经硬编码Jan,Feb&三月以上。该脚本应该在技术上检测一年中的前几个月。我无法完全编写算法来实现这一目标。这就是我所拥有的。

<?php
    $posts = array(
        array('post_id' => 7, 'timestamp' => '2014-04-20 20:17:49'),
        array('post_id' => 6, 'timestamp' => '2014-04-07 20:17:49'),
        array('post_id' => 5, 'timestamp' => '2014-03-17 20:17:49'),
        array('post_id' => 4, 'timestamp' => '2014-02-14 20:17:49'),
        array('post_id' => 3, 'timestamp' => '2014-01-09 20:17:49'),
        array('post_id' => 2, 'timestamp' => '2013-09-23 20:17:49'),
        array('post_id' => 1, 'timestamp' => '2012-09-23 20:17:49')
    );

    $today = strtotime(date("Y-m-d"));
    $week_start = strtotime('last sunday', strtotime('tomorrow'));
    $month_start = strtotime(date_create(date("Y-m-d"))->modify('first day of this month')->format("Y-m-d"));
    $year_start = strtotime(date_create(date("Y-m-d"))->modify('first day of january 2014')->format("Y-m-d"));

    foreach ($posts as $post)
    {
        $item = strtotime($post['timestamp']);

        if ($item >= $today)
        {
            // Today
            echo '<br><br>' . 'Today' . '<br>';
            echo $post['post_id'] . '<br>';
        }
        else if (($item <= $today) && ($item >= $week_start))
        {
            // This week
            echo '<br><br>' . 'This week' . '<br>';
            echo $post['post_id'] . '<br>';
        }
        else if (($item <= $week_start) && ($item >= $month_start))
        {
            // This month
            echo '<br><br>' . 'This month' . '<br>';
            echo $post['post_id'] . '<br>';
        }
        else if (($item <= $month_start) && ($item >= $year_start))
        {
           // This year
           echo '<br><br>' . 'This year' . '<br>';
           echo $post['post_id'] . '<br>';
        }
    }

这个脚本一直工作到本月&#39;并将剩下的只剩下今年的&#39;。我无法按月对它们进行分类,而且在今年之前无法进行分类。实现此级别群集并快速完成的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

这有点粗糙,但应该可以胜任。

你提到今年1月之后该组合应该回到年份(2013年,2012年等) - 好吧,为了一点点味道,我还增加了'去年'的额外限制,就这样你可以看到datetime formats的可能性。

我还添加了一个额外的帖子,因此您可以看到“本周”正常工作。我没有彻底测试边界,所以可能还有一些改进空间。

$posts = array(
    array('post_id' => 8, 'timestamp' => '2014-04-20 20:17:49'),
    array('post_id' => 7, 'timestamp' => '2014-04-16 20:17:49'),
    array('post_id' => 6, 'timestamp' => '2014-04-07 20:17:49'),
    array('post_id' => 5, 'timestamp' => '2014-03-17 20:17:49'),
    array('post_id' => 4, 'timestamp' => '2014-02-14 20:17:49'),
    array('post_id' => 3, 'timestamp' => '2014-01-09 20:17:49'),
    array('post_id' => 2, 'timestamp' => '2013-09-23 20:17:49'),
    array('post_id' => 1, 'timestamp' => '2012-09-23 20:17:49')
);

// Set some limits
$limits = array(
    array('name' => 'Today',      'date' => new DateTime('today')),
    array('name' => 'This Week',  'date' => new DateTime('last sunday')),
    array('name' => 'This Month', 'date' => new DateTime('first day of this month midnight')),
    array('name' => 'Last Year',  'date' => new DateTime('first day of last year midnight')),
);

// Backfill months from this month to January of this year
for ($m = date('m') - 1; $m > 0; $m--) {
    $dateTime = new DateTime(sprintf('first day of %d month ago midnight', $m));
    $limits[] = array('name' => $dateTime->format('F'), 'date' => $dateTime);
}

// Sort the limits
uasort($limits, function ($date1, $date2) {
    if ($date1['date'] === $date2['date']) {
        return 0;
    }
    return $date1['date'] > $date2['date'] ? -1 : 1;
});

// Find out where each post falls
foreach ($posts as $post) {

    $timestamp = new DateTime($post['timestamp']);

    // Default to the fallback (the year)
    $formatted = $timestamp->format('Y');

    foreach ($limits as $limit) {
        if ($timestamp >= $limit['date']) {
            $formatted = $limit['name'];
            break;
        }
    }

    echo sprintf("ID %s: %s (%s)\n", $post['post_id'], $timestamp->format('dS M Y H:i:s'), $formatted);
}