2009-05-29 17 views
1

誰でも私のdatetimeとtimestampクラスを使用せずに2つの日付の差分を計算する方法を教えてもらえますか?asp.netの日付差分

ありがとうございました

+2

日付はどのような形式で保存されますか?文字列?整数?その他? –

+7

日時の操作のために提供されている型の使用を避けたい理由を説明すると、本当に役に立ちます。 –

+0

あなたの日付はどのような形式ですか?文字列?整数?なぜ日時なし? – Alan

答えて

3

私は組み込み関数を使用できない場合は、型では、別の.NETの日付/時刻APIを見つけようとします。私は、正気の人が組み込みのものを使うとすれば、私は見つけられないだろうと思う。

の場合は実際にはの日付の場合、完全な日付/時刻APIは実際には必要ないと思います。 「何時から何日になったのか」(たとえば1970年1月1日)を解析し、通常の減算を行います。

閏年には注意してください。数世紀前の気まぐれなカレンダーの変更に対処する必要がある場合は、さらに楽しくなります。

サンプル・コード1900より前の日付に対処ではない、と全く効率の心配はない、任意のエラーチェックを行っていない、「YYYYMMDD」の形式を想定して:

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)trueを返します;"私のひどい悩みをぶち壊していました...私はあなたと非常によく似た簡単なテストハーネスを書いていましたが、 DateTime-DateTimeのバージョンが私に与えてくれたもの –

2

あなたはDateTimeを使用できない場合はどうしますか?文字列?その場合は、DateTime.Parse()のバリアント*またはConvert.ToDateTime()のいずれかを使用して比較します。それが唯一正しい方法です。それ以外のものはもう少し情報が必要です。コメントに基づいて

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

1

、私は1月1日、1901は、今、それはクロックで割る、単に一方を他方から差し引くの問題ですので、日付・時刻はクロック・サイクル数として格納されることを選択します(秒で60、時間で3600、日で3600 * 24など)

+0

クロックサイクルは、 - タイムゾーンとあらゆる種類の奇妙なものを考慮する必要があります。 * dates *しか見つからなかったので、特定の日付以降に* days *の数として保存してみませんか? –

+0

なぜ私はタイムゾーンを考慮する必要があるのか​​分かりません。カウントベースの日時システムの利点は、完全に時計とカレンダーに依存せず、たとえば時計のバック日に最初の2 AMと2番目の2 AMの違いを知ることです。 (クロックサイクルは極端な例ですが、現実のOSで使われています) –

1

私はあなたを面接者を賭けますVBの開発者であり、VBの組み込み関数(Microsoft.VisualBasic.DateAndTime.DateDiff)を使用して回答することを期待していました。私は100%ではありませんが、関数に文字列またはオブジェクトの日付引数のオーバーロードがあると思います。