2015-03-10T23:49:44の更新内容

programming/netfx/tips/calc_elapsed_years/index.wiki.txt

current previous
1,107 1,38
~
${smdncms:title,経過年数・経過月数を計算する}
${smdncms:title,今日までの経過年数を計算する}
~
${smdncms:keywords,C#,VB.NET,DateTime,DateTimeOffset,TimeSpan,経過年数,満年数}
${smdncms:keywords,C#,VB.NET,DateTime,TimeSpan}
 
${smdncms:tags,algo,lang/vb,api/.net}
${smdncms:tags,algo,lang/vb,api/.net}
 
${smdncms:document_versions,codelang=cs,codelang=vb}
${smdncms:document_versions,codelang=cs,codelang=vb}
+

          
+
2つのDateTimeから経過年数(満年数)などを求める方法について。
+

          
 
#adunit
#adunit
 

        

        
 
-関連するページ
-関連するページ
 
--[[programming/netfx/datetime]]
--[[programming/netfx/datetime]]
~
---[[programming/netfx/datetime/0_abstract#DateTime_Subtract]]
---[[programming/netfx/datetime/0_abstract]]
 
--[[programming/netfx/tips/get_last_day_of_month]]
--[[programming/netfx/tips/get_last_day_of_month]]
 
--[[programming/netfx/tips/convert_unixtime_into_datetime]]
--[[programming/netfx/tips/convert_unixtime_into_datetime]]
 

        

        
~
*経過日数・経過時間
DateTime同士の減算では戻り値がTimeSpan構造体となるが、TimeSpanには&msdn(netfx,member,System.TimeSpan.TotalDays){TotalDaysプロパティ};のような年数を計算するプロパティが用意されていない。 経過した日数(TimeSpan.TotalDays)から求めるとしても、閏年などの処理が面倒になる。 そこで、まず二つのDateTimeから年のみの差を求め、次にその日より前であればを-1することで経過年数を求める。
+
&msdn(netfx,type,System.DateTime){DateTime};(または&msdn(netfx,type,System.DateTimeOffset){DateTimeOffset};)同士を減算すると、結果として&msdn(netfx,type,System.TimeSpan){TimeSpan構造体};が返される。 TimeSpanには&msdn(netfx,member,System.TimeSpan.TotalDays){TotalDaysプロパティ};といったプロパティが用意されているので、これを参照することで経過日数・経過秒数などを求めることができる。
 

        

        
 
#tabpage(codelang=cs)
#tabpage(codelang=cs)
 
#code{{
#code{{
 
using System;
using System;
 

        

        
 
class Sample {
class Sample {
~
  public static void Main()
  public static void Main() {
~
  {
    Console.Write("日付は? ");
+
    var baseDay = new DateTime(2011, 6, 18);
+
    var day = new DateTime(2011, 6, 20);
+

          
+
    TimeSpan elapsedSpan = day - baseDay;
+

          
+
    Console.WriteLine("経過日数: {0}日", elapsedSpan.TotalDays);
+
    Console.WriteLine("経過時間: {0}時間", elapsedSpan.TotalHours);
+
    Console.WriteLine("経過秒数: {0}秒", elapsedSpan.TotalSeconds);
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
 

        

        
~
Module Sample
    var baseDay = DateTime.Parse(Console.ReadLine());
~
  Sub Main()
    var today = DateTime.Today;
+
    Dim baseDay As New DateTime(2011, 6, 18)
+
    Dim day As New DateTime(2011, 6, 20)
+

          
+
    Dim elapsedSpan As TimeSpan = day - baseDay
+

          
+
    Console.WriteLine("経過日数: {0}日", elapsedSpan.TotalDays)
+
    Console.WriteLine("経過時間: {0}時間", elapsedSpan.TotalHours)
+
    Console.WriteLine("経過秒数: {0}秒", elapsedSpan.TotalSeconds)
+
  End Sub
+
End Module
+
}}
+
#tabpage-end
 

        

        
~
#prompt(実行結果){{
    var yearsElapsed = today.Year - baseDay.Year;
+
経過日数: 2日
+
経過時間: 48時間
+
経過秒数: 172800秒
+
}}
+

          
+

          
+
*経過年数
+
一方、TimeSpanには経過年数を求めるプロパティは用意されていない。 経過日数(TimeSpan.TotalDays)から求めるにしても月毎の日数の違いや閏年などを考慮する必要がある。
+

          
+
経過年数(満年数)を求めるには、まず二つのDateTimeから年数のみの単純な差を求め、次に日付を比較し同月同日に達していなければ-1することで求めることができる。
+

          
+
#tabpage(codelang=cs,container-title=経過年数・満年数の取得)
+
#code{{
+
using System;
 

        

        
~
class Sample {
    var sameDayInThisYear = new DateTime(today.Year, baseDay.Month, baseDay.Day);
+
  // 基準日baseDayからdayまでの経過年数を求める
+
  public static int GetElapsedYears(DateTime baseDay, DateTime day)
+
  {
+
    if (day < baseDay)
+
      // 日付が基準日より前の場合は例外とする
+
      throw new ArgumentException();
+

          
+
    // 経過年数を求める(満年数を考慮しない単純計算)
+
    var elapsedYears = day.Year - baseDay.Year;
+

          
+
    // 指定された年における同月同日に達しているか調べる
+
    if (day < new DateTime(day.Year, baseDay.Month, baseDay.Day))
+
      // 同月同日に達していなければ、経過年数を-1する
+
      elapsedYears -= 1;
 

        

        
~
    return elapsedYears;
    if (sameDayInThisYear > today)
~
  }
      yearsElapsed -= 1;
 

        

        
~
  public static void Main()
    Console.WriteLine("基準となる日付: {0:D}", baseDay);
~
  {
    Console.WriteLine("今日: {0:D}", today);
~
    var baseDay = new DateTime(2011, 6, 18);
    Console.WriteLine("経過年数: {0}", yearsElapsed);
+

          
+
    Console.WriteLine("基準日: {0:D}", baseDay);
+

          
+
    foreach (var day in new[] {
+
      new DateTime(2012, 6, 17),
+
      new DateTime(2012, 6, 18),
+
      new DateTime(2015, 6, 17),
+
      new DateTime(2015, 6, 18),
+
    }) {
+
      Console.WriteLine("日付: {0:D}, 経過年数: {1}", day, GetElapsedYears(baseDay, day));
+
    }
 
  }
  }
 
}
}
 
}}
}}
109,145 40,36
 
#code{{
#code{{
 
Imports System
Imports System
 

        

        
~
Module Sample
Class Sample
~
  ' 基準日baseDayからdayまでの経過年数を求める
  Public Shared Sub Main()
~
  Public Function GetElapsedYears(ByVal baseDay As DateTime, ByVal day As  DateTime) As Integer
    Console.Write("日付は? ")
+
    ' 日付が基準日より前の場合は例外とする
+
    If day < baseDay Then Throw New ArgumentException()
+

          
+
    ' 経過年数を求める(満年数を考慮しない単純計算)
+
    Dim elapsedYears As Integer = day.Year - baseDay.Year
+

          
+
    ' 指定された年における同月同日に達しているか調べる
+
    If day < New DateTime(day.Year, baseDay.Month, baseDay.Day) Then
+
      ' 同月同日に達していなければ、経過年数を-1する
+
      elapsedYears -= 1
+
    End If
+

          
+
    Return elapsedYears
+
  End Function
+

          
+
  Sub Main()
+
    Dim baseDay As New DateTime(2011, 6, 18)
+

          
+
    Console.WriteLine("基準日: {0:D}", baseDay)
+

          
+
    For Each day As DateTime In New DateTime() { _
+
      New DateTime(2012, 6, 17), _
+
      New DateTime(2012, 6, 18), _
+
      New DateTime(2015, 6, 17), _
+
      New DateTime(2015, 6, 18) _
+
    }
+
      Console.WriteLine("日付: {0:D}, 経過年数: {1}", day, GetElapsedYears(baseDay, day))
+
    Next
+
  End Sub
+
End Module
+
}}
+
#tabpage-end
+

          
+
#prompt(出力例){{
+
基準日: 2011年6月18日
+
日付: 2012年6月17日, 経過年数: 0
+
日付: 2012年6月18日, 経過年数: 1
+
日付: 2015年6月17日, 経過年数: 3
+
日付: 2015年6月18日, 経過年数: 4
+
}}
 

        

        
~
*経過月数
    Dim baseDay As DateTime = DateTime.Parse(Console.ReadLine())
~
経過年数の場合と同様に、まず二つのDateTimeから月数のみの単純な差を求め、次に日付を比較し同日に達していなければ-1することで求めることができる。
    Dim today As DateTime = DateTime.Today
 

        

        
~
#tabpage(codelang=cs,container-title=経過月数・満月数の取得)
    Dim yearsElapsed As Integer = today.Year - baseDay.Year
+
#code{{
+
using System;
 

        

        
~
class Sample {
    Dim sameDayInThisYear As New DateTime(today.Year, baseDay.Month, baseDay.Day)
+
  // 基準日baseDayからdayまでの経過月数を求める
+
  public static int GetElapsedMonths(DateTime baseDay, DateTime day)
+
  {
+
    if (day < baseDay)
+
      // 日付が基準日より前の場合は例外とする
+
      throw new ArgumentException();
+

          
+
    // 経過月数を求める(満月数を考慮しない単純計算)
+
    var elapsedMonths = (day.Year - baseDay.Year) * 12 + (day.Month - baseDay.Month);
+

          
+
    // 指定された年・月における同日に達しているか調べる
+
    if (day < new DateTime(day.Year, day.Month, baseDay.Day))
+
      // 同日に達していなければ、経過月数を-1する
+
      elapsedMonths -= 1;
+

          
+
    return elapsedMonths;
+
  }
 

        

        
~
  public static void Main()
    If sameDayInThisYear > today Then yearsElapsed -= 1
+
  {
+
    var baseDay = new DateTime(2011, 6, 18);
+

          
+
    Console.WriteLine("基準日: {0:D}", baseDay);
+

          
+
    foreach (var day in new[] {
+
      new DateTime(2011, 7, 17),
+
      new DateTime(2011, 7, 18),
+
      new DateTime(2012, 6, 18),
+
      new DateTime(2015, 6, 17),
+
      new DateTime(2015, 6, 18),
+
    }) {
+
      Console.WriteLine("日付: {0:D}, 経過月数: {1}", day, GetElapsedMonths(baseDay, day));
+
    }
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
 

        

        
~
Module Sample
    Console.WriteLine("基準となる日付: {0:D}", baseDay)
~
  ' 基準日baseDayからdayまでの経過月数を求める
    Console.WriteLine("今日: {0:D}", today)
~
  Public Function GetElapsedMonths(ByVal baseDay As DateTime, ByVal day As  DateTime) As Integer
    Console.WriteLine("経過年数: {0}", yearsElapsed)
+
    ' 日付が基準日より前の場合は例外とする
+
    If day < baseDay Then Throw New ArgumentException()
+

          
+
    ' 経過月数を求める(満月数を考慮しない単純計算)
+
    Dim elapsedMonths As Integer = (day.Year - baseDay.Year) * 12 + (day.Month - baseDay.Month)
+

          
+
    ' 指定された年・月における同日に達しているか調べる
+
    If day < New DateTime(day.Year, day.Month, baseDay.Day) Then
+
      ' 同日に達していなければ、経過月数を-1する
+
      elapsedMonths -= 1
+
    End If
+

          
+
    Return elapsedMonths
+
  End Function
+

          
+
  Sub Main()
+
    Dim baseDay As New DateTime(2011, 6, 18)
+

          
+
    Console.WriteLine("基準日: {0:D}", baseDay)
+

          
+
    For Each day As DateTime In New DateTime() { _
+
      New DateTime(2011, 7, 17), _
+
      New DateTime(2011, 7, 18), _
+
      New DateTime(2012, 6, 18), _
+
      New DateTime(2015, 6, 17), _
+
      New DateTime(2015, 6, 18) _
+
    }
+
      Console.WriteLine("日付: {0:D}, 経過月数: {1}", day, GetElapsedMonths(baseDay, day))
+
    Next
 
  End Sub
  End Sub
~
End Module
End Class
 
}}
}}
 
#tabpage-end
#tabpage-end
 

        

        
 
#prompt(出力例){{
#prompt(出力例){{
~
基準日: 2011年6月18日
日付は? 1999/7/1
~
日付: 2011年7月17日, 経過月数: 0
基準となる日付: 1999年7月1日
~
日付: 2011年7月18日, 経過月数: 1
今日: 2011年6月18日
~
日付: 2012年6月18日, 経過月数: 12
経過年数: 11
~
日付: 2015年6月17日, 経過月数: 47

          
~
日付: 2015年6月18日, 経過月数: 48
日付は? 2000/1/1
-
基準となる日付: 2000年1月1日
-
今日: 2011年6月18日
-
経過年数: 11
 
}}
}}
 

        

        
+

          
+

          
+

          
+