4

ここに問題があります。私は多くの解決策を見てきましたが、誰も私が望む基準を満たしていないようです...

この形式で年齢を表示したい

20 y(s) 2 m(s) 20 d(s)
20 y(s) 2 m(s)
2 m(s) 20 d(s)
20 d(s)

等...

私はいくつかの解決策を試しましたが、うるう年が問題を引き起こしています。私の単体テストはうるう年のために常に失敗しており、その間に何日が経過しても、うるう年は余分な日数としてカウントされます。

これが私のコードです...

public static string AgeDiscription(DateTime dateOfBirth)
{
    var today = DateTime.Now;
    var days = GetNumberofDaysUptoNow(dateOfBirth);
    var months = 0;
    var years = 0;
    if (days > 365)
    {
        years = today.Year - dateOfBirth.Year;
        days = days % 365;
    }
    if (days > DateTime.DaysInMonth(today.Year, today.Month))
    {
        months = Math.Abs(today.Month - dateOfBirth.Month);
        for (int i = 0; i < months; i++)
        {
            days -= DateTime.DaysInMonth(today.Year, today.AddMonths(0 - i).Month);
        }
    }

    var ageDescription = new StringBuilder("");

    if (years != 0)
        ageDescription = ageDescription.Append(years + " y(s) ");
    if (months != 0)
        ageDescription = ageDescription.Append(months + " m(s) ");
    if (days != 0)
        ageDescription = ageDescription.Append(days + " d(s) ");

    return ageDescription.ToString();
}

public static int GetNumberofDaysUptoNow(DateTime dateOfBirth)
{
    var today = DateTime.Now;
    var timeSpan = today - dateOfBirth;
    var nDays = timeSpan.Days;
    return nDays;
}

何か案は???

アップデート:

2つの日付の違いを次のようにしたいと思います。

var dateOfBirth = DateTime.Now.AddYears(-20);
string expected = "20 y(s) ";
string actual; // returns 20 y(s) 5 d(s)
actual = Globals.AgeDiscription(dateOfBirth);
Assert.AreEqual(expected, actual);
4

6 に答える 6

7

年齢はかなりトリッキーです。これが私が使用する構造体からの関連する抜粋です。

public struct Age
{
    private readonly Int32 _years;
    private readonly Int32 _months;
    private readonly Int32 _days;
    private readonly Int32 _totalDays;

    /// <summary>
    /// Initializes a new instance of <see cref="Age"/>.
    /// </summary>
    /// <param name="start">The date and time when the age started.</param>
    /// <param name="end">The date and time when the age ended.</param>
    /// <remarks>This </remarks>
    public Age(DateTime start, DateTime end)
        : this(start, end, CultureInfo.CurrentCulture.Calendar)
    {
    }

    /// <summary>
    /// Initializes a new instance of <see cref="Age"/>.
    /// </summary>
    /// <param name="start">The date and time when the age started.</param>
    /// <param name="end">The date and time when the age ended.</param>
    /// <param name="calendar">Calendar used to calculate age.</param>
    public Age(DateTime start, DateTime end, Calendar calendar)
    {
        if (start > end) throw new ArgumentException("The starting date cannot be later than the end date.");

        var startDate = start.Date;
        var endDate = end.Date;

        _years = _months = _days = 0;
        _days += calendar.GetDayOfMonth(endDate) - calendar.GetDayOfMonth(startDate);
        if (_days < 0)
        {
            _days += calendar.GetDaysInMonth(calendar.GetYear(startDate), calendar.GetMonth(startDate));
            _months--;
        }
        _months += calendar.GetMonth(endDate) - calendar.GetMonth(startDate);
        if (_months < 0)
        {
            _months += calendar.GetMonthsInYear(calendar.GetYear(startDate));
            _years--;
        }
        _years += calendar.GetYear(endDate) - calendar.GetYear(startDate);

        var ts = endDate.Subtract(startDate);
        _totalDays = (Int32)ts.TotalDays;
    }

    /// <summary>
    /// Gets the number of whole years something has aged.
    /// </summary>
    public Int32 Years
    {
        get { return _years; }
    }

    /// <summary>
    /// Gets the number of whole months something has aged past the value of <see cref="Years"/>.
    /// </summary>
    public Int32 Months
    {
        get { return _months; }
    }

    /// <summary>
    /// Gets the age as an expression of whole months.
    /// </summary>
    public Int32 TotalMonths
    {
        get { return _years * 12 + _months; }
    }

    /// <summary>
    /// Gets the number of whole weeks something has aged past the value of <see cref="Years"/> and <see cref="Months"/>.
    /// </summary>
    public Int32 Days
    {
        get { return _days; }
    }

    /// <summary>
    /// Gets the total number of days that have elapsed since the start and end dates.
    /// </summary>
    public Int32 TotalDays
    {
        get { return _totalDays; }
    }

    /// <summary>
    /// Gets the number of whole weeks something has aged past the value of <see cref="Years"/> and <see cref="Months"/>.
    /// </summary>
    public Int32 Weeks
    {
        get { return (Int32) Math.Floor((Decimal) _days/7); }
    }

    /// <summary>
    /// Gets the age as an expression of whole weeks.
    /// </summary>
    public Int32 TotalWeeks
    {
        get { return (Int32) Math.Floor((Decimal) _totalDays/7); }
    }
}

合格した単体テストの例を次に示します。

    [Test]
    public void Should_be_exactly_20_years_old()
    {
        var now = DateTime.Now;
        var age = new Age(now.AddYears(-20), now);

        Assert.That(age, Has.Property("Years").EqualTo(20)
            .And.Property("Months").EqualTo(0)
            .And.Property("Days").EqualTo(0));
    }
于 2012-05-16T12:18:20.113 に答える
2

使用する

Timespan interval = DateTime.Now - DateOfBirth;

次に、

interval.Days
interval.TotalDays;
interval.Hours;
interval.TotalHours;
interval.Minutes;
interval.TotalMinutes;
interval.Seconds;
interval.TotalSeconds;
interval.Milliseconds;
interval.TotalMilliseconds;
interval.Ticks;

望ましい結果を得るために。

于 2012-05-16T12:11:42.980 に答える
0
static int AgeInYears(DateTime birthday, DateTime today)
{
    return ((today.Year - birthday.Year) * 372 + (today.Month - birthday.Month) * 31 + (today.Day - birthday.Day)) / 372;
}
于 2012-05-16T12:20:07.773 に答える
0

この小さな関数を記述して、現在の年から生年月日までのうるう年の日数を取得し、返される日数を年齢の日数に追加します。

 private static int NumberOfLeapYears(int startYear, int endYear)
 {         
 int counter = 0;
 for (int year = startYear; year <= endYear; year++)
 counter += DateTime.IsLeapYear(year) ? 1 : 0;
 return counter;
 } 
于 2012-05-16T12:34:18.923 に答える
0

このコードを確認してください:

{                                                    
    dif = int(datediff("D", Convert.ToDateTime("01/" + Q101m.text + "/" + Q101y.Text), (Convert.ToDateTime(Vdate.text)))/365.25)

    //If dif < 15 Or dif > 49 
    {
           MessageBox.Show("xxxxxxx");
           Q101m.Focus();
    }

}
于 2013-03-21T03:16:26.197 に答える
0

@HackedByChineseから「派生」したDateTimeクラスの拡張メソッドとしてソリューションを作成しました。

    /// <summary>
    /// Calculate age in years relative to months and days, for example Peters age is 25 years 2 months and 10 days
    /// </summary>
    /// <param name="startDate">The date when the age started</param>
    /// <param name="endDate">The date when the age ended</param>
    /// <param name="calendar">Calendar used to calculate age</param>
    /// <param name="years">Return number of years, with considering months and days</param>
    /// <param name="months">Return calculated months</param>
    /// <param name="days">Return calculated days</param>
    public static bool GetAge(this DateTime startDate, DateTime endDate, Calendar calendar, out int years, out int months, out int days)
    {
        if (startDate > endDate)
        {
            years = months = days = -1;
            return false;
        }

        years = months = days = 0;
        days += calendar.GetDayOfMonth(endDate) - calendar.GetDayOfMonth(startDate);

        // When negative select days of last month
        if (days < 0)
        {
            days += calendar.GetDaysInMonth(calendar.GetYear(startDate), calendar.GetMonth(startDate));
            months--;
        }

        months += calendar.GetMonth(endDate) - calendar.GetMonth(startDate);

        // when negative select month of last year
        if (months < 0)
        {
            months += calendar.GetMonthsInYear(calendar.GetYear(startDate));
            years--;
        }

        years += calendar.GetYear(endDate) - calendar.GetYear(startDate);

        return true;
    }

しかし、結果の日数は他の計算機とは少し異なる可能性があることを認識しました。

于 2019-10-11T10:55:47.367 に答える