.net date time - 誰かの年齢をC#でどのように計算するのですか?



15 Answers

これは奇妙な方法ですが、日付をyyyymmddフォーマットし、現在の日付から生年月日を引いた場合、年齢を指定した最後の4桁を削除してください:)

私はC#を知らないが、これはどの言語でも動作すると信じている。

20080814 - 19800703 = 280111 

最後の4桁= 28ます。

C#コード:

int now = int.Parse(DateTime.Now.ToString("yyyyMMdd"));
int dob = int.Parse(dateOfBirth.ToString("yyyyMMdd"));
int age = (now - dob) / 10000;

あるいは、すべての型変換を拡張メソッドの形式で行う必要はありません。 エラーチェック省略:

public static Int32 GetAge(this DateTime dateOfBirth)
{
    var today = DateTime.Today;

    var a = (today.Year * 100 + today.Month) * 100 + today.Day;
    var b = (dateOfBirth.Year * 100 + dateOfBirth.Month) * 100 + dateOfBirth.Day;

    return (a - b) / 10000;
}
format yyyymmddhhmmss datetime

人の誕生日を表すDateTime与えられると、年数はどのように計算されますか?




私はこれまでの答えのどれも、年齢を別々に計算する文化を提供していないと思います。 例えば、 東アジア時代と東アジア時代との比較を見てください。

実際の答えには、ローカリゼーションが含まれている必要があります。 この例では、 Strategy Patternがおそらく順番に並んでいます。




私のおすすめ

int age = (int) ((DateTime.Now - bday).TotalDays/365.242199);

それは正しい日に年が変わるようです。 (私は107歳まで検査を受けました)




2解決すべき主な問題は次のとおりです。

1.正確な年齢の計算 - 年、月、日など

2.一般的に知覚される年齢を計算します。人々は通常、どれくらいの年齢を気にせず、今年の誕生日が気になるときだけ気にします。

1の解決策は明らかです。

DateTime birth = DateTime.Parse("1.1.2000");
DateTime today = DateTime.Today;     //we usually don't care about birth time
TimeSpan age = today - birth;        //.NET FCL should guarantee this as precise
double ageInDays = age.TotalDays;    //total number of days ... also precise
double daysInYear = 365.2425;        //statistical value for 400 years
double ageInYears = ageInDays / daysInYear;  //can be shifted ... not so precise

2の解は、全年齢を決定する際にそれほど正確ではないが、人々によって正確であると知覚されるものである。 人々は、通常、年齢を「手動で」計算すると、それを使用します。

DateTime birth = DateTime.Parse("1.1.2000");
DateTime today = DateTime.Today;
int age = today.Year - birth.Year;    //people perceive their age in years

if (today.Month < birth.Month ||
   ((today.Month == birth.Month) && (today.Day < birth.Day)))
{
  age--;  //birthday in current year not yet reached, we are 1 year younger ;)
          //+ no birthday for 29.2. guys ... sorry, just wrong date for birth
}

2への注記:

  • これは私が推奨する解決策です
  • 私たちは、うるう年の日数をシフトするので、DateTime.DayOfYearまたはTimeSpansを使用することはできません
  • 私は読みやすさのために少しだけ行を追加しました

もう1つのメモ...私は2つの静的なオーバーロードされたメソッドを作成します.1つは汎用的な使い方、もう1つは使い勝手の良さです。

public static int GetAge(DateTime bithDay, DateTime today) 
{ 
  //chosen solution method body
}

public static int GetAge(DateTime birthDay) 
{ 
  return GetAge(birthDay, DateTime.Now);
}



これはここで使用するバージョンです。 それは動作し、それはかなり簡単です。 それはJeffと同じ考えですが、私はそれが論理を分けて論理を分けるので少しはっきりしていると思うので、少し理解しやすくなります。

public static int GetAge(this DateTime dateOfBirth, DateTime dateAsAt)
{
    return dateAsAt.Year - dateOfBirth.Year - (dateOfBirth.DayOfYear < dateAsAt.DayOfYear ? 0 : 1);
}

そのようなことがはっきりしないと思えば、三元演算子をさらに拡張してより明確にすることができます。

明らかに、これはDateTime拡張メソッドとして行われますが、作業を行い、どこにでも配置できるコードの1行を取得できます。 ここでは、完全性のために、 DateTime.Nowで渡されるExtensionメソッドの別のオーバーロードがあります。




うるう年とすべてのために私が知っている最良の方法は次のとおりです。

DateTime birthDate = new DateTime(2000,3,1);
int age = (int)Math.Floor((DateTime.Now - birthDate).TotalDays / 365.25D);

お役に立てれば。




私は、誕生日を前に、誰かの年齢を計算するSQL Server User Defined Functionを作成しました。 これは、クエリの一部として必要な場合に便利です。

using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

public partial class UserDefinedFunctions
{
    [SqlFunction(DataAccess = DataAccessKind.Read)]
    public static SqlInt32 CalculateAge(string strBirthDate)
    {
        DateTime dtBirthDate = new DateTime();
        dtBirthDate = Convert.ToDateTime(strBirthDate);
        DateTime dtToday = DateTime.Now;

        // get the difference in years
        int years = dtToday.Year - dtBirthDate.Year;

        // subtract another year if we're before the
        // birth day in the current year
        if (dtToday.Month < dtBirthDate.Month || (dtToday.Month == dtBirthDate.Month && dtToday.Day < dtBirthDate.Day))
            years=years-1;

        int intCustomerAge = years;
        return intCustomerAge;
    }
};



ここにもう一つの答えがあります:

public static int AgeInYears(DateTime birthday, DateTime today)
{
    return ((today.Year - birthday.Year) * 372 + (today.Month - birthday.Month) * 31 + (today.Day - birthday.Day)) / 372;
}

これは広範にユニットテストされています。 ちょっと "魔法"に見えます。 372という数字は、毎月31日であれば1年になる日数です。

それがなぜ機能するのか( ここから持ち上げた )の説明は次のとおりです:

Yn = DateTime.Now.Year, Yb = birthday.Year, Mn = DateTime.Now.Month, Mb = birthday.Month, Dn = DateTime.Now.Day, Db = birthday.Day設定しましょう

age = Yn - Yb + (31*(Mn - Mb) + (Dn - Db)) / 372

私たちが必要とするのは、すでに日付に達していればYn-Yb 、そうでなければYn-Yb-1です。

a) Mn<Mb場合、 -341 <= 31*(Mn-Mb) <= -31 and -30 <= Dn-Db <= 30

-371 <= 31*(Mn - Mb) + (Dn - Db) <= -1

整数除算の場合

(31*(Mn - Mb) + (Dn - Db)) / 372 = -1

b) Mn=MbおよびDn<Db場合、 31*(Mn - Mb) = 0 and -30 <= Dn-Db <= -1

再び整数除算を行う

(31*(Mn - Mb) + (Dn - Db)) / 372 = -1

c) Mn>Mb場合、 31 <= 31*(Mn-Mb) <= 341 and -30 <= Dn-Db <= 30

1 <= 31*(Mn - Mb) + (Dn - Db) <= 371

整数除算の場合

(31*(Mn - Mb) + (Dn - Db)) / 372 = 0

d) Mn=MbおよびDn>Db場合、 31*(Mn - Mb) = 0 and 1 <= Dn-Db <= 3 0

再び整数除算を行う

(31*(Mn - Mb) + (Dn - Db)) / 372 = 0

e) Mn=MbDn=Db場合、 31*(Mn - Mb) + Dn-Db = 0

したがって(31*(Mn - Mb) + (Dn - Db)) / 372 = 0




それを単純なままにする(そして、おそらくばかげて:))。

DateTime birth = new DateTime(1975, 09, 27, 01, 00, 00, 00);
TimeSpan ts = DateTime.Now - birth;
Console.WriteLine("You are approximately " + ts.TotalSeconds.ToString() + " seconds old.");



私が今までに見つけた最も簡単な方法はこれです。 これは、米国と西ヨーロッパのロケールで正しく動作します。 他のロケール、特に中国のような場所に話すことはできません。 4つの余分な比較は、多くても、年齢の初期計算に従う。

public int AgeInYears(DateTime birthDate, DateTime referenceDate)
{
  Debug.Assert(referenceDate >= birthDate, 
               "birth date must be on or prior to the reference date");

  DateTime birth = birthDate.Date;
  DateTime reference = referenceDate.Date;
  int years = (reference.Year - birth.Year);

  //
  // an offset of -1 is applied if the birth date has 
  // not yet occurred in the current year.
  //
  if (reference.Month > birth.Month);
  else if (reference.Month < birth.Month) 
    --years;
  else // in birth month
  {
    if (reference.Day < birth.Day)
      --years;
  }

  return years ;
}

私はこれに対する答えを見ていて、誰も閏年の出生の規制/法的影響を参照していないことに気づいた。 たとえば、 Wikipediaごとに 、2月29日に様々な管轄区域で生まれた場合、閏年以外の誕生日は異なります:

  • 英国と香港では:それは翌年の翌日ですので、3月1日の翌日はあなたの誕生日です。
  • ニュージーランドでは、運転免許証の目的で2月28日、その他の目的で3月1日の前日です。
  • 台湾:2月28日です。

そして私が知る限り、米国では、法律は、法律と様々な規制機関がどのように規制の中で物事を定義しているかについて、それについては言及していません。

そのために、改善点:

public enum LeapDayRule
{
  OrdinalDay     = 1 ,
  LastDayOfMonth = 2 ,
}

static int ComputeAgeInYears(DateTime birth, DateTime reference, LeapYearBirthdayRule ruleInEffect)
{
  bool isLeapYearBirthday = CultureInfo.CurrentCulture.Calendar.IsLeapDay(birth.Year, birth.Month, birth.Day);
  DateTime cutoff;

  if (isLeapYearBirthday && !DateTime.IsLeapYear(reference.Year))
  {
    switch (ruleInEffect)
    {
      case LeapDayRule.OrdinalDay:
        cutoff = new DateTime(reference.Year, 1, 1)
                             .AddDays(birth.DayOfYear - 1);
        break;

      case LeapDayRule.LastDayOfMonth:
        cutoff = new DateTime(reference.Year, birth.Month, 1)
                             .AddMonths(1)
                             .AddDays(-1);
        break;

      default:
        throw new InvalidOperationException();
    }
  }
  else
  {
    cutoff = new DateTime(reference.Year, birth.Month, birth.Day);
  }

  int age = (reference.Year - birth.Year) + (reference >= cutoff ? 0 : -1);
  return age < 0 ? 0 : age;
}

このコードでは、次のことを前提としています。

  • 西洋(ヨーロッパ)の年齢計算
  • カレンダー。グレゴリオ暦のように、1ヵ月の終わりに1閏日を挿入します。



ここに解決策があります。

DateTime dateOfBirth = new DateTime(2000, 4, 18);
DateTime currentDate = DateTime.Now;

int ageInYears = 0;
int ageInMonths = 0;
int ageInDays = 0;

ageInDays = currentDate.Day - dateOfBirth.Day;
ageInMonths = currentDate.Month - dateOfBirth.Month;
ageInYears = currentDate.Year - dateOfBirth.Year;

if (ageInDays < 0)
{
    ageInDays += DateTime.DaysInMonth(currentDate.Year, currentDate.Month);
    ageInMonths = ageInMonths--;

    if (ageInMonths < 0)
    {
        ageInMonths += 12;
        ageInYears--;
    }
}

if (ageInMonths < 0)
{
    ageInMonths += 12;
    ageInYears--;
}

Console.WriteLine("{0}, {1}, {2}", ageInYears, ageInMonths, ageInDays);



このソリューションはどうですか?

static string CalcAge(DateTime birthDay)
{
    DateTime currentDate = DateTime.Now;         
    int approximateAge = currentDate.Year - birthDay.Year;
    int daysToNextBirthDay = (birthDay.Month * 30 + birthDay.Day) - 
        (currentDate.Month * 30 + currentDate.Day) ;

    if (approximateAge == 0 || approximateAge == 1)
    {                
        int month =  Math.Abs(daysToNextBirthDay / 30);
        int days = Math.Abs(daysToNextBirthDay % 30);

        if (month == 0)
            return "Your age is: " + daysToNextBirthDay + " days";

        return "Your age is: " + month + " months and " + days + " days"; ;
    }

    if (daysToNextBirthDay > 0)
        return "Your age is: " + --approximateAge + " Years";

    return "Your age is: " + approximateAge + " Years"; ;
}



private int GetAge(int _year, int _month, int _day
{
    DateTime yourBirthDate= new DateTime(_year, _month, _day);

    DateTime todaysDateTime = DateTime.Today;
    int noOfYears = todaysDateTime.Year - yourBirthDate.Year;

    if (DateTime.Now.Month < yourBirthDate.Month ||
        (DateTime.Now.Month == yourBirthDate.Month && DateTime.Now.Day < yourBirthDate.Day))
    {
        noOfYears--;
    }

    return  noOfYears;
}



SQLバージョン:

declare @dd smalldatetime = '1980-04-01'
declare @age int = YEAR(GETDATE())-YEAR(@dd)
if (@dd> DATEADD(YYYY, -@age, GETDATE())) set @age = @age -1

print @age  



次のアプローチ(.NETクラスDateDiffのTime Period Libraryから抽出)では、カルチャ情報のカレンダーが考慮されます

// ----------------------------------------------------------------------
private static int YearDiff( DateTime date1, DateTime date2 )
{
  return YearDiff( date1, date2, DateTimeFormatInfo.CurrentInfo.Calendar );
} // YearDiff

// ----------------------------------------------------------------------
private static int YearDiff( DateTime date1, DateTime date2, Calendar calendar )
{
  if ( date1.Equals( date2 ) )
  {
    return 0;
  }

  int year1 = calendar.GetYear( date1 );
  int month1 = calendar.GetMonth( date1 );
  int year2 = calendar.GetYear( date2 );
  int month2 = calendar.GetMonth( date2 );

  // find the the day to compare
  int compareDay = date2.Day;
  int compareDaysPerMonth = calendar.GetDaysInMonth( year1, month1 );
  if ( compareDay > compareDaysPerMonth )
  {
    compareDay = compareDaysPerMonth;
  }

  // build the compare date
  DateTime compareDate = new DateTime( year1, month2, compareDay,
    date2.Hour, date2.Minute, date2.Second, date2.Millisecond );
  if ( date2 > date1 )
  {
    if ( compareDate < date1 )
    {
      compareDate = compareDate.AddYears( 1 );
    }
  }
  else
  {
    if ( compareDate > date1 )
    {
      compareDate = compareDate.AddYears( -1 );
    }
  }
  return year2 - calendar.GetYear( compareDate );
} // YearDiff

使用法:

// ----------------------------------------------------------------------
public void CalculateAgeSamples()
{
  PrintAge( new DateTime( 2000, 02, 29 ), new DateTime( 2009, 02, 28 ) );
  // > Birthdate=29.02.2000, Age at 28.02.2009 is 8 years
  PrintAge( new DateTime( 2000, 02, 29 ), new DateTime( 2012, 02, 28 ) );
  // > Birthdate=29.02.2000, Age at 28.02.2012 is 11 years
} // CalculateAgeSamples

// ----------------------------------------------------------------------
public void PrintAge( DateTime birthDate, DateTime moment )
{
  Console.WriteLine( "Birthdate={0:d}, Age at {1:d} is {2} years", birthDate, moment, YearDiff( birthDate, moment ) );
} // PrintAge



Related