给定特定的DateTime值,如何显示相对时间,例如:
2小时前3天前一个月前
给定特定的DateTime值,如何显示相对时间,例如:
2小时前3天前一个月前
当前回答
我是这样做的
var ts = new TimeSpan(DateTime.UtcNow.Ticks - dt.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
if (delta < 60)
{
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
}
if (delta < 60 * 2)
{
return "a minute ago";
}
if (delta < 45 * 60)
{
return ts.Minutes + " minutes ago";
}
if (delta < 90 * 60)
{
return "an hour ago";
}
if (delta < 24 * 60 * 60)
{
return ts.Hours + " hours ago";
}
if (delta < 48 * 60 * 60)
{
return "yesterday";
}
if (delta < 30 * 24 * 60 * 60)
{
return ts.Days + " days ago";
}
if (delta < 12 * 30 * 24 * 60 * 60)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
建议?评论?如何改进此算法?
其他回答
public string getRelativeDateTime(DateTime date)
{
TimeSpan ts = DateTime.Now - date;
if (ts.TotalMinutes < 1)//seconds ago
return "just now";
if (ts.TotalHours < 1)//min ago
return (int)ts.TotalMinutes == 1 ? "1 Minute ago" : (int)ts.TotalMinutes + " Minutes ago";
if (ts.TotalDays < 1)//hours ago
return (int)ts.TotalHours == 1 ? "1 Hour ago" : (int)ts.TotalHours + " Hours ago";
if (ts.TotalDays < 7)//days ago
return (int)ts.TotalDays == 1 ? "1 Day ago" : (int)ts.TotalDays + " Days ago";
if (ts.TotalDays < 30.4368)//weeks ago
return (int)(ts.TotalDays / 7) == 1 ? "1 Week ago" : (int)(ts.TotalDays / 7) + " Weeks ago";
if (ts.TotalDays < 365.242)//months ago
return (int)(ts.TotalDays / 30.4368) == 1 ? "1 Month ago" : (int)(ts.TotalDays / 30.4368) + " Months ago";
//years ago
return (int)(ts.TotalDays / 365.242) == 1 ? "1 Year ago" : (int)(ts.TotalDays / 365.242) + " Years ago";
}
一个月和一年中的天数的转换值取自谷歌。
我是这样做的
var ts = new TimeSpan(DateTime.UtcNow.Ticks - dt.Ticks);
double delta = Math.Abs(ts.TotalSeconds);
if (delta < 60)
{
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
}
if (delta < 60 * 2)
{
return "a minute ago";
}
if (delta < 45 * 60)
{
return ts.Minutes + " minutes ago";
}
if (delta < 90 * 60)
{
return "an hour ago";
}
if (delta < 24 * 60 * 60)
{
return ts.Hours + " hours ago";
}
if (delta < 48 * 60 * 60)
{
return "yesterday";
}
if (delta < 30 * 24 * 60 * 60)
{
return ts.Days + " days ago";
}
if (delta < 12 * 30 * 24 * 60 * 60)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
建议?评论?如何改进此算法?
jquery.timeago插件
Jeff,因为Stack Overflow广泛使用jQuery,所以我建议使用jQuery.timeago插件。
优点:
即使页面是在10分钟前打开的,也不要使用“1分钟前”的时间戳;timeago自动刷新。您可以充分利用web应用程序中的页面和/或片段缓存,因为时间戳不是在服务器上计算的。你可以像酷孩子一样使用微格式。
只需将其附加到DOM就绪的时间戳:
jQuery(document).ready(function() {
jQuery('abbr.timeago').timeago();
});
这将在标题中使用timeago类和ISO 8601时间戳转换所有缩写元素:
<abbr class="timeago" title="2008-07-17T09:24:17Z">July 17, 2008</abbr>
变成这样:
<abbr class="timeago" title="July 17, 2008">4 months ago</abbr>
结果:4个月前。随着时间的推移,时间戳将自动更新。
免责声明:我写了这个插件,所以我有偏见。
通过在客户端执行此逻辑,可以减少服务器端负载。在一些Digg页面上查看源代码以供参考。它们让服务器发出一个由Javascript处理的历元时间值。这样,您就不需要管理最终用户的时区。新的服务器端代码类似于:
public string GetRelativeTime(DateTime timeStamp)
{
return string.Format("<script>printdate({0});</script>", timeStamp.ToFileTimeUtc());
}
您甚至可以在那里添加一个NOSCRIPT块,然后执行ToString()。
我的方法要简单得多。您可以根据需要调整返回字符串
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;
}