Nav*_*utt 3 .net c# asp.net datetime c#-4.0
这是一个问题.我见过很多解决方案,但似乎没有人能达到我想要的标准......
我想以这种格式显示年龄
20 y(s) 2 m(s) 20 d(s)
20 y(s) 2 m(s)
2 m(s) 20 d(s)
20 d(s)
Run Code Online (Sandbox Code Playgroud)
等等...
我尝试了几种解决方案,但闰年对我造成了问题.由于闰年,我的单元测试总是失败,无论中间有多少天,飞跃都会计入额外的天数.
这是我的代码......
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;
}
Run Code Online (Sandbox Code Playgroud)
有任何想法吗???
更新:
我希望两个日期之间的区别为:
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);
Run Code Online (Sandbox Code Playgroud)
年龄相当棘手.这是我使用的结构的相关摘录.
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); }
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个通过的示例单元测试:
[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));
}
Run Code Online (Sandbox Code Playgroud)