267

私はたくさんのグーグルでたくさんの解決策を見つけましたが、それらのどれも私に2012-12-31の正しい週番号を教えてくれません。MSDN(リンク)の例でさえ失敗します。

2012-12-31は月曜日なので、1週目になるはずですが、試したすべての方法で53が得られます。試した方法のいくつかを次に示します。

MDSNライブラリから:

DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;

return cal.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);

解決策2:解決策2:

return new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

解決策3:

CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;

アップデート

次のメソッドは、日付が2012-12-31の場合、実際には1を返します。言い換えれば、私の問題は、私のメソッドがISO-8601標準に準拠していないことでした。

// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
    // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
    // be the same week# as whatever Thursday, Friday or Saturday are,
    // and we always get those right
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    // Return the week of our adjusted day
    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
4

18 に答える 18

365

このMSDN ページに記載されているように、ISO8601 の週と .Net の週の番号付けにはわずかな違いがあります。

より詳しい説明については、MSDN ブログの記事「ISO 8601 Week of Year format in Microsoft .Net」を参照してください。

簡単に言えば、.Net では週を年に分割できますが、ISO 標準ではできません。この記事には、年の最後の週の正しい ISO 8601 週番号を取得するための簡単な関数もあります。

更新次のメソッドは、実際には2012-12-31ISO 8601 (ドイツなど) で正しい 1 を返します。

// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
    // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
    // be the same week# as whatever Thursday, Friday or Saturday are,
    // and we always get those right
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    // Return the week of our adjusted day
    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
} 
于 2012-06-22T11:13:01.643 に答える
35

1 年に 52 週以上ある場合もあります。毎年、52 週間 + 1 日または +2 日 (閏年) の余分な週があります。彼らは53週を埋め合わせます。

  • 52 週間 * 7 日 = 364 日。

したがって、毎年、少なくとも 1 日余分な日があります。うるう年の場合は 2 つ。これらの余分な日は、それぞれ別の週としてカウントされますか?

実際に何週間あるかは、週の開始日によって異なります。2012年について考えてみましょう。

  • 米国 (日曜日 -> 土曜日): 2012 年 12 月 30 日と 2012 年 12 月 31 日の 52 週間 + 短い 2 日間の週。これにより、合計 53 週間になります。今年の最後の 2 日間 (日曜日と月曜日) は、短い 1 週間です。

現在の文化の設定をチェックして、週の最初の曜日として使用されているものを確認してください。

ご覧のとおり、結果として 53 が得られるのは正常です。

  • ヨーロッパ (月曜日 -> 日曜日): 1 月 2 日 (2012 年 1 月 2 日) が最初の月曜日なので、これが最初の週の最初の日です。1 月 1 日の週番号を尋ねると、2011 年の最後の週の一部と見なされるため、52 が返されます。

54週目になることさえあります。1 月 1 日と 12 月 31 日が別の週として扱われる場合、28 年ごとに発生します。うるう年でもあるはずです。

たとえば、2000 年は 54 週でした。1月1日(土)が1週目、12月31日(日)が2週目。

var d = new DateTime(2012, 12, 31);
CultureInfo cul = CultureInfo.CurrentCulture;

var firstDayWeek = cul.Calendar.GetWeekOfYear(
    d,
    CalendarWeekRule.FirstDay,
    DayOfWeek.Monday);

int weekNum = cul.Calendar.GetWeekOfYear(
    d,
    CalendarWeekRule.FirstDay,
    DayOfWeek.Monday);

int year = weekNum == 52 && d.Month == 1 ? d.Year - 1 : d.Year;
Console.WriteLine("Year: {0} Week: {1}", year, weekNum);

プリントアウト: 年: 2012 週: 54

上記の例の CalendarWeekRule を FirstFullWeek または FirstFourDayWeek に変更すると、53 が返されます。ここではドイツを扱っているので、月曜日を開始日とします。

したがって、第 53 週は 2012 年 12 月 31 日の月曜日に始まり、1 日続き、その後停止します。

53が正解です。試してみたい場合は、文化をドイツに変更してください。

CultureInfo cul = CultureInfo.GetCultureInfo("de-DE");
于 2012-06-22T11:00:33.293 に答える
25

これが方法です:

public int GetWeekNumber()
{
    CultureInfo ciCurr = CultureInfo.CurrentCulture;
    int weekNum = ciCurr.Calendar.GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    return weekNum;
}

最も重要なのはCalendarWeekRuleパラメータです。

ここを参照してください: https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=IT-IT&k=k(System.Globalization.CalendarWeekRule);k(TargetFrameworkMoniker-.NETFramework

于 2016-08-19T08:59:53.883 に答える
6

.NET 3.0 以降では、ISOWeek.GetWeekOfDate-Methodを使用できます。

DateTime週が年の境界をまたぐため、年 + 週番号形式の年は、年とは異なる場合があることに注意してください。

于 2020-01-26T16:27:00.507 に答える
4

il_guruからの上記のコードからの C# からPowershellへの移植:

function GetWeekOfYear([datetime] $inputDate)
{
   $day = [System.Globalization.CultureInfo]::InvariantCulture.Calendar.GetDayOfWeek($inputDate)
   if (($day -ge [System.DayOfWeek]::Monday) -and ($day -le [System.DayOfWeek]::Wednesday))
   {
      $inputDate = $inputDate.AddDays(3)
   }

   # Return the week of our adjusted day
   $weekofYear = [System.Globalization.CultureInfo]::InvariantCulture.Calendar.GetWeekOfYear($inputDate, [System.Globalization.CalendarWeekRule]::FirstFourDayWeek, [System.DayOfWeek]::Monday)
   return $weekofYear
}
于 2015-09-30T16:31:10.250 に答える
2
var cultureInfo = CultureInfo.CurrentCulture;
var calendar = cultureInfo.Calendar;

var calendarWeekRule = cultureInfo.DateTimeFormat.CalendarWeekRule;
var firstDayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
var lastDayOfWeek = cultureInfo.LCID == 1033 //En-us
                    ? DayOfWeek.Saturday
                    : DayOfWeek.Sunday;

var lastDayOfYear = new DateTime(date.Year, 12, 31);

var weekNumber = calendar.GetWeekOfYear(date, calendarWeekRule, firstDayOfWeek);

 //Check if this is the last week in the year and it doesn`t occupy the whole week
return weekNumber == 53 && lastDayOfYear.DayOfWeek != lastDayOfWeek 
       ? 1  
       : weekNumber;

これは、米国とロシアの文化の両方でうまく機能します。ISO 8601 も正しいでしょう。なぜなら、ロシアの週は月曜日から始まるからです。

于 2014-06-11T09:00:28.587 に答える
0

問題は、週が 2012 年か 2013 年かをどのように定義するかということです。あなたの推測では、週の 6 日が 2013 年なので、今週は 2013 年の最初の週としてマークされるはずです。

これが正しい方法かどうかはわかりません。その週は 2012 年 (12 月 31 日月曜日) に始まったので、2012 年の最後の週としてマークする必要があります。

これで、曜日情報を使用してエッジ週 (年の最初と最後の週) の特定のケースを処理できるようになりました。それはすべてあなたの論理に依存します。

于 2012-06-22T10:58:45.340 に答える
0

週が月曜日に始まると仮定すると、これらの 2 つの方法が役に立ちます。

/// <summary>
    /// Returns the weekId
    /// </summary>
    /// <param name="DateTimeReference"></param>
    /// <returns>Returns the current week id</returns>
    public static DateTime GetDateFromWeek(int WeekReference)
    {
        //365 leap
        int DaysOffset = 0;
        if (WeekReference > 1)
        {
            DaysOffset = 7;
            WeekReference = WeekReference - 1;
        }
        DateTime DT = new DateTime(DateTime.Now.Year, 1, 1);
        int CurrentYear = DT.Year;
        DateTime SelectedDateTime = DateTime.MinValue;

        while (CurrentYear == DT.Year)
        {
            int TheWeek = WeekReportData.GetWeekId(DT);
            if (TheWeek == WeekReference)
            {
                SelectedDateTime = DT;
                break;
            }
            DT = DT.AddDays(1.0D);
        }

        if (SelectedDateTime == DateTime.MinValue)
        {
            throw new Exception("Please check week");
        }

        return SelectedDateTime.AddDays(DaysOffset);
    }
/// <summary>
    /// Returns the weekId
    /// </summary>
    /// <param name="DateTimeReference"></param>
    /// <returns>Returns the current week id</returns>
    public static int GetWeekId(DateTime DateTimeReference)
    {
        CultureInfo ciCurr = CultureInfo.InvariantCulture;
        int weekNum = ciCurr.Calendar.GetWeekOfYear(DateTimeReference,
        CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
        return weekNum;
    }
于 2020-05-21T10:37:35.020 に答える
-1

1年は52週間で、ラップ年の場合は1日または2日です(52 x 7 = 364)。2012-12-31は53週目で、2012年はラップ年であるため2日しかありません。

于 2012-06-22T10:54:25.310 に答える