如何从一系列事件创建日历?

How to create a calendar from an array of events?

我在 Wordpress 中工作,我得到了一个名为事件的自定义 post 类型。

在我使用 get_posts() 检索事件的数组中,我将所有事件按日期从最旧到最新排序。

不,我想要实现的基本上是这些事件的月历。

我知道如何遍历这些并将它们分组为年和日。但是我不知道如何在中间添加空天。

例如,这是一段代码:

$events = array(
    array('Event 1', '2015-04-03'),
    array('Event 2', '2015-04-03'),
    array('Event 3', '2015-06-16'),
    array('Event 4', '2015-06-29'),
    array('Event 5', '2015-07-04'),
    array('Event 6', '2015-12-25'),
    array('Event 7', '2016-01-01')
)

我目前能做的事情:

2015
  April
    3
      Event 1
      Event 2
  June
    16
      Event 3
    29
      Event 4

    ...

我想要做的是从第一个月的第一天开始,经过所有的日子,到那个月的最后一天结束。基本上我正在尝试创建一个日历。

所以我想得到的是:

2015
  April
    1
      empty
    2 
      empty
    3
      Event 1
      Event 2
    4
      empty
    5
      empty

    ...

等等...这样我就可以遍历所有的日子来创建一个日历。但我也不想包括没有事件的月份。所以我不能只在我的数组中选择第一个事件的日期和最后一个事件的日期并从中创建日历,可能有几个月没有事件,我不想显示。

据我所知:

for ($date = strtotime("2015-04-01"); $date < strtotime("2016-01-01"); $date = strtotime("+1 day", $date)) {
    echo date("Y-m-d", $date)."";
}

这当然不会得到我的事件,也不会跳过空白月份,但这是我的起点。

没有 运行 大量查询的最佳方法是什么?

编辑:今天早上醒来后,我意识到有一种比递归函数更简单、更好的方法!

这里是:

$start_date = strtotime("2015-01-01");
$end_date = strtotime("2016-01-01");

$event_no = 0;

for ($date = $start_date; $date  < $end_date; $date = strtotime("+1 month", $date)) {
    $out = "The Month";
    $contains_events = false;
    for ($day = $date; $day  < strtotime("+1 month", $date); $day = strtotime("+1 day", $day)) { 
        foreach ($events as $k => $event) {
            if ($k < $event_no) continue; // Starts the loop where we left off
            if (date("Y-m-d", $day) == $event[1]) {
                $contains_events = true;
                $out .= $event[0]; // Obviously these outputs will require a little formatting.
                $event_no++;
            } else {
                $out .= "Empty";
                break;
            }
        }
    }
    if($contains_events) echo $out;
}

我的旧答案

我能看到的最简单的方法是实现一个自调用函数来检查特定日期,因为这样可以轻松添加一个日期的多个事件。

你可以这样循环:

$start_date = strtotime("2015-01-01");
$end_date = strtotime("2016-01-01");

$event_no = 0;

for ($date = $start_date; $date  < $end_date; $date = strtotime("+1 month", $date)) {

    // For each month

    $out = "The Month";
    $contains_events = false;

    for ($day = $date; $day  < strtotime("+1 month", $date); $day = strtotime("+1 day", $day)) { 

        // For each day in month

        $day_check = check_day($events, $event_no, $day); // Check if day has events

        if($day_check) {
            $out .= $day_check;
            $contains_events = true;
        } else $out .= "Empty";
    }
    if($contains_events) echo $out;
}

然后,假设数据与您的示例相同,您可以使用此函数检查每天的事件:

function check_day($events, &$event_no, $day) {
    if (date("Y-m-d", $day) == $events[$event_no][1]) {

        $ret = $events[$event_no][0]; // Obviously these outputs will require a little formatting.
        $event_no++;
        $ret .= check_day($events, $event_no, $day);
        return $ret;
    } else return null;
}

我已经尽力了,但我还没有时间实际测试它们,所以如果有任何问题,我深表歉意。