18

これが私がやろうとしていることです: 日付、曜日、および整数nを指定して、日付が月のnth 日であるかどうかを判断します。

例えば:

  • は第 2 月曜日ではないため、 の入力は1/1/2009,Monday,2 false になります1/1/2009

  • 11/13/2008,Thursday,2 第 2 木曜日なので、の入力は true を返します

この実装を改善するにはどうすればよいですか?

private bool NthDayOfMonth(DateTime date, DayOfWeek dow, int n)
{
    int d = date.Day;
    return date.DayOfWeek == dow && (d/ 7 == n || (d/ 7 == (n - 1) && d % 7 > 0));
}
4

8 に答える 8

13

関数が次のようになるように、週のチェックを変更できます。

private bool NthDayOfMonth(DateTime date, DayOfWeek dow, int n){
  int d = date.Day;
  return date.DayOfWeek == dow && (d-1)/7 == (n-1);
}

それ以外は、かなり良くて効率的に見えます。

于 2008-11-13T22:12:03.723 に答える
10

答えはこのウェブサイトからです。そのサイトが失われた場合に備えて、ここにコピーして貼り付けてください。

public static DateTime FindTheNthSpecificWeekday(int year, int month,int nth, System.DayOfWeek day_of_the_week)
{
    // validate month value
    if(month < 1 || month > 12)
    {
        throw new ArgumentOutOfRangeException("Invalid month value.");
    }

    // validate the nth value
    if(nth < 0 || nth > 5)
    {
        throw new ArgumentOutOfRangeException("Invalid nth value.");
    }

    // start from the first day of the month
    DateTime dt = new DateTime(year, month, 1);

    // loop until we find our first match day of the week
    while(dt.DayOfWeek != day_of_the_week)
    {
        dt = dt.AddDays(1);
    }

    if(dt.Month != month)
    {
        // we skip to the next month, we throw an exception
        throw new ArgumentOutOfRangeException(string.Format("The given month has less than {0} {1}s", nth, day_of_the_week));
    }

    // Complete the gap to the nth week
    dt = dt.AddDays((nth - 1) * 7);

    return dt;
}
于 2008-11-13T22:17:39.640 に答える
1

これがMSDNが言わなければならないことです。そのVBですが、簡単に変換できます。

于 2008-11-13T22:15:17.010 に答える
1

任意の月で特定の曜日が n 番目に発生した日付を返す関数を見つけることができます。

http://chiragrdarji.wordpress.com/2010/08/23/find-second-saturday-and-fourth-saturday-of-month/を参照してください。

于 2010-08-23T11:18:08.927 に答える
1

言語が特定の日付の日付/日のメソッドを提供しているようです。興味のある人は、 Zeller の合同について読むことができます。

それは彼らがあなたに望んでいたことではないと思いますが、それから月の最初の日の曜日を見つけることができます. 考えてみると、指定された日の曜日を として見つけ、Nそのモジュロ 7 を取得できます。

ああ、それは N 番目の曜日 (日曜日のような) または月の N 番目の平日のようなものです! さて、私は例を見ます。

月の1日などの日付を作成できれば、違いがあるかもしれません..

それが曜日の N 番目の出現であり、どの日時データ型でもいじることができず、get day of week と get day of month の両方の機能にアクセスできることを考えると。日曜日はゼロですか?

1) まず、曜日は指定された曜日と一致する必要があります。
2) N は 1 以上 4 以下である必要があります。
3) 同じ n に対して、月の日付は n*7*dayOfWeek + 1 から n*7*dayOfWeek + 6 の範囲になります。
- 考えさせてください。日曜日が最初の場合.. 0*7*0+1 = 1 で、6 日目の土曜日は 0*7*0+6 になります。

get day of month 関数は 2 に違反してはならないため、上記の 1 と 3 で十分だと考えてください。

(* first try, this code sucks *)

function isNthGivenDayInMonth(date : dateTime;
                              dow : dayOfWeek;
                              N : integer) : boolean;
    var B, A : integer (* on or before and after day of month *)
    var Day : integer (* day of month *)
    begin
    B := (N-1)*7 + 1; A := (N-1)*7 + 6;
    D := getDayOfMonth(date);
    if (dow <> getDayOfWeek(date) 
        then return(false)
        else return( (B <= Day) and (A >= Day) );
    end; (* function *)

そこにバグがないことを願っています笑!
[編集: 土曜日は 7 日で、上限は(N-1)*7 + 7.]
あなたのソリューションは 2 つの異なる週に一致するように見えますか? 日曜日には常にゼロを返すように見えますか? C# で疑似コードを作成する必要がありました..ショート サーキット && は私の if のようなものです..日曜日に始まる月の N = 1 の最初の試合を日曜日にするべきではありませんか?

 d/ 7 == n

その結果、(either 0 or 1)/7 == 1、それは正しくありません! あなたの||キャッチ(n-1)も、ロバートはそれを持っています。Robert Wagnerの答えに行きましょう!2行だけ、短いのがいい!(Day-1) mod 7
[edit: (Day-1) div 7]を使用 すると、不要な変数と 2 行のセットアップがなくなります。

記録のために、8 月 31 日が日曜日または土曜日である場合のように、境界のケースなどについてこれをチェックする必要があります。
[編集: 週末のケースもチェックすべきでした。ごめん!]

于 2008-11-14T23:44:53.550 に答える
0

月の N 番目の DayOfWeek の期間 (1 つだけでなく) の日付のリストが必要な場合は、次のように使用できます。

internal static List<DateTime> GetDatesForNthDOWOfMonth(int weekNum, DayOfWeek DOW, DateTime beginDate, DateTime endDate)
{
    List<DateTime> datesForNthDOWOfMonth = new List<DateTime>();
    int earliestDayOfMonth = 1;
    int latestDayOfMonth = 7;
    DateTime currentDate = beginDate;

    switch (weekNum)
    {
        case 1:
            earliestDayOfMonth = 1;
            latestDayOfMonth = 7;
            break;
        case 2:
            earliestDayOfMonth = 8;
            latestDayOfMonth = 14;
            break;
        case 3:
            earliestDayOfMonth = 15;
            latestDayOfMonth = 21;
            break;
        case 4:
            earliestDayOfMonth = 22;
            latestDayOfMonth = 28;
            break;
    }

    while (currentDate < endDate)
    {
        DateTime dateToInc = currentDate;
        DateTime endOfMonth = new DateTime(dateToInc.Year, dateToInc.Month, DateTime.DaysInMonth(dateToInc.Year, dateToInc.Month));
        bool dateFound = false;
        while (!dateFound)
        {
            dateFound = dateToInc.DayOfWeek.Equals(DOW);
            if (dateFound)
            {
                if ((dateToInc.Day >= earliestDayOfMonth) && 
                    (dateToInc.Day <= latestDayOfMonth))
                {
                    datesForNthDOWOfMonth.Add(dateToInc);
                }
            }
            if (dateToInc.Date.Equals(endOfMonth.Date)) continue;
            dateToInc = dateToInc.AddDays(1);
        }
        currentDate = new DateTime(currentDate.Year, currentDate.Month, 1);
        currentDate = currentDate.AddMonths(1);
    }
    return datesForNthDOWOfMonth;
}

...そして、次のように呼び出します。

// This is to get the 1st Monday in each month from today through one year from today
DateTime beg = DateTime.Now;
DateTime end = DateTime.Now.AddYears(1);
List<DateTime> dates = GetDatesForNthDOWOfMonth(1, DayOfWeek.Monday, beg, end);
// To see the list of dateTimes, for verification
foreach (DateTime d in dates)
{
    MessageBox.Show(string.Format("Found {0}", d.ToString()));
}

次のように、毎月第 2 金曜日を取得できます。

List<DateTime> dates = GetDatesForNthDOWOfMonth(2, DayOfWeek.Friday, beg, end);

...等。

于 2016-02-23T17:33:27.813 に答える
0

この回答では、次のコードを反転する必要があります。

// Complete the gap to the nth week
dt = dt.AddDays((nth - 1) * 7);

if(dt.Month != month)
{
// we skip to the next month, we throw an exception
throw new ArgumentOutOfRangeException(”The given month has less than ” nth.ToString() ” ”
day_of_the_week.ToString() “s”);
}
于 2009-02-06T15:33:20.223 に答える