Calculate relative time in C#

后端 未结 30 2246
生来不讨喜
生来不讨喜 2020-11-21 05:59

Given a specific DateTime value, how do I display relative time, like:

  • 2 hours ago
  • 3 days ago
  • a month ago
30条回答
  •  旧时难觅i
    2020-11-21 06:23

    public static string ToRelativeDate(DateTime input)
    {
        TimeSpan oSpan = DateTime.Now.Subtract(input);
        double TotalMinutes = oSpan.TotalMinutes;
        string Suffix = " ago";
    
        if (TotalMinutes < 0.0)
        {
            TotalMinutes = Math.Abs(TotalMinutes);
            Suffix = " from now";
        }
    
        var aValue = new SortedList>();
        aValue.Add(0.75, () => "less than a minute");
        aValue.Add(1.5, () => "about a minute");
        aValue.Add(45, () => string.Format("{0} minutes", Math.Round(TotalMinutes)));
        aValue.Add(90, () => "about an hour");
        aValue.Add(1440, () => string.Format("about {0} hours", Math.Round(Math.Abs(oSpan.TotalHours)))); // 60 * 24
        aValue.Add(2880, () => "a day"); // 60 * 48
        aValue.Add(43200, () => string.Format("{0} days", Math.Floor(Math.Abs(oSpan.TotalDays)))); // 60 * 24 * 30
        aValue.Add(86400, () => "about a month"); // 60 * 24 * 60
        aValue.Add(525600, () => string.Format("{0} months", Math.Floor(Math.Abs(oSpan.TotalDays / 30)))); // 60 * 24 * 365 
        aValue.Add(1051200, () => "about a year"); // 60 * 24 * 365 * 2
        aValue.Add(double.MaxValue, () => string.Format("{0} years", Math.Floor(Math.Abs(oSpan.TotalDays / 365))));
    
        return aValue.First(n => TotalMinutes < n.Key).Value.Invoke() + Suffix;
    }
    

    http://refactormycode.com/codes/493-twitter-esque-relative-dates

    C# 6 version:

    static readonly SortedList> offsets = 
       new SortedList>
    {
        { 0.75, _ => "less than a minute"},
        { 1.5, _ => "about a minute"},
        { 45, x => $"{x.TotalMinutes:F0} minutes"},
        { 90, x => "about an hour"},
        { 1440, x => $"about {x.TotalHours:F0} hours"},
        { 2880, x => "a day"},
        { 43200, x => $"{x.TotalDays:F0} days"},
        { 86400, x => "about a month"},
        { 525600, x => $"{x.TotalDays / 30:F0} months"},
        { 1051200, x => "about a year"},
        { double.MaxValue, x => $"{x.TotalDays / 365:F0} years"}
    };
    
    public static string ToRelativeDate(this DateTime input)
    {
        TimeSpan x = DateTime.Now - input;
        string Suffix = x.TotalMinutes > 0 ? " ago" : " from now";
        x = new TimeSpan(Math.Abs(x.Ticks));
        return offsets.First(n => x.TotalMinutes < n.Key).Value(x) + Suffix;
    }
    

提交回复
热议问题