首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用年份设置TimeSpan格式

使用年份设置TimeSpan格式
EN

Stack Overflow用户
提问于 2013-04-12 04:11:06
回答 6查看 28.1K关注 0票数 26

我有一个有两个date属性的类:FirstDayLastDayLastDay是可以为空的。我想生成一个"x year(s) y day(s)"格式的字符串。如果总年份小于1,我想省略年份部分。如果总天数小于1,我想省略day部分。如果year或days为0,则应分别说"day/year",而不是“days/year”。

示例:

2.2年:一年一次,“2年73天”

1.002738年:用“1年1天”

0.2年:一年一次,一天一次,一次是“73天”。

2年:“2年”:“2年”。

我所拥有的是有效的,但它很长:

代码语言:javascript
复制
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;
    }
}

有没有一种更简洁的方法(但仍然可读)?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-04-12 04:20:03

TimeSpan没有合理的“年”概念,因为它依赖于起点和终点。(月份是相似的- 29天有多少个月?嗯,这要看情况...)

不过,我的Noda Time项目让这一切变得非常简单:

代码语言:javascript
复制
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);
    }
}

输出:

代码语言:javascript
复制
Between 19 June 2010 and 11 April 2013 are 2 years and 296 days
票数 46
EN

Stack Overflow用户

发布于 2014-01-21 22:02:22

代码语言:javascript
复制
public string GetAgeText(DateTime birthDate)
{
        const double ApproxDaysPerMonth = 30.4375;
        const double ApproxDaysPerYear = 365.25;

        /*
        The above are the average days per month/year over a normal 4 year period
        We use these approximations as they are more accurate for the next century or so
        After that you may want to switch over to these 400 year approximations

           ApproxDaysPerMonth = 30.436875
           ApproxDaysPerYear  = 365.2425 

          How to get theese numbers:
            The are 365 days in a year, unless it is a leepyear.
            Leepyear is every forth year if Year % 4 = 0
            unless year % 100 == 1
            unless if year % 400 == 0 then it is a leep year.

            This gives us 97 leep years in 400 years. 
            So 400 * 365 + 97 = 146097 days.
            146097 / 400      = 365.2425
            146097 / 400 / 12 = 30,436875

        Due to the nature of the leap year calculation, on this side of the year 2100
        you can assume every 4th year is a leap year and use the other approximatiotions

        */
    //Calculate the span in days
    int iDays = (DateTime.Now - birthDate).Days;

    //Calculate years as an integer division
    int iYear = (int)(iDays / ApproxDaysPerYear);

    //Decrease remaing days
    iDays -= (int)(iYear * ApproxDaysPerYear);

    //Calculate months as an integer division
    int iMonths = (int)(iDays / ApproxDaysPerMonth);

    //Decrease remaing days
    iDays -= (int)(iMonths * ApproxDaysPerMonth);

    //Return the result as an string   
    return string.Format("{0} years, {1} months, {2} days", iYear, iMonths, iDays);
}
票数 7
EN

Stack Overflow用户

发布于 2013-04-12 04:14:41

我不会用TimeSpan这样做的。一旦超出了天数,日期数学就变得棘手起来,因为一个月的天数和一年的天数不再是恒定的。这可能是为什么TimeSpan不包含YearsMonths的属性。相反,我将确定两个DateTime值之间的年数/月数/天数等,并相应地显示结果。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15957984

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档