【问题标题】:Display recurring dates from SQL Database using PHP使用 PHP 显示 SQL 数据库中的重复日期
【发布时间】:2013-02-02 07:04:04
【问题描述】:

我正在访问由另一家网络公司创建的数据库,以检索我当前客户的事件信息。我的客户输入事件信息并记录日期是否重复。我正在尝试显示所有重复日期。到目前为止,我已经能够显示所有内容,包括常规日期和重复日期。

表格排列如下:

  • 活动
  • Events_Recurring

这是事件表的一部分BIGGER PICTURE

这就是 Events_Recurring 表的样子

当客户端将其检查为重复时,events_recurring 表会创建一行,其中包含事件 ID 和其他信息,例如该事件在一周中的哪一天或每月的哪一天重复发生。

我只是不确定如何显示重复出现的特定 ID 的倍数。我有一个可以访问的开始日期和结束日期,以及它在一周中的哪一天重复出现。

例如:如果此事件在每个星期四再次发生。我知道它从 1 月 1 日开始,到 1 月 31 日结束,我可以通过它找出 4 个不同的事件,所有事件的日期都是 1 月的每个星期四吗?

这是我正在使用的完整代码,在尝试解决这个问题时有点混乱。我正在检查底部的重复率

// Access external database
$events_db = new wpdb(TOP SECRET CREDENTIALS HERE);
$events_db->show_errors();

if ($events_db) :
    // Query Events Database
    $events = $events_db->get_results(
        "
        SELECT ID, RequestDateStart, RequestDateEnd, Ministry, RequestTimeStart, EventName, CoordinatorName, EventDescription, Location
        FROM gc_events
        WHERE PrivateEvent = 0
        AND Ministry = 15
        AND date(RequestDateStart)>=date(NOW())
        ORDER BY RequestDateStart
        "
    );

    // Create the event data that will be displayed
    foreach ($events as $event) :

        // Store Event ID in a variable
        $masterID = $event->ID;

        echo '<div class="col-12">';

        echo '<strong>ID:</strong> ' . $event->ID . '<br /><strong>Event Name:</strong> ' . $event->EventName . '<br /><strong>Leader:</strong> ' . $event->CoordinatorName . '<br /><strong>Date:</strong> ' . date('l, F j',strtotime($event->RequestDateStart)) . '<br /><strong>Start Time:</strong> ' . date('g:i a',strtotime($event->RequestTimeStart));

        // CHECK IF RECURRING

        $recurring_events = $events_db->get_results(
            "
            SELECT gc_event_id, period, day
            FROM gc_event_recurring
            WHERE gc_event_id = '$masterID'
            "
        );

        foreach ($recurring_events as $recurring_event) :
        if ($recurring_event->period === 'week') {

        echo '<div class="col-12"><strong>&uarr; WEEKLY</strong><br />';

        echo $recurring_event->day;

        echo '</div>';

        }
        endforeach;

        echo '</div>';

    endforeach;
endif;

我现在得到的结果(重复事件)是

活动:每周祈祷
日期:2013 年 2 月 1 日

我想要的结果是

活动:每周祈祷
日期:2013 年 2 月 1 日

活动:每周祈祷
日期:2013 年 2 月 8 日

活动:每周祈祷
日期:2013 年 2 月 15 日

活动:每周祈祷
日期:2013 年 2 月 22 日


如果开始日期是 2 月 1 日,结束日期是 2 月 28 日。

【问题讨论】:

  • 您的问题令人困惑,能否请您显示代码,是的,请尝试以一种好的方式定义您的问题,不要惊慌,冷静并写下
  • 尽量不要惊慌 :) 添加了更多信息,以及我正在使用的代码
  • 所以,重复事件显示多次?
  • ($recurring_event-&gt;period === 'week') 不要使用=== 使用==
  • 请发布表结构和临时数据;也是您想要获得的样本结果

标签: php mysql


【解决方案1】:

忠告。

虽然从设计的角度来看,设计一个数据库来存储重复模式的“描述”是一种非常简洁的方法,但您可能会遇到很多问题。

我不久前用类似的方法完成了一个项目(我将查找数据库设计并将其添加到我的答案中),虽然我能够重现重复事件的确切日期/时间,但您在以下情况下会遇到问题;大部分源于此:

重复事件描述重复模式,因此实际(个别)事件在您的数据库中没有物理记录

  1. 如果客户决定添加新事件,您将如何检查它是否与任何现有事件重叠?您必须根据重复模式计算所有“事件”。
  2. 如果客户决定需要更改某个活动的预定时间,您将如何将此更改应用于所有未来事件,而不适用于过去的事件(您将必须复制原始事件,修改其结束日期,并将复制的事件设置为新的开始日期)
  3. 如果客户决定从重复模式中删除一天(例如,一个事件已被取消),您还必须将原始事件拆分为 两个 单独的重复,有一个“取消/阻止”的日期/时间表
  4. 如果人们需要为特定事件“预订”,您将无法将它们附加到“真实”事件记录中,因为单个事件并不实际存在于数据库中。例如要检查单个事件是否可以重新安排或取消,您需要从代码中执行此操作,因为数据库无法使用外键约束来自动更新相关预订
  5. 关于性能;由于单个事件没有物理存储,因此每次您都必须对其进行计算以显示它们。考虑在数据库中有 1000 个重复事件,并尝试显示两年后第 23 周的“日历”。您必须分析所有重复事件模式并计算它们产生的所有事件!

当然,这一切都取决于您系统的实际使用情况,但我想警告您我们遇到的问题。

这是“时间表”表的架构(包含重复事件模式);

CREATE TABLE IF NOT EXISTS `schedules` (
  `id`              int(11)     NOT NULL auto_increment,
  `date_start`      date        NOT NULL,
  `time_start`      time        NOT NULL,
  `time_end`        time        NOT NULL,
  `recur_until`     date        default NULL COMMENT 'end date when recurrence stops',
  `recur_freq`      varchar(30) default NULL COMMENT 'null, "secondly", "minutely", "hourly", "daily", "weekly", "monthly", "yearly"',
  `recur_interval`  smallint(5) unsigned default NULL COMMENT 'e.g. 1 for each day/week, 2 for every other day/week',
  `recur_byday`     smallint(5) unsigned default NULL COMMENT 'BITWISE; monday = 1, sunday = 64',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

如何规避上述问题

在这里完全描述这些问题的解决方案可能不合适,但这里有一些事情需要考虑;

按照描述的方式存储重复发生的事件不是不好的做法。它完美地描述了事件应该发生的时间和频率。然而,实际事件的物理记录的缺乏是导致问题的原因。

  1. 创建修改重复事件时,计算所有结果事件并将它们存储为物理记录。可以查询这些记录,可以将“保留”附加到它们,您将能够利用数据库功能(例如外键约束)来正确处理它们。
  2. 按 1. 中所述存储单个事件时,请确保保留对它们所属的“计划”的引用。如果(例如)客户想要更改重复事件的时间,您将能够更新所有相关(单个)事件。
  3. 请记住,在情况 2 中,您可能只想更新 未来 事件,因此“重复事件”仍需要“拆分”为两部分才能实现。在这种情况下,需要将“未来”事件附加到新的“重复事件”,旧事件仍会附加到现有的“重复事件”

在您的数据库/软件设计上投入时间,适当地调查该设计是否会为您想要实现的目标“工作”。测试它,尝试一些东西,如果它们不起作用,不要犹豫,“扔掉它”,通常从头开始比尝试“修复”更容易。正确的设计需要时间,并且可能需要多次“重新设计”才能使其正确,但它最终为您节省时间和金钱。

希望这会有所帮助,祝你好运!

【讨论】:

  • 哇,谢谢你提供的信息!实际上,我这周才开始搞数据库。我没有构建我正在使用的当前数据库,只是试图从中提取信息。尽管我会牢记,但您确实提出了一些可靠的观点。谢谢!
  • @ftntravis 不客气。我将在我的帖子中添加一些额外信息,以规避所描述的问题
  • 我喜欢它。谢谢!这是一个很好的回应,来自平面设计背景,我绝对可以看到构建一个漂亮、可读的数据库的艺术。
【解决方案2】:
        foreach ($events as $event) :

                // Store Event ID in a variable
                $masterID = $event->ID;

                echo '<div class="col-12">';

                echo '<strong>ID:</strong> ' . $event->ID . '<br /><strong>Event Name:</strong> ' . $event->EventName . '<br /><strong>Leader:</strong> ' . $event->CoordinatorName . '<br /><strong>Date:</strong> ' . date('l, F j',strtotime($event->RequestDateStart)) . '<br /><strong>Start Time:</strong> ' . date('g:i a',strtotime($event->RequestTimeStart));

                // CHECK IF RECURRING

                $recurring_events = $events_db->get_results(
                    "
                    SELECT gc_event_id, period, day
                    FROM gc_event_recurring
                    WHERE gc_event_id = '$masterID'
                    "
                );

                foreach ($recurring_events as $recurring_event) :
                if ($recurring_event->period == 'week') {
                $StartDate = strtotime($event->RequestDateStart);
                $EndDate = strtotime($event->RequestDateEnd);
$TotalDays = round(($EndDate-$StartDate)/(60*60*24*7));
                for($i = 0 ;$i<($TotalDays-1);$i++)
                {
                $StartDate += (60*60*24*7);
                echo '<div class="col-12">';

                echo '<strong>ID:</strong> ' . $event->ID . '<br /><strong>Event Name:</strong> ' . $event->EventName . '<br /><strong>Leader:</strong> ' . $event->CoordinatorName . '<br /><strong>Date:</strong> ' . date('l, F j',$StartDate) . '<br /><strong>Start Time:</strong> ' . date('g:i a',strtotime($event->RequestTimeStart));


                }


                }
                endforeach;

                echo '</div>';

            endforeach;

试试这个,告诉我它是否有效

【讨论】:

  • $recurring_event-&gt;dayday of the week 我相信。
  • 但在表格中我认为它是一个计数。在问题中看到。他可以用那个东西来计算它是什么
  • 啊几乎!我认为它正在工作,但在检查它们时,有些已经超过了它们应该结束的日期。客户输入我可以使用的开始日期和结束日期。我猜这些可以解决过去的问题?
  • 你面临什么问题,你能告诉我你现在得到的结果吗?
  • 您可以在此处看到:beta.revival.tv/test 应该结束的事件仍在填充更多日期。
猜你喜欢
  • 2016-09-01
  • 2023-03-12
  • 2012-03-10
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-21
相关资源
最近更新 更多