给定特定的DateTime值,如何显示相对时间,例如:

2小时前3天前一个月前


当前回答

我的方法要简单得多。您可以根据需要调整返回字符串

    public static string TimeLeft(DateTime utcDate)
    {
        TimeSpan timeLeft = DateTime.UtcNow - utcDate;
        string timeLeftString = "";
        if (timeLeft.Days > 0)
        {
            timeLeftString += timeLeft.Days == 1 ? timeLeft.Days + " day" : timeLeft.Days + " days";
        }
        else if (timeLeft.Hours > 0)
        {
            timeLeftString += timeLeft.Hours == 1 ? timeLeft.Hours + " hour" : timeLeft.Hours + " hours";
        }
        else
        {
            timeLeftString += timeLeft.Minutes == 1 ? timeLeft.Minutes+" minute" : timeLeft.Minutes + " minutes";
        }
        return timeLeftString;
    }

其他回答

我将为此提供一些方便的扩展方法,并使代码更可读。首先,Int32的两个扩展方法。

public static class TimeSpanExtensions {

    public static TimeSpan Days(this int value) {

        return new TimeSpan(value, 0, 0, 0);
    }

    public static TimeSpan Hours(this int value) {

        return new TimeSpan(0, value, 0, 0);
    }

    public static TimeSpan Minutes(this int value) {

        return new TimeSpan(0, 0, value, 0);
    }

    public static TimeSpan Seconds(this int value) {

        return new TimeSpan(0, 0, 0, value);
    }

    public static TimeSpan Milliseconds(this int value) {

        return new TimeSpan(0, 0, 0, 0, value);
    }

    public static DateTime Ago(this TimeSpan value) {

        return DateTime.Now - value;
    }
}

然后,为DateTime设置一个。

public static class DateTimeExtensions {

    public static DateTime Ago(this DateTime dateTime, TimeSpan delta) {

        return dateTime - delta;
    }
}

现在,您可以执行以下操作:

var date = DateTime.Now;
date.Ago(2.Days()); // 2 days ago
date.Ago(7.Hours()); // 7 hours ago
date.Ago(567.Milliseconds()); // 567 milliseconds ago

简单且100%的工作解决方案。

处理过去和将来的时间。。以防万一

        public string GetTimeSince(DateTime postDate)
    {
        string message = "";
        DateTime currentDate = DateTime.Now;
        TimeSpan timegap = currentDate - postDate;

     
        if (timegap.Days > 365)
        {
            message = string.Format(L("Ago") + " {0} " + L("Years"), (((timegap.Days) / 30) / 12));                
        }
        else if (timegap.Days > 30)
        {
            message = string.Format(L("Ago") + " {0} " + L("Months"), timegap.Days/30);                
        }
        else if (timegap.Days > 0)
        {
            message = string.Format(L("Ago") + " {0} " + L("Days"), timegap.Days);
        }           
        else if (timegap.Hours > 0)
        {
            message = string.Format(L("Ago") + " {0} " + L("Hours"), timegap.Hours);
        }           
        else if (timegap.Minutes > 0)
        {
            message = string.Format(L("Ago") + " {0} " + L("Minutes"), timegap.Minutes);
        }
        else if (timegap.Seconds > 0)
        {
            message = string.Format(L("Ago") + " {0} " + L("Seconds"), timegap.Seconds);
        }

        // let's handle future times..just in case       
        else if (timegap.Days < -365)
        {
            message = string.Format(L("In") + " {0} " + L("Years"), (((Math.Abs(timegap.Days)) / 30) / 12));                
        }
        else if (timegap.Days < -30)
        {
            message = string.Format(L("In") + " {0} " + L("Months"), ((Math.Abs(timegap.Days)) / 30));                
        }
        else if (timegap.Days < 0)
        {
            message = string.Format(L("In") + " {0} " + L("Days"), Math.Abs(timegap.Days));                
        }           
      
        else if (timegap.Hours < 0)
        {
            message = string.Format(L("In") + " {0} " + L("Hours"), Math.Abs(timegap.Hours));                
        }
        else if (timegap.Minutes < 0)
        {
            message = string.Format(L("In") + " {0} " + L("Minutes"), Math.Abs(timegap.Minutes));                
        }
        else if (timegap.Seconds < 0)
        {
            message = string.Format(L("In") + " {0} " + L("Seconds"), Math.Abs(timegap.Seconds));                
        }


        else
        {
            message = "a bit";
        }

        return message;
    }

这里是Jeffs Script for PHP的重写:

define("SECOND", 1);
define("MINUTE", 60 * SECOND);
define("HOUR", 60 * MINUTE);
define("DAY", 24 * HOUR);
define("MONTH", 30 * DAY);
function relativeTime($time)
{   
    $delta = time() - $time;

    if ($delta < 1 * MINUTE)
    {
        return $delta == 1 ? "one second ago" : $delta . " seconds ago";
    }
    if ($delta < 2 * MINUTE)
    {
      return "a minute ago";
    }
    if ($delta < 45 * MINUTE)
    {
        return floor($delta / MINUTE) . " minutes ago";
    }
    if ($delta < 90 * MINUTE)
    {
      return "an hour ago";
    }
    if ($delta < 24 * HOUR)
    {
      return floor($delta / HOUR) . " hours ago";
    }
    if ($delta < 48 * HOUR)
    {
      return "yesterday";
    }
    if ($delta < 30 * DAY)
    {
        return floor($delta / DAY) . " days ago";
    }
    if ($delta < 12 * MONTH)
    {
      $months = floor($delta / DAY / 30);
      return $months <= 1 ? "one month ago" : $months . " months ago";
    }
    else
    {
        $years = floor($delta / DAY / 365);
        return $years <= 1 ? "one year ago" : $years . " years ago";
    }
}    

我的方法要简单得多。您可以根据需要调整返回字符串

    public static string TimeLeft(DateTime utcDate)
    {
        TimeSpan timeLeft = DateTime.UtcNow - utcDate;
        string timeLeftString = "";
        if (timeLeft.Days > 0)
        {
            timeLeftString += timeLeft.Days == 1 ? timeLeft.Days + " day" : timeLeft.Days + " days";
        }
        else if (timeLeft.Hours > 0)
        {
            timeLeftString += timeLeft.Hours == 1 ? timeLeft.Hours + " hour" : timeLeft.Hours + " hours";
        }
        else
        {
            timeLeftString += timeLeft.Minutes == 1 ? timeLeft.Minutes+" minute" : timeLeft.Minutes + " minutes";
        }
        return timeLeftString;
    }

Jeff,您的代码很好,但使用常量可以更清晰(如代码完成中所建议的)。

const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;

var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
double delta = Math.Abs(ts.TotalSeconds);

if (delta < 1 * MINUTE)
  return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";

if (delta < 2 * MINUTE)
  return "a minute ago";

if (delta < 45 * MINUTE)
  return ts.Minutes + " minutes ago";

if (delta < 90 * MINUTE)
  return "an hour ago";

if (delta < 24 * HOUR)
  return ts.Hours + " hours ago";

if (delta < 48 * HOUR)
  return "yesterday";

if (delta < 30 * DAY)
  return ts.Days + " days ago";

if (delta < 12 * MONTH)
{
  int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
  return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
  int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
  return years <= 1 ? "one year ago" : years + " years ago";
}