Kalendarz Powtarzające Się / Powtarzające Się Wydarzenia-Najlepsza Metoda Przechowywania

Buduję niestandardowy system zdarzeń, a jeśli masz powtarzające się zdarzenie, które wygląda tak:

Event a powtarza się co 4 dni od 3 marca 2011

LUB

Event B powtarza się co 2 tygodnie we wtorek począwszy od 1 marca 2011

Jak mogę to zapisać w bazie danych w sposób, który ułatwi wyszukiwanie. Nie chcę problemów z wydajnością, jeśli jest duża liczba zdarzeń, i muszę przejść przez każdy z nich podczas renderowania kalendarz.

Author: Brandon Wamboldt, 2011-03-03

11 answers

Przechowywanie" Prostych " Powtarzających Się Wzorców

W moim kalendarzu opartym na PHP/MySQL chciałem przechowywać powtarzające się/powtarzające się informacje o zdarzeniach tak efektywnie, jak to tylko możliwe. Nie chciałem mieć dużej liczby wierszy i chciałem łatwo wyszukać wszystkie wydarzenia, które miały miejsce w określonej dacie.

Poniższa metoda jest świetna w przechowywaniu powtarzających się informacji, które występują w regularnych odstępach czasu, takich jak codziennie, co n dni, co tydzień, co miesiąc co rok, itp itd. Dotyczy to również wzorców typowania we wtorek i czwartek, ponieważ są one przechowywane oddzielnie, jak co tydzień, począwszy od wtorku i co tydzień, począwszy od czwartku.

Zakładając, że mam dwie tabele, jedna o nazwie events tak:

ID    NAME
1     Sample Event
2     Another Event

I tabelę o nazwie events_meta w ten sposób:

ID    event_id      meta_key           meta_value
1     1             repeat_start       1299132000
2     1             repeat_interval_1  432000

Repeat_start jest datą bez czasu jako znacznik czasu Uniksa, a repeat_interval jest wartością w sekundach między interwałami (432000 to 5 dni).

Repeat_interval_1 przechodzi z repeat_start ID 1. Więc jeśli mam zdarzenie, które powtarza się w każdy wtorek i w każdy czwartek, repeat_interval będzie wynosił 604800( 7 dni) i będą 2 repeat_starts i 2 repeat_intervals. Tabela wyglądałaby tak:

ID    event_id      meta_key           meta_value
1     1             repeat_start       1298959200 -- This is for the Tuesday repeat
2     1             repeat_interval_1  604800
3     1             repeat_start       1299132000 -- This is for the Thursday repeat
4     1             repeat_interval_3  604800
5     2             repeat_start       1299132000
6     2             repeat_interval_5  1          -- Using 1 as a value gives us an event that only happens once

Następnie, jeśli masz kalendarz, który zapętla się każdego dnia, chwytając wydarzenia Dla dnia, w którym jest, zapytanie wyglądałoby tak:

SELECT EV.*
FROM `events` EV
RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id`
RIGHT JOIN `events_meta` EM2 ON EM2.`meta_key` = CONCAT( 'repeat_interval_', EM1.`id` )
WHERE EM1.meta_key = 'repeat_start'
    AND (
        ( CASE ( 1299132000 - EM1.`meta_value` )
            WHEN 0
              THEN 1
            ELSE ( 1299132000 - EM1.`meta_value` )
          END
        ) / EM2.`meta_value`
    ) = 1
LIMIT 0 , 30

Zastąpienie {current_timestamp} znacznikiem czasu Uniksa dla bieżącej daty (Minus czas, więc wartości godzin, minut i sekund zostaną ustawione na 0).

Mam nadzieję, że to pomoże również komuś innemu!


Przechowywanie" Złożonych " Powtarzających Się Wzorców

Ta metoda lepiej nadaje się do przechowywania złożonych wzorców, takich jak

Event A repeats every month on the 3rd of the month starting on March 3, 2011

Lub

Event A repeats Friday of the 2nd week of the month starting on March 11, 2011

Polecam połączenie tego z powyższym systemem, aby uzyskać największą elastyczność. Tabele do tego powinny wyglądać następująco:

ID    NAME
1     Sample Event
2     Another Event

I tabelę o nazwie events_meta Jak to:

ID    event_id      meta_key           meta_value
1     1             repeat_start       1299132000 -- March 3rd, 2011
2     1             repeat_year_1      *
3     1             repeat_month_1     *
4     1             repeat_week_im_1   2
5     1             repeat_weekday_1   6

repeat_week_im reprezentuje tydzień bieżącego miesiąca, który potencjalnie może wynosić od 1 do 5. repeat_weekday w dniu tygodnia, 1-7.

Teraz zakładając, że przeglądasz dni / tygodnie, aby utworzyć widok miesiąca w kalendarzu, możesz skomponować zapytanie takie jak:

SELECT EV . *
FROM `events` AS EV
JOIN `events_meta` EM1 ON EM1.event_id = EV.id
AND EM1.meta_key = 'repeat_start'
LEFT JOIN `events_meta` EM2 ON EM2.meta_key = CONCAT( 'repeat_year_', EM1.id )
LEFT JOIN `events_meta` EM3 ON EM3.meta_key = CONCAT( 'repeat_month_', EM1.id )
LEFT JOIN `events_meta` EM4 ON EM4.meta_key = CONCAT( 'repeat_week_im_', EM1.id )
LEFT JOIN `events_meta` EM5 ON EM5.meta_key = CONCAT( 'repeat_weekday_', EM1.id )
WHERE (
  EM2.meta_value =2011
  OR EM2.meta_value = '*'
)
AND (
  EM3.meta_value =4
  OR EM3.meta_value = '*'
)
AND (
  EM4.meta_value =2
  OR EM4.meta_value = '*'
)
AND (
  EM5.meta_value =6
  OR EM5.meta_value = '*'
)
AND EM1.meta_value >= {current_timestamp}
LIMIT 0 , 30

To w połączeniu z powyższą metodą można połączyć, aby pokryć większość powtarzających się/powtarzających się wzorców zdarzeń. Jeśli coś przeoczyłem proszę zostawić komentarz.

 182
Author: Brandon Wamboldt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-01 12:01:10

Chociaż obecnie akceptowana odpowiedź była dla mnie ogromną pomocą, chciałem podzielić się kilkoma przydatnymi modyfikacjami, które upraszczają zapytania, a także zwiększają wydajność.


"Proste" Powtarzanie Zdarzeń

Do obsługi zdarzeń powtarzających się w regularnych odstępach czasu, takich jak:

Repeat every other day 

Lub

Repeat every week on Tuesday 

Powinieneś utworzyć dwie tabele, jedna o nazwie events w następujący sposób:

ID    NAME
1     Sample Event
2     Another Event

I tabelę o nazwie events_meta w ten sposób:

ID    event_id      repeat_start       repeat_interval
1     1             1369008000         604800            -- Repeats every Monday after May 20th 2013
1     1             1369008000         604800            -- Also repeats every Friday after May 20th 2013

With repeat_start being a Unix timestamp Data bez czasu (1369008000 odpowiada 20 maja 2013) i repeat_interval kwota w sekundach między interwałami (604800 to 7 dni).

Poprzez zapętlenie każdego dnia w kalendarzu możesz uzyskać powtarzające się zdarzenia za pomocą tego prostego zapytania:

SELECT EV.*
FROM `events` EV
RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id`
WHERE  (( 1299736800 - repeat_start) % repeat_interval = 0 )

Wystarczy zastąpić uniksowy znacznik czasu (1299736800) dla każdej daty w kalendarzu.

Zwróć uwagę na użycie znaku modulo ( % ). Symbol ten jest jak regularny podział, ale Zwraca "resztę" zamiast ilorazu i jako taki wynosi 0, gdy bieżąca data jest dokładną wielokrotnością repeat_interval z repeat_start.

Porównanie Wydajności

Jest to znacznie szybsza odpowiedź niż sugerowana wcześniej odpowiedź "meta_keys", która była następująca:]}
SELECT EV.*
FROM `events` EV
RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id`
RIGHT JOIN `events_meta` EM2 ON EM2.`meta_key` = CONCAT( 'repeat_interval_', EM1.`id` )
WHERE EM1.meta_key = 'repeat_start'
    AND (
        ( CASE ( 1299132000 - EM1.`meta_value` )
            WHEN 0
              THEN 1
            ELSE ( 1299132000 - EM1.`meta_value` )
          END
        ) / EM2.`meta_value`
    ) = 1

Jeśli uruchomisz EXPLAIN to zapytanie, zauważysz, że wymagało ono użycia bufora przyłączeniowego:

+----+-------------+-------+--------+---------------+---------+---------+------------------+------+--------------------------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref              | rows | Extra                          |
+----+-------------+-------+--------+---------------+---------+---------+------------------+------+--------------------------------+
|  1 | SIMPLE      | EM1   | ALL    | NULL          | NULL    | NULL    | NULL             |    2 | Using where                    |
|  1 | SIMPLE      | EV    | eq_ref | PRIMARY       | PRIMARY | 4       | bcs.EM1.event_id |    1 |                                |
|  1 | SIMPLE      | EM2   | ALL    | NULL          | NULL    | NULL    | NULL             |    2 | Using where; Using join buffer |
+----+-------------+-------+--------+---------------+---------+---------+------------------+------+--------------------------------+

Rozwiązanie z 1 łącznikiem powyżej nie wymaga takiego bufora.


"Złożone" Wzory

Możesz dodawanie obsługi bardziej złożonych typów, aby obsługiwać te typy reguł powtarzania:

Event A repeats every month on the 3rd of the month starting on March 3, 2011

Lub

Event A repeats second Friday of the month starting on March 11, 2011

Twoja tabela zdarzeń może wyglądać dokładnie tak samo:

ID    NAME
1     Sample Event
2     Another Event

Następnie, aby dodać obsługę tych złożonych reguł dodaj kolumny do events_meta w następujący sposób:

ID    event_id      repeat_start       repeat_interval    repeat_year    repeat_month    repeat_day    repeat_week    repeat_weekday
1     1             1369008000         604800             NULL           NULL            NULL          NULL           NULL             -- Repeats every Monday after May 20, 2013
1     1             1368144000         604800             NULL           NULL            NULL          NULL           NULL             -- Repeats every Friday after May 10, 2013
2     2             1369008000         NULL               2013           *               *             2              5                -- Repeats on Friday of the 2nd week in every month    

Zauważ, że po prostu musisz podać repeat_interval lub zestaw repeat_year, repeat_month, repeat_day, repeat_week, i repeat_weekday dane.

To sprawia, że wybór obu typów jednocześnie jest bardzo prosty. Wystarczy przełączyć 1370563200 dla 7 czerwca 2013, a następnie Rok, Miesiąc, Dzień, numer tygodnia i Dzień tygodnia w następujący sposób):

SELECT EV.*
FROM `events` EV
RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id`
WHERE  (( 1370563200 - repeat_start) % repeat_interval = 0 )
  OR ( 
    (repeat_year = 2013 OR repeat_year = '*' )
    AND
    (repeat_month = 6 OR repeat_month = '*' )
    AND
    (repeat_day = 7 OR repeat_day = '*' )
    AND
    (repeat_week = 2 OR repeat_week = '*' )
    AND
    (repeat_weekday = 5 OR repeat_weekday = '*' )
    AND repeat_start <= 1370563200
  )

Zwraca wszystkie zdarzenia, które powtarzają się w piątek drugiego tygodnia, , jak również wszelkie zdarzenia, które powtarzają się w każdy piątek, więc zwraca zarówno Zdarzenie o ID 1, jak i 2:

ID    NAME
1     Sample Event
2     Another Event
W tym przypadku nie jest to możliwe, ale jest to możliwe tylko w przypadku, gdy nie jest to możliwe.]}

Mam nadzieję, że to pomoże innym tak bardzo jak oryginalna odpowiedź mi pomogła!

 158
Author: ahoffner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-01 12:00:53

Dla wszystkich, którzy są zainteresowani tym, teraz Można po prostu skopiować i wkleić, aby rozpocząć w ciągu kilku minut. Skorzystałem z porad w komentarzach najlepiej jak mogłem. Daj znać, jeśli coś przeoczę.

"WERSJA ZŁOŻONA": {]}

Wydarzenia

+----------+----------------+
| ID       | NAME           | 
+----------+----------------+
| 1        | Sample event 1 |
| 2        | Second  event  |
| 3        | Third event    |
+----------+----------------+

Events_meta

+----+----------+--------------+------------------+-------------+--------------+------------+-------------+----------------+
| ID | event_id | repeat_start | repeat_interval  | repeat_year | repeat_month | repeat_day | repeat_week | repeat_weekday |
+----+----------+--------------+------------------+-------------+--------------+------------+-------------+----------------+
| 1  | 1        | 2014-07-04   | 7                | NULL        | NULL         | NULL       | NULL        | NULL           |
| 2  | 2        | 2014-06-26   | NULL             | 2014        | *            | *          | 2           | 5              |
| 3  | 3        | 2014-07-04   | NULL             | *           | *            | *          | *           | 5              |
+----+----------+--------------+------------------+-------------+--------------+------------+-------------+----------------+

Kod SQL:

CREATE TABLE IF NOT EXISTS `events` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(255) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;

--
-- Dumping data for table `events`
--

INSERT INTO `events` (`ID`, `NAME`) VALUES
(1, 'Sample event'),
(2, 'Another event'),
(3, 'Third event...');

CREATE TABLE IF NOT EXISTS `events_meta` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `event_id` int(11) NOT NULL,
  `repeat_start` date NOT NULL,
  `repeat_interval` varchar(255) NOT NULL,
  `repeat_year` varchar(255) NOT NULL,
  `repeat_month` varchar(255) NOT NULL,
  `repeat_day` varchar(255) NOT NULL,
  `repeat_week` varchar(255) NOT NULL,
  `repeat_weekday` varchar(255) NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `ID` (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;

--
-- Dumping data for table `events_meta`
--

INSERT INTO `events_meta` (`ID`, `event_id`, `repeat_start`, `repeat_interval`, `repeat_year`, `repeat_month`, `repeat_day`, `repeat_week`, `repeat_weekday`) VALUES
(1, 1, '2014-07-04', '7', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL'),
(2, 2, '2014-06-26', 'NULL', '2014', '*', '*', '2', '5'),
(3, 3, '2014-07-04', 'NULL', '*', '*', '*', '*', '1');

Dostępny również jako MySQL export (dla łatwego dostępu)

Indeks przykładowego kodu PHP.php:

<?php
    require 'connect.php';    

    $now = strtotime("yesterday");

    $pushToFirst = -11;
    for($i = $pushToFirst; $i < $pushToFirst+30; $i++)
    {
        $now = strtotime("+".$i." day");
        $year = date("Y", $now);
        $month = date("m", $now);
        $day = date("d", $now);
        $nowString = $year . "-" . $month . "-" . $day;
        $week = (int) ((date('d', $now) - 1) / 7) + 1;
        $weekday = date("N", $now);

        echo $nowString . "<br />";
        echo $week . " " . $weekday . "<br />";



        $sql = "SELECT EV.*
                FROM `events` EV
                RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id`
                WHERE ( DATEDIFF( '$nowString', repeat_start ) % repeat_interval = 0 )
                OR ( 
                    (repeat_year = $year OR repeat_year = '*' )
                    AND
                    (repeat_month = $month OR repeat_month = '*' )
                    AND
                    (repeat_day = $day OR repeat_day = '*' )
                    AND
                    (repeat_week = $week OR repeat_week = '*' )
                    AND
                    (repeat_weekday = $weekday OR repeat_weekday = '*' )
                    AND repeat_start <= DATE('$nowString')
                )";
        foreach ($dbConnect->query($sql) as $row) {
            print $row['ID'] . "\t";
            print $row['NAME'] . "<br />";
        }

        echo "<br /><br /><br />";
    }
?>

Przykładowy kod PHP połącz się.php:

<?
// ----------------------------------------------------------------------------------------------------
//                                       Connecting to database
// ----------------------------------------------------------------------------------------------------
// Database variables
$username = "";
$password = "";
$hostname = ""; 
$database = ""; 

// Try to connect to database and set charset to UTF8
try {
    $dbConnect = new PDO("mysql:host=$hostname;dbname=$database;charset=utf8", $username, $password);
    $dbConnect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}
// ----------------------------------------------------------------------------------------------------
//                                      / Connecting to database
// ----------------------------------------------------------------------------------------------------
?>

Również kod php jest dostępny tutaj (dla lepszej czytelności):
indeks.php
oraz
połącz się.php
Przygotowanie tego zajmie ci kilka minut. Nie godziny. :)

 21
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-12 19:35:57

Enhancement: zamień znacznik czasu na datę

Jako małe rozszerzenie przyjętej odpowiedzi, która została następnie udoskonalona przez ahoffnera - możliwe jest użycie formatu daty zamiast znacznika czasu. Zalety:

  1. czytelne daty w bazie danych
  2. brak problemu z latami > 2038 i znacznikiem czasu
  3. usuwa trzeba uważać na znaczniki czasu, które są oparte na terminach dostosowanych sezonowo tj. w Wielkiej Brytanii 28 czerwca zaczyna się godzinę wcześniej niż 28 grudnia tak więc wyprowadzenie znacznika czasu z daty może złamać algorytm rekurencji.

Aby to zrobić, zmień DB repeat_start, który ma być przechowywany jako typ "date" I repeat_interval przechowuj teraz dni, a nie sekundy. tj. 7 przez 7 dni.

Zmień linię sql: WHERE ((1370563200-repeat_start) % repeat_interval = 0)

To: WHERE (DATEDIFF ('2013-6-7', event_start) % repeat_interval = 0)

Wszystko inne pozostaje takie samo. Simples!
 20
Author: user3781087,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-30 10:51:57

Podczas gdy proponowane rozwiązania działają, próbowałem zaimplementować z pełnym kalendarzem i wymagałoby to ponad 90 wywołań baz danych dla każdego widoku( ponieważ ładuje bieżący, poprzedni i następny miesiąc), co, nie byłem zbyt zachwycony.

Znalazłem bibliotekę rekurencji https://github.com/tplaner/When gdzie po prostu przechowujesz reguły w bazie danych i jedno zapytanie, aby pobrać wszystkie odpowiednie reguły.

Mam nadzieję, że to pomoże komuś innemu, ponieważ spędziłem tak wiele godzin próbując znaleźć dobre rozwiązanie.

Edit: ta Biblioteka jest dla PHP

 14
Author: Tim Ramsey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-17 13:47:35

Dlaczego nie użyć mechanizmu podobnego do zadań Apache cron? http://en.wikipedia.org/wiki/Cron

Dla kalendarza \ scheduling użyłbym nieco innych wartości dla "bitów", aby pomieścić standardowe zdarzenia powtarzania kalendarza - zamiast [dzień tygodnia (0 - 7), miesiąc (1 - 12), dzień miesiąca (1 - 31), godzina (0 - 23), min (0-59)]

-- użyłbym czegoś takiego [Rok (powtórz co N lat), miesiąc (1 - 12), dzień miesiąca (1 - 31), tydzień miesiąca (1-5), dzień tygodnia (0 - 7)]

Mam nadzieję, że to pomoże.

 13
Author: Vladimir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-08 22:21:03

Podążałbym za tym przewodnikiem: https://github.com/bmoeskau/Extensible/blob/master/recurrence-overview.md

Upewnij się również, że używasz formatu iCal, aby nie odkrywać koła na nowo i pamiętaj Zasada #0: nie przechowuj pojedynczych powtarzających się wystąpień zdarzeń jako wierszy w bazie danych!

 13
Author: Gal Bracha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-05 15:51:41

Brzmi bardzo podobnie do zdarzeń MySQL, które są przechowywane w tabelach systemowych. Możesz spojrzeć na strukturę i dowiedzieć się, które kolumny nie są potrzebne:

   EVENT_CATALOG: NULL
    EVENT_SCHEMA: myschema
      EVENT_NAME: e_store_ts
         DEFINER: jon@ghidora
      EVENT_BODY: SQL
EVENT_DEFINITION: INSERT INTO myschema.mytable VALUES (UNIX_TIMESTAMP())
      EVENT_TYPE: RECURRING
      EXECUTE_AT: NULL
  INTERVAL_VALUE: 5
  INTERVAL_FIELD: SECOND
        SQL_MODE: NULL
          STARTS: 0000-00-00 00:00:00
            ENDS: 0000-00-00 00:00:00
          STATUS: ENABLED
   ON_COMPLETION: NOT PRESERVE
         CREATED: 2006-02-09 22:36:06
    LAST_ALTERED: 2006-02-09 22:36:06
   LAST_EXECUTED: NULL
   EVENT_COMMENT:
 4
Author: Valentin Kuzub,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-22 13:33:18

Stworzyłem ezoteryczny język programowania właśnie do tego przypadku. Najlepsze jest to, że jest mniej schematów i niezależny od platformy. Wystarczy, że napiszesz program selektora do swojego harmonogramu, którego składnia jest ograniczona zestawem reguł opisanych tutaj -

Https://github.com/tusharmath/sheql/wiki/Rules

Zasady są rozszerzalne i można dodać dowolny rodzaj dostosowywania w oparciu o rodzaj logiki powtórzeń, które chcesz wykonać, bez martwiąc się o migracje schematów itp.

Jest to zupełnie inne podejście i może mieć swoje wady.

 4
Author: Tushar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-14 15:40:13

@ Rogue Coder

To jest świetne!

Możesz po prostu użyć operacji modulo (MOD lub % w mysql), aby Kod był prosty na końcu:

Zamiast:

AND (
    ( CASE ( 1299132000 - EM1.`meta_value` )
        WHEN 0
          THEN 1
        ELSE ( 1299132000 - EM1.`meta_value` )
      END
    ) / EM2.`meta_value`
) = 1

Do:

$current_timestamp = 1299132000 ;

AND ( ('$current_timestamp' - EM1.`meta_value` ) MOD EM2.`meta_value`) = 1")
Aby pójść dalej, można uwzględnić wydarzenia, które nie powtarzają się na zawsze.

Można dodać coś w rodzaju "repeat_interval_1_end" oznaczającego datę ostatniej "repeat_interval_1". To jednak sprawia, że zapytanie jest bardziej skomplikowane i nie mogę naprawdę dowiedzieć się, jak to zrobić to ...

Może ktoś mógłby pomóc!
 3
Author: dorogz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-03 07:53:50

Dwa przykłady, które podałeś są bardzo proste; można je przedstawić jako prosty przedział (pierwszy to cztery dni, drugi to 14 dni). Sposób modelowania będzie zależał całkowicie od złożoności Twoich nawrotów. Jeśli to, co masz powyżej, jest naprawdę takie proste, Zapisz datę początkową i liczbę dni w przedziale powtórzeń.

Jeśli jednak musisz wspierać takie rzeczy jak

Event A powtarza się co miesiąc 3 dnia miesiąca rozpoczynającego się 3 marca, 2011

LUB

Event a powtarza drugi piątek miesiąca od 11 marca 2011

To jest o wiele bardziej złożony wzór.

 1
Author: Adam Robinson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-03 16:41:12