2011-01-05 43 views
12

我有兩個DateTime變量,我需要計算它們之間的星期數。如何計算2個日期給定的週數?

什麼是最快(和正確)的方式來做到這一點?

+1

整週的數量?如果是這樣,那麼一週的哪一天開始?或天數差異/ 7? – Ani 2011-01-05 12:58:38

+2

你如何定義*正確*?你能舉出一些關於不同投入的預期結果的例子嗎? – 2011-01-05 13:01:10

+0

請檢查,http://stackoverflow.com/questions/13970641/count-the-number-of-inclusive-dates-covered-by-a-date-period – shankbond 2016-08-30 08:34:20

回答

29

使用TimeSpan

int weeks = (date1 - date2).TotalDays/7; 
+0

我沒有看到TimeSpan在這裏被使用在哪裏例如,我錯過了什麼? – 2014-07-31 06:13:20

+1

@Aeron - 相互減去日期的結果是'TimeSpan'。 – Oded 2014-07-31 09:01:27

+0

以上方法有1天的錯誤。它似乎不包括兩個日期。考慮Date1爲2016年8月1日,第二次日期爲2016年8月2日。扣除後1天,但實際上有兩天。 – shankbond 2016-08-30 09:20:17

3

你可以嘗試以下方法:

DateTime d1 = new DateTime(2006,10,1); 
DateTime d2 = new DateTime(2007,10,15); 

TimeSpan tt = d2 - d1; 
int totalWeeks = tt.Days/7; 

如果你想確切的差異分數也再不是:

int totalWeeks = tt.Days/7; 

使用:

double totalWeeks = tt.TotalDays/7; 
1
(dtTo - dtFrom).TotalDays/7 

會給周

1
public static int NumberOfWeeks(DateTime dateFrom, DateTime dateTo) 
{ 
    TimeSpan Span = dateTo.Subtract(dateFrom); 

    if (Span.Days <= 7) 
    { 
     if (dateFrom.DayOfWeek > dateTo.DayOfWeek) 
     { 
     return 2; 
     } 

     return 1; 
    } 

    int Days = Span.Days - 7 + (int)dateFrom.DayOfWeek; 
    int WeekCount = 1; 
    int DayCount = 0; 

    for (WeekCount = 1; DayCount < Days; WeekCount++) 
    { 
     DayCount += 7; 
    } 

    return WeekCount; 
} 
+1

感謝您的驗證! – 2016-05-13 19:43:36

0

你可以嘗試像數:

var d1 = new DateTime(2011, 01, 05); 
var d2 = new DateTime(2010, 01, 05); 

Console.WriteLine((d1 - d2).Days/7); 

您可能需要四捨五入的結果向上或向下取決你的具體要求,但應做的伎倆。

0

如果嘗試分解爲整數,它將不起作用。你必須分成兩倍。

DateTime startDateTime = new DateTime(2010, 8, 1); 
DateTime endDateTime = new DateTime(2010, 8, 28); 
double weeks = (endDateTime - startDateTime).TotalDays/7; 
3

UPDATE:試試這個庫:http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET 筆者已經相當的方式來找出所有的這些細節。

我沒有看到真正定義本週的答案。

這是陷阱,不是所有的周都是平等的。有些人計算星期一,而其他人計算星期四。

以本月爲例。如果我要算在2012年8月的週數,我可以這樣做:

var date1 = new DateTime(2012,8,1); 
var date2 = new DateTime(2012,8,31); 
var weeks = (date1 - date2).TotalDays/7; 

一方面,.TotalDays給我們提供了雙: 周== 4.2857 ...

我們能一輪,但有時你會過度計數。其他時間你會失敗。

計數週通常依賴於定義一週的開始和結束時間。使用DateTime對象,我們會在每週的星期一開始查找。

廣泛使用的ISO8601標準定義了週四開始的一週。所以兩個日期之間的星期數取決於星期四發生的次數。

使用的GregorianCalendar類來實現這樣的事情:

using System; 
using System.Globalization; 
using FluentAssertions; 
using NUnit.Framework; 

//...Namespace, test fixture class, etc ... 

     [Test] 
     public void GetMetricsTimesBetween_ReturnsCorrectRange() { 
      DateTime startDate = new DateTime(2012, 8, 1); 
      DateTime endDate = new DateTime(2012, 8, 31); 

      var cal = new GregorianCalendar(); 

      int startWeekNumber = cal.GetWeekOfYear(startDate, 
                CalendarWeekRule.FirstDay,          
                DayOfWeek.Thursday); 
      int endWeekNumber = cal.GetWeekOfYear(endDate, 
               CalendarWeekRule.FirstDay, 
               DayOfWeek.Thursday); 
      int numberOfWeeksInRange = endWeekNumber - startWeekNumber; 

      numberOfWeeksInRange.Should().Be(5); 
     } 

這應該給你更可靠的結果。你必須考慮這個例子假設我們在同一年內計算幾周。通過一些額外的工作,您可以幫助計算應對跨越不同年份的日期範圍:

[Test] 
public void GetCountOfWeeks() { 
    var startDate = new DateTime(2012, 12, 1); // 4 weeks here 
    var endDate = new DateTime(2014, 1, 10); // 52 in 2013 and 2 weeks in 2014 
    int numberOfWeeksInRange = 0; 

    var cal = new GregorianCalendar(); 

    for (int year = startDate.Year; year <= endDate.Year; year++) 
    { 
     int startWeekNumber = 0; 
     int endWeekNumber= 0; 

     if(year == startDate.Year) { // start date through the end of the year 
      startWeekNumber = cal.GetWeekOfYear(startDate, 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday); 

      endWeekNumber = cal.GetWeekOfYear((
            new DateTime(year + 1, 1, 1).AddDays(-1)), 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday);      
     } else if(year == endDate.Year) { // start of the given year through the end date 
      startWeekNumber = cal.GetWeekOfYear((new DateTime(year, 1, 1)), 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday);      

      endWeekNumber = cal.GetWeekOfYear(endDate, 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday);     
     } else { // calculate the number of weeks in a full year     
      startWeekNumber = cal.GetWeekOfYear(new DateTime(year, 1, 1), 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday); 

      endWeekNumber = cal.GetWeekOfYear((
            new DateTime(year + 1, 1, 1).AddDays(-1)), 
       CalendarWeekRule.FirstDay, DayOfWeek.Thursday);      
     } 

     numberOfWeeksInRange += endWeekNumber - startWeekNumber; 
    } 

    numberOfWeeksInRange.Should().Be(58); 
} 

這仍然不是完美的,但它更接近。這裏的要點是,如果你想得到像「一週」這樣的真實計數的真實數據,並非像我們傾向於做的那樣簡單,實際上這更像是一個特定地區的決定,而不是一些標準的科學表達式,比如1 + 1 = 2.以總天數除以7表示所有「工作日」爲9至5的含糊不清...

下面是一個更好的示例。當然,仍然可以使用重構,但在同一年處理日期範圍,並跨越多年作爲GregorianCalendar類的擴展:

/// <summary> 
/// Returns the number of weeks between two datetimes 
/// </summary> 
/// <param name="cal"></param> 
/// <param name="startDate"></param> 
/// <param name="endDate"></param> 
/// <returns></returns> 
public static int GetWeeks(this GregorianCalendar cal, 
           CalendarWeekRule weekRule, 
           DayOfWeek dayofWeek, 
           DateTime startDate, 
           DateTime endDate) { 
    int startWeekNumber = 0; 
    int endWeekNumber = 0; 
    int numberOfWeeksInRange = 0; 

    if (startDate.Year == endDate.Year) { 
     startWeekNumber = 0; 
     endWeekNumber = 0; 
     startWeekNumber = cal.GetWeekOfYear(startDate, 
              weekRule, 
              dayofWeek); 

     endWeekNumber = cal.GetWeekOfYear(endDate, 
              weekRule, 
              dayofWeek); 

     numberOfWeeksInRange = endWeekNumber - startWeekNumber; 

    } 
    else { // calculate per year, inclusive 
     for (int year = startDate.Year; year <= endDate.Year; year++) { 
      startWeekNumber = 0; 
      endWeekNumber = 0; 

      if (year == startDate.Year) { // start date through the end of the year 
       startWeekNumber = cal.GetWeekOfYear(startDate, weekRule, dayofWeek); 

       endWeekNumber = cal.GetWeekOfYear((new DateTime(year + 1, 1, 1).AddDays(-1)), 
        weekRule, dayofWeek); 
      } 
      else if (year == endDate.Year) { // start of the given year through the end date 
       startWeekNumber = cal.GetWeekOfYear((new DateTime(year, 1, 1)), 
        weekRule, dayofWeek); 

       endWeekNumber = cal.GetWeekOfYear(endDate, 
        weekRule, dayofWeek); 
      } 
      else { // calculate the total number of weeks in this year     
       startWeekNumber = cal.GetWeekOfYear(new DateTime(year, 1, 1), 
        weekRule, dayofWeek); 

       endWeekNumber = cal.GetWeekOfYear((new DateTime(year + 1, 1, 1).AddDays(-1)), 
        weekRule, dayofWeek; 
      } 
      numberOfWeeksInRange += endWeekNumber - startWeekNumber; 
     } 
    } 

    return numberOfWeeksInRange; 
}