2009-05-29 11 views
1

Quelqu'un peut-il me dire comment calculer la différence entre deux dates sans utiliser les classes .net datetime et timestamp?date diff dans asp.net

Merci

+2

Dans quel format les dates sont-elles stockées? Chaîne? Entier? Autre? –

+7

Il serait vraiment utile si vous expliquer pourquoi vous voulez éviter d'utiliser les types qui ont été fournis pour la manipulation de la date et de l'heure. –

+0

Dans quel format sont vos dates? Cordes? Entiers? Pourquoi sans une date-heure? – Alan

Répondre

3

Si je ne pouvais pas utiliser le dans les types, j'essaierais de trouver une autre API de date/heure .NET. Je suppose que je n'en trouverais pas un, étant donné que toute personne sensée utiliserait ceux intégrés.

Si c'est vraiment juste un cas de dates, je suppose qu'une API date/heure complète n'est pas vraiment nécessaire. Analysez tout ce que vous obtenez dans les «jours depuis une certaine époque» (par exemple, le 1er janvier 1970) et effectuez simplement la soustraction normale. Cependant, faites attention aux années bissextiles - et les choses deviennent encore plus amusantes si vous avez besoin de faire face au calendrier bizarre change quelques siècles en arrière.

Exemple de code en supposant un format « aaaammjj », ne fait aucune vérification d'erreur, ne pas faire face aux dates avant 1900, et ne pas se soucier de l'efficacité du tout:

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

Bien sûr, juste analyser la date et l'heure, faire le calcul, prendre en compte les années bissextiles, etc ... Hey, quelqu'un devrait vraiment construire un API pour cela. Peut-être que cela devrait même être inclus dans .NET! –

+0

Eh bien oui en effet ...Cela fait un peu plus de sens en tant que problème de type «puzzle» dans une interview, en termes de «ce développeur peut-il réfléchir à travers les casse-tête et écrire un code utilisable». –

+0

Cette ligne ici "if ((year% 400) == 0) return true;" était en train de mettre de l'ordre sur moi ... J'ai écrit un harnais de test rapide très similaire au vôtre mais sortait 2 jours en décalage avec ce que la version de DateTime-DateTime me donnait –

2

Si vous ne pouvez pas utiliser un DateTime, qu'est-ce que vous avez? Cordes? Dans ce cas, utilisez l'une des variantes DateTime.Parse() * ou Convert.ToDateTime() et effectuez la comparaison ici. C'est le seul moyen correct. Rien d'autre et nous aurons besoin d'un peu plus d'informations.

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

1

Basé sur le commentaire, je choisis que la date-heure est stockée sous forme de nombre de cycles d'horloge depuis le 1er janvier 1901. Maintenant, il est une question de simple soustraction de l'un de l'autre, en divisant par horloge cycles par seconde, et en divisant par le coefficient approprié à l'unité de temps que vous voulez mesurer (60 pour minutes, 3600 pour heures, 3600 * 24 pour jours, etc.)

+0

- Vous devriez tenir compte des fuseaux horaires et de toutes sortes de bizarreries. Étant donné que nous avons seulement * dates *, pourquoi ne pas le stocker comme le nombre de * jours * depuis une date particulière? –

+0

Je ne vois pas pourquoi je devrais tenir compte des fuseaux horaires. L'avantage des systèmes de date-heure basés sur le compte est qu'ils sont complètement indépendants de l'horloge et du calendrier et qu'ils connaissent la différence entre, par exemple, le premier 2 heures du matin et le deuxième 2 heures du matin. (Cycle d'horloge est un exemple extrême, mais utilisé dans les systèmes d'exploitation réels.) –

1

Je parie que la personne que vous interviewer était un dev VB, et attend de vous que vous utilisiez la fonction VB datediff intégrée (Microsoft.VisualBasic.DateAndTime.DateDiff). Je ne suis pas 100% mais je crois que cette fonction a une surcharge pour les arguments de date de chaîne ou d'objet.