Calculate relative time in C#

后端 未结 30 2109
生来不讨喜
生来不讨喜 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条回答
  •  走了就别回头了
    2020-11-21 06:09

    Here's an implementation I added as an extension method to the DateTime class that handles both future and past dates and provides an approximation option that allows you to specify the level of detail you're looking for ("3 hour ago" vs "3 hours, 23 minutes, 12 seconds ago"):

    using System.Text;
    
    /// 
    /// Compares a supplied date to the current date and generates a friendly English 
    /// comparison ("5 days ago", "5 days from now")
    /// 
    /// The date to convert
    /// When off, calculate timespan down to the second.
    /// When on, approximate to the largest round unit of time.
    /// 
    public static string ToRelativeDateString(this DateTime value, bool approximate)
    {
        StringBuilder sb = new StringBuilder();
    
        string suffix = (value > DateTime.Now) ? " from now" : " ago";
    
        TimeSpan timeSpan = new TimeSpan(Math.Abs(DateTime.Now.Subtract(value).Ticks));
    
        if (timeSpan.Days > 0)
        {
            sb.AppendFormat("{0} {1}", timeSpan.Days,
              (timeSpan.Days > 1) ? "days" : "day");
            if (approximate) return sb.ToString() + suffix;
        }
        if (timeSpan.Hours > 0)
        {
            sb.AppendFormat("{0}{1} {2}", (sb.Length > 0) ? ", " : string.Empty,
              timeSpan.Hours, (timeSpan.Hours > 1) ? "hours" : "hour");
            if (approximate) return sb.ToString() + suffix;
        }
        if (timeSpan.Minutes > 0)
        {
            sb.AppendFormat("{0}{1} {2}", (sb.Length > 0) ? ", " : string.Empty, 
              timeSpan.Minutes, (timeSpan.Minutes > 1) ? "minutes" : "minute");
            if (approximate) return sb.ToString() + suffix;
        }
        if (timeSpan.Seconds > 0)
        {
            sb.AppendFormat("{0}{1} {2}", (sb.Length > 0) ? ", " : string.Empty, 
              timeSpan.Seconds, (timeSpan.Seconds > 1) ? "seconds" : "second");
            if (approximate) return sb.ToString() + suffix;
        }
        if (sb.Length == 0) return "right now";
    
        sb.Append(suffix);
        return sb.ToString();
    }
    

提交回复
热议问题