问题描述
我有一个具有 2 个日期属性的类:FirstDay
和 LastDay
.LastDay
可以为空.我想生成 "x year(s) y day(s)"
格式的字符串.如果总年份小于 1,我想省略年份部分.如果总天数小于 1,我想省略天部分.如果年或日为 0,则应分别表示日/年",而不是日/年".
I have a class with 2 date properties: FirstDay
and LastDay
. LastDay
is nullable. I would like to generate a string in the format of "x year(s) y day(s)"
. If the total years are less than 1, I would like to omit the year section. If the total days are less than 1, I would like to omit the day section. If either years or days are 0, they should say "day/year", rather than "days/years" respectively.
示例:
2.2年: 2年73天"
1.002738年: "1年1天"
0.2年: 73天"
2年: 2年"
Examples:
2.2 years: "2 years 73 days"
1.002738 years: "1 year 1 day"
0.2 years: "73 days"
2 years: "2 years"
我有什么作品,但是很长:
What I have works, but it is long:
private const decimal DaysInAYear = 365.242M;
public string LengthInYearsAndDays
{
get
{
var lastDay = this.LastDay ?? DateTime.Today;
var lengthValue = lastDay - this.FirstDay;
var builder = new StringBuilder();
var totalDays = (decimal)lengthValue.TotalDays;
var totalYears = totalDays / DaysInAYear;
var years = (int)Math.Floor(totalYears);
totalDays -= (years * DaysInAYear);
var days = (int)Math.Floor(totalDays);
Func<int, string> sIfPlural = value =>
value > 1 ? "s" : string.Empty;
if (years > 0)
{
builder.AppendFormat(
CultureInfo.InvariantCulture,
"{0} year{1}",
years,
sIfPlural(years));
if (days > 0)
{
builder.Append(" ");
}
}
if (days > 0)
{
builder.AppendFormat(
CultureInfo.InvariantCulture,
"{0} day{1}",
days,
sIfPlural(days));
}
var length = builder.ToString();
return length;
}
}
有没有更简洁的方法来做到这一点(但仍然可读)?
Is there a more concise way of doing this (but still readable)?
推荐答案
TimeSpan
没有年"的合理概念,因为它取决于起点和终点.(月份类似 - 29 天有多少个月?嗯,这取决于...)
A TimeSpan
doesn't have a sensible concept of "years" because it depends on the start and end point. (Months is similar - how many months are there in 29 days? Well, it depends...)
为了给一个无耻的插件,我的 Noda Time 项目使这非常简单:
To give a shameless plug, my Noda Time project makes this really simple though:
using System;
using NodaTime;
public class Test
{
static void Main(string[] args)
{
LocalDate start = new LocalDate(2010, 6, 19);
LocalDate end = new LocalDate(2013, 4, 11);
Period period = Period.Between(start, end,
PeriodUnits.Years | PeriodUnits.Days);
Console.WriteLine("Between {0} and {1} are {2} years and {3} days",
start, end, period.Years, period.Days);
}
}
输出:
Between 19 June 2010 and 11 April 2013 are 2 years and 296 days
这篇关于用年份格式化 TimeSpan的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!