2009-05-29 3 views
1

Может ли кто-нибудь сказать мне, как рассчитать разницу между двумя датами, не используя классы .net datetime и timestamp?date diff in asp.net

Благодаря

+2

В каком формате хранятся даты? Строка? Integer? Другие? –

+7

Это действительно поможет, если вы объясните, почему на земле вы хотите избежать использования типов, которые были предоставлены для обработки даты и времени. –

+0

В каком формате указаны ваши даты? Строки? Целые? Почему без даты? – Alan

ответ

3

Если я не мог использовать встроенный модуль, в типах, я бы попытался найти другой .NET-интерфейс даты и времени. Я подозреваю, что не найду никого, учитывая, что любой здравомыслящий человек будет использовать встроенные.

Если это действительно просто случай дат, я думаю, что полный API даты/времени на самом деле не требуется. Разбирайте все, что вы попадаете в «дни с какой-то эпохи» (например, 1 января 1970 года) и просто выполняете нормальное вычитание.

Будьте осторожны с високосными годами - и все становится еще веселее, если вам нужно справиться с причудливыми изменениями календаря на несколько столетий назад.

Пример кода при условии, формат «YYyyMmDd», а не делать какие-либо проверки ошибок, не справляясь с датами до 1900 года, и не заботясь об эффективности на всех:

using System; 

struct Date 
{ 
    readonly int year; 
    readonly int month; 
    readonly int day; 

    public Date(int year, int month, int day) 
    { 
     this.year = year; 
     this.month = month; 
     this.day = day; 
    } 

    public static Date Parse(string text) 
    { 
     return new Date(int.Parse(text.Substring(0, 4)), 
         int.Parse(text.Substring(4, 2)), 
         int.Parse(text.Substring(6, 2))); 
    } 

    // Days since first Jan 1st 1900 
    public int DaysSinceEpoch 
    { 
     get 
     { 
      int days = 0; 
      for (int i = 1900; i < year; i++) 
      { 
       days += IsLeapYear(i) ? 366 : 365; 
      } 
      for (int i = 1; i < month; i++) 
      { 
       days += GetMonthLength(i, year); 
      } 
      days += day - 1; 
      return days; 
     } 
    } 

    private static readonly int[] MonthLengths = 
    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 

    private static int GetMonthLength(int month, int year) 
    { 
     return MonthLengths[month-1] + 
      ((IsLeapYear(year) && month == 2) ? 1 : 0); 
    } 

    private static bool IsLeapYear(int year) 
    { 
     // http://en.wikipedia.org/wiki/Leap_year 
     if ((year % 4) != 0) return false; 
     if ((year % 400) == 0) return true; 
     if ((year % 100) == 0) return false; 
     return true; 
    } 
} 

class Test 
{ 
    static void Main(string[] args) 
    { 
     Console.WriteLine(DateDiff("19040301", "19050301")); // 365 
     Console.WriteLine(DateDiff("19040201", "19050201")); // 366 
     Console.WriteLine(DateDiff("19760619", "20090529")); // I feel old 
    } 

    static int DateDiff(string first, string second) 
    { 
     Date firstDate = Date.Parse(first); 
     Date secondDate = Date.Parse(second); 
     return secondDate.DaysSinceEpoch - firstDate.DaysSinceEpoch; 
    } 
} 
+1

Конечно, просто проанализируйте дату и время, выполните математику, учтите високосные годы и т. Д. Эй, кто-то должен действительно построить API для этого. Может быть, он даже должен быть включен в .NET! –

+0

Ну да действительно ...это немного более разумно, поскольку проблема типа «головоломка» в интервью, хотя, с точки зрения «может ли этот разработчик продумать угловые случаи и написать полезный код». –

+0

Эта строка здесь "if ((year% 400) == 0) return true;" прослушивал дерьмо из меня ... Я написал быстрый тестовый жгут, очень похожий на ваш, но вышел из-за синхронности с 2 днями что давала мне версия DateTime-DateTime –

2

Если вы не можете использовать DateTime, что у вас есть? Строки? В этом случае используйте один из вариантов DateTime.Parse() * или Convert.ToDateTime() и выполните сравнение там. Это единственный правильный путь. Что-нибудь еще, и нам понадобится немного больше информации.

* DateTime.Parse(), DateTime.TryParse(), DateTime.ParseExact(), or DateTime.TryParseExact().

1

Основываясь на комментарий, я выбираю, что дата-время хранится в виде числа тактов начиная с 1 января 1901. Теперь это вопрос не просто вычитая одно из другого, деля на часы (60 минут, 3600 часов, 3600 * 24 в течение нескольких дней и т. д.)

+0

Циклы часов чувствуют себя излишними для меня - вам нужно будет учитывать часовые пояса и всевозможные странности. Учитывая, что у нас есть только * даты *, почему бы не сохранить его как число * дней * с определенной даты? –

+0

Я не понимаю, почему я должен учитывать часовые пояса. Преимущество систем с датой окончания счета заключается в том, что они полностью независимы от часов и календаря и знают разницу между, например, первыми 2 AM и вторым 2 AM в день возврата. (Часовые циклы - крайний пример, но один используется в реальных операционных системах.) –

1

Держу пари человека вас интервью был разработчиком VB и ожидал, что вы ответите с помощью встроенной функции VB датированной функции (Microsoft.VisualBasic.DateAndTime.DateDiff). Я не 100%, но я считаю, что функция имеет перегрузку для аргументов строки или объекта date.