36

カレンダー Web サイト ( ) アプリケーション (単純なバージョンの Outlook と考えてください) を構築しASP.NET MVCており、定期的なカレンダー イベント (毎月、毎年など) のサポートを開始したいと考えています。

現在、実際の日付を自分に保存していますが、定期的に日付を保存し続けることが理にかなっているのか (明らかなカットオフがあります)、または定期的なオプションを保存してその場で日付を生成する必要があるかどうかを判断したかったのです。 .

Outlook や google mail などが、定期的なカレンダー アイテムをサポートするサービスやその他のサービスでどのように機能するかを考えさせられました。

これに関する提案はありますか?

4

7 に答える 7

58

データを「正規」データ (繰り返しルール) と「提供」 (生成された日付、再生成以外は読み取り専用) の 2 つの部分に分けます。正規データが変更された場合は、その時点で「提供」データを再生成します。無限の繰り返しの場合、いくつかのインスタンスを保持し、不足した場合 (たとえば、ユーザーが 2020 年のカレンダーを見た場合) にさらに生成します。

無限のプロセッサ速度があれば、正規データのみが必要になりますが、実際には、すべてのページ ビューですべての繰り返しルールに対してすべての日付/時刻処理を行うのは時間がかかりすぎる可能性があります...その繰り返しの計算を節約するために、一部のストレージ(および複雑さ)をオフにします。ストレージは通常、多数のイベントに必要な計算に比べてかなり安価です。あなただけならイベントの日付を保存する必要があります。これは非常に安価です。繰り返しがすべて日付ベースであると仮定すると、日付を表すために 4 バイトの整数を簡単に使用でき、そこから完全な日付/時刻を生成できます。時間ベースの繰り返し (たとえば、「3 時間ごと」) の場合、完全な UTC インスタントを使用できます。8 バイトは、必要になる可能性が高い限り、かなり細かい解像度までそれを表します。

ただし、有効性を維持することに注意する必要があります。定期的な会議が今日変更された場合、それは過去に発生したときに変更されません...したがって、再発が実際にいつ発生したかについての正規の読み取り専用データ必要になるでしょう。明らかに、過去を永遠に保持したくないので、ストレージの制限に応じて、おそらく数年以上前のイベントを「ガベージ コレクション」する必要があります。

また、発生ごとにメモや例外を追加する機能が必要になる場合もあります (たとえば、「今日は祝日のため会議は行われません」または「午後 4 時に移動しました」)。繰り返しを変更すると、とても楽しくなります。「毎週月曜日」を「毎週火曜日」に変更すると、例外が保持されますか? 「毎日」から「毎週」に変更した場合、どのように例外を一致させるのでしょうか? これらはストレージに関する直接的な質問ではありませんが、ストレージの決定は、決定したポリシーをどれだけ簡単に実装できるかに影響します。

于 2012-04-14T07:16:19.217 に答える
14

イベントとオカレンスを別々に処理する必要があります。

イベントワイズ:イベントの場合、繰り返しルール(rfc5545で指定されたようなrruleでも、rfc5545のrdateのような明示的な日付のセットでもかまいません)だけでなく、例外(rfc5545のexdateおよび場合によってはrfc2445のようなexruleを参照)を保存する必要があります。 。また、これらのルールの変更を追跡する必要があります。rdate、exdateの変更は、将来発生しても問題なく、過去の日付では無視されます。rruleの変更は、以前の発生に影響を与えるため、より注意が必要です。私の個人的な好みは、新旧のルールに特定のプロパティを追加して、それぞれの有効の開始日と終了日を指定することです。

イベントの期間が限られている場合(たとえば、COUNTまたはUNTILプロパティが存在する場合)、イベントのクエリを簡単に行えるように、開始と終了をテーブルに保存する必要があります(特に、事前に計算された時間枠外の発生を探す場合(以下を参照)。計算をやり直すイベントの数を減らすのに役立ちます)。

オカレンスワイズ:オカレンスの場合、インスタンスを現在の前後の事前定義されたウィンドウ内に保存し(たとえば、+ /-6か月または12か月で定期的に計算)、ユーザーがさらに確認したい場合に再計算できるように、これを記録する必要があります。将来(パフォーマンスの問題の場合)。次の発生を簡単に見つけられるように、インデックス(RECURRENCE-ID)の計算も検討する必要があります。

バックエンドではなくフロントエンドで、tzidの変更を追跡して、特定のtzidでスケジュールされたイベントが、現在のタイムゾーンにとどまる必要があるかどうかをユーザーに確認する必要があります。更新されました(国がこの日が存在しないと決定する前に2011年12月30日金曜日に会議をスケジュールしたサモア島の誰かを考えてください)、同様に、夏時間中に発生するイベントが「決してない」ことを意味するかどうかを尋ねることができます「起こる」または「2回起こる」(このトピックの詳細はこちら

注:rfc5545で定義されている以上のサポートを繰り返しルールの観点から検討し、宗教的な繰り返しルールのサポートを追加することもできます(USNOのカレンダーの概要、またはE. Reingol and Nの印刷物「CalendricalCalculations」(第3版)を参照)。 。ダーショウィッツ)。

既存の実装について質問するので、sunbird(sqlite)またはAppleオープンソースカレンダーおよび連絡先サーバーのデータベーススキーマを簡単に確認できます。これは、caldavサーバーの既存のオープンソースプロジェクトのより完全なリストです(おそらく、あなたが探している)はここで利用可能です)

于 2012-04-15T16:30:11.417 に答える
10

私はスケジューリングに対応したシステムを構築する必要があり、その両方を行いました。これが私たちが持っていたものです

  • スケジュールを追跡する一連のテーブル。
  • スケジュールの以前のインスタンスを追跡するテーブル (それらが実際に発生したとき)
  • 前回と次のインスタンス (前回に基づいて次のアイテムが発生する予定のとき) を追跡したテーブル現在発生している

スケジューリングでは、いつでもスケジュールが変更される可能性があることを覚えておく必要があるため、物事は非常に複雑になる可能性があります. また、アプリケーションが実行されていないときにアイテムの期限が切れる場合があり、アプリケーションが再び起動したときに、期限を過ぎたアイテムを特定する方法を知っておく必要があります。

また、実際のスケジュールを追跡するテーブルが独立していることを確認しました。その理由は、これらがシステム内で最も複雑なテーブルのセットであり、スケジューリングが必要なさまざまなことに使用できるように、それらを再利用できるようにしたかったからです。管理者メールの送信、通知の送信、ログ ファイルのクリーンアップなどのサーバー メンテナンスなど。

于 2010-11-21T20:00:31.140 に答える
3

私は間違いなくあなたの2番目のオプションを使用します。さまざまな繰り返しオプションを使用し、個別に保存して、その場で計算します。これらすべての日付を保存すると、大量のデータが必要になりません。

これがあなたの質問を褒める良い答えです。
定期的なイベントを保存するためのデータ構造?

また、補足として。複数のタイムゾーンを使用する必要がある場合に共通のベースラインを使用できるように、すべてをUTC時間として保存し始めました。

于 2010-11-21T19:36:21.670 に答える
1

数年前に作成したWebアプリケーションでも同様の問題が発生しました(今はもっと良い方法があるかもしれません:))。定期的なイベントのすべての機能を備え、時間、日、週、月、年、および例外を処理するスケジューラーを含めて、次のようなルールを作成できるようにしたいと思いました。

1)水曜日を除く毎日午前10時

2)2時間ごと、1日あたり最大4回の反復

3)毎月第1月曜日

等..

定期的な日付/時刻を保存することは可能でしたが、柔軟性がありませんでした。イベントの各反復は、「最大」になるときに変更されます。そして、あなたはどれくらい先を見ますか?

最後に、文字列の読み取りと書き込みが可能なカスタムスケジューリングクラスを作成しました。これはデータベースに保存された文字列であり、次に単純な関数を呼び出して、次の出現がいつであるかを調べることができます。

于 2010-11-21T19:38:11.653 に答える
1

それらのいくつかを確実に保存する必要があります。ユーザーは予定の 1 つを編集し、他の予定はそのままにしておくことがあります (Windows Mobile などの一部のカレンダーでは、「定期的な予定をすべて編集しますか、それともこの 1 つだけを編集しますか?」という質問におそらく答えます)。

また、過去のイベントを保存し、ユーザーが定期的なイベントを削除したときに削除しないようにすることもできます。

他のすべてを保存するか生成するかは、実装の詳細です。可能であれば、それらを生成したいと思います。

どのような場合でも、定期的なイベントの ID を各イベントと共に保存し、イベントが後で変更されたかどうかを示すフラグを保持する必要があります。または、より複雑なアプローチでは、各イベント プロパティのフラグが、(定期的なイベントからの) デフォルト値であるか、この特定のインスタンス用に変更されたかを示します。これは、ユーザーが定期的なイベントを編集することを決定したときに必要になります。

于 2012-04-15T12:49:13.017 に答える
1

ほとんどの返信は、生成されたデータの保存に傾いていることに注意してください。ただし、ユースケースを必ず検討してください。

昔、私のサーバーは io によって制限されていて、多くの CPU が何もしていませんでした。最近では、ssd を使用しています (余裕がある場合は、そうでない場合は、古い回転する hd を残しています) が、コア数も増加していることに注意してください。

この種の計算の良いところは、計算を簡単に分割して、多くのコアや、ローカル ネットワーク内のいくつかの安価なサーバーに与えることができることです。多くの場合、nosql クラスターをセットアップしたり、完全なデータベース クラスターを使用したりするよりも安価です。

また、代わりにキャッシュを使用することもできます。カレンダー ビューをキャッシュするだけで、何も変更されていないときに毎回すべての計算を行う必要はありません。

ただし、前述のように、ユースケースによって異なります。上記の答えに従うだけでなく、時間があれば自分で計算して決定してください。

于 2018-07-02T18:56:10.203 に答える