2011-01-05 11 views
12

Mam dwie zmienne DateTime i muszę obliczyć liczbę tygodni między nimi.jak obliczyć liczbę tygodni z 2 datami?

Jaki jest najszybszy (i właściwy) sposób na zrobienie tego?

+1

liczbę pełnych tygodni? Jeśli tak, to w którym dniu zaczyna się tydzień? Lub różnica liczby dni/7? – Ani

+2

Jak definiujesz * poprawnie *? Czy możesz podać przykłady oczekiwanego wyniku dla różnych danych wejściowych? –

+0

Prosimy o sprawdzenie, http://stackoverflow.com/questions/13970641/count-the-number-of-inclusive-dates-covered-by-a-date-period – shankbond

Odpowiedz

29

Zastosowanie TimeSpan:

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

Nie widzę, gdzie TimeSpan jest używany w tym przykład, czy czegoś brakuje? –

+1

@Aeron - wynikiem odejmowania dat od siebie jest "TimeSpan". – Oded

+0

Wystąpił błąd 1 dnia według powyższej metody. Wygląda na to, że nie obejmuje obu dat. Rozważ datę 1 jako 1 sierpnia 2016 r. I drugą datę jako 2 sierpnia 2016 r. Po odjęciu otrzymujesz 1 dzień, ale w rzeczywistości są to dwa dni. – shankbond

3

Można spróbować wykonać następujące czynności:

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

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

A jeśli chcesz dokładną różnicę w ułamku również wtedy zamiast:

int totalWeeks = tt.Days/7; 

zastosowanie:

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

da liczbę tygodni

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

dzięki za te walidacje! –

0

Można spróbować czegoś takiego:

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

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

może zaistnieć potrzeba zaokrąglić wynik w górę lub w dół w zależności od dokładnego wymogu, ale że powinien Zrób sztuczkę.

0

Nie zadziała, jeśli spróbujesz podzielić na liczbę całkowitą. Musisz podzielić na podwójny.

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

UPDATE: Spróbuj tej biblioteki: http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET autora upadł dość daleko, aby dowiedzieć się wszystkich tych szczegółów.

Nie widzę odpowiedzi, która naprawdę określa, co to jest tydzień.

Oto pułapka, nie wszystkie tygodnie są sobie równe. Niektóre zliczają się w poniedziałki, a inne w czwartki.

Weź w tym miesiącu na przykład. Jeśli chcę zliczyć liczbę tygodni w sierpniu 2012 roku mogłam zrobić coś takiego:

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

Z jednej .TotalDays daje nam podwójne: tygodnie == 4.2857 ...

Moglibyśmy okrągłe, ale czasami będziesz się liczyć. Innym razem nie spełnisz się.

Zliczanie tygodni zazwyczaj polega na określeniu, kiedy rozpoczyna się i kończy tydzień. W przypadku obiektów DateTime każdy tydzień zaczyna się w poniedziałek.

Szeroko stosowany standard ISO8601 definiuje tydzień rozpoczynający się w czwartek. Tak więc liczba tygodni między dwiema datami zależy od liczby czwartków.

zaimplementować coś takiego za pomocą klasy kalendarz gregoriański:

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); 
     } 

To powinno dać bardziej wiarygodne wyniki.Musisz wziąć pod uwagę, że ten przykład zakłada, że ​​liczymy tygodnie w tym samym roku. Z pewną dodatkową pracę, można pomóc obliczenie poradzić sobie z zakresów dat, które obejmują różne lat:

[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); 
} 

to jeszcze nie jest idealny, ale jest bliżej. Chodzi o to, że nie jest to tak proste, jak to robimy, jeśli chcemy uzyskać prawdziwą liczbę czegoś w rodzaju "tygodnia", który jest naprawdę bardziej specyficzny dla lokalizacji, niż standardowe wyrażenie naukowe, takie jak 1 + 1 = 2. Łączna liczba dni i dzielenie przez 7 jest tak niejednoznaczna, jak stwierdzenie, że wszystkie "dni pracy" to od 9 do 5 ...

Oto lepszy przykład. Nadal może korzystać refaktoryzacji, oczywiście, ale obsługuje zakresy dat, zarówno w tym samym roku i obejmujących wiele lat jako rozszerzenie klasy kalendarz gregoriański:

/// <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; 
} 
Powiązane problemy