Подтвердить что ты не робот

Как рассчитать количество недель, учитывая 2 даты?

У меня есть две переменные DateTime, и мне нужно вычислить количество недель между ними.

Каков самый быстрый (и правильный) способ сделать это?

4b9b3361

Ответ 1

Используйте TimeSpan:

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

Ответ 2

Вы можете попробовать следующее:

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;

Ответ 3

UPDATE: попробуйте эту библиотеку: http://www.codeproject.com/Articles/168662/Time-Period-Library-for-NET Автор довольно подробно рассмотрел все эти детали.

Я не вижу ответа, который действительно определяет, что такое неделя.

Здесь ловушка, не все недели, создаются равными. Некоторые считают понедельники, в то время как другие считают четверг.

Возьмите, к примеру, в этом месяце. Если я хочу подсчитать количество недель в августе 2012 года, я мог бы сделать что-то вроде:

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

Ответ 4

(dtTo - dtFrom).TotalDays / 7

даст количество недель

Ответ 5

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

Ответ 6

Вы можете попробовать что-то вроде:

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

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

Вам может потребоваться округлить результат вверх или вниз в зависимости от вашего точного требования, но это должно сделать трюк.

Ответ 7

Это не сработает, если вы попытаетесь делить на целое число. Вы должны разделить на два.

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