给定特定的DateTime值,如何显示相对时间,例如:
2小时前3天前一个月前
给定特定的DateTime值,如何显示相对时间,例如:
2小时前3天前一个月前
当前回答
我也建议在客户端进行计算。服务器工作更少。
以下是我使用的版本(来自Zach Leatherman)
/*
* Javascript Humane Dates
* Copyright (c) 2008 Dean Landolt (deanlandolt.com)
* Re-write by Zach Leatherman (zachleat.com)
*
* Adopted from the John Resig's pretty.js
* at http://ejohn.org/blog/javascript-pretty-date
* and henrah's proposed modification
* at http://ejohn.org/blog/javascript-pretty-date/#comment-297458
*
* Licensed under the MIT license.
*/
function humane_date(date_str){
var time_formats = [
[60, 'just now'],
[90, '1 minute'], // 60*1.5
[3600, 'minutes', 60], // 60*60, 60
[5400, '1 hour'], // 60*60*1.5
[86400, 'hours', 3600], // 60*60*24, 60*60
[129600, '1 day'], // 60*60*24*1.5
[604800, 'days', 86400], // 60*60*24*7, 60*60*24
[907200, '1 week'], // 60*60*24*7*1.5
[2628000, 'weeks', 604800], // 60*60*24*(365/12), 60*60*24*7
[3942000, '1 month'], // 60*60*24*(365/12)*1.5
[31536000, 'months', 2628000], // 60*60*24*365, 60*60*24*(365/12)
[47304000, '1 year'], // 60*60*24*365*1.5
[3153600000, 'years', 31536000], // 60*60*24*365*100, 60*60*24*365
[4730400000, '1 century'] // 60*60*24*365*100*1.5
];
var time = ('' + date_str).replace(/-/g,"/").replace(/[TZ]/g," "),
dt = new Date,
seconds = ((dt - new Date(time) + (dt.getTimezoneOffset() * 60000)) / 1000),
token = ' ago',
i = 0,
format;
if (seconds < 0) {
seconds = Math.abs(seconds);
token = '';
}
while (format = time_formats[i++]) {
if (seconds < format[0]) {
if (format.length == 2) {
return format[1] + (i > 1 ? token : ''); // Conditional so we don't return Just Now Ago
} else {
return Math.round(seconds / format[2]) + ' ' + format[1] + (i > 1 ? token : '');
}
}
}
// overflow for centuries
if(seconds > 4730400000)
return Math.round(seconds / 4730400000) + ' centuries' + token;
return date_str;
};
if(typeof jQuery != 'undefined') {
jQuery.fn.humane_dates = function(){
return this.each(function(){
var date = humane_date(this.title);
if(date && jQuery(this).text() != date) // don't modify the dom if we don't have to
jQuery(this).text(date);
});
};
}
其他回答
这是stackoverflow使用的算法,但使用了错误修复(没有“一小时前”)的perlish伪代码进行了更简洁的重写。该函数在秒前取一个(正数),并返回一个人类友好的字符串,如“3小时前”或“昨天”。
agoify($delta)
local($y, $mo, $d, $h, $m, $s);
$s = floor($delta);
if($s<=1) return "a second ago";
if($s<60) return "$s seconds ago";
$m = floor($s/60);
if($m==1) return "a minute ago";
if($m<45) return "$m minutes ago";
$h = floor($m/60);
if($h==1) return "an hour ago";
if($h<24) return "$h hours ago";
$d = floor($h/24);
if($d<2) return "yesterday";
if($d<30) return "$d days ago";
$mo = floor($d/30);
if($mo<=1) return "a month ago";
$y = floor($mo/12);
if($y<1) return "$mo months ago";
if($y==1) return "a year ago";
return "$y years ago";
@杰夫
var ts=新时间跨度(DateTime.UtcNow.Ticks-dt.Ticks);
对DateTime执行减法仍会返回TimeSpan。
所以你可以这样做
(DateTime.UtcNow - dt).TotalSeconds
我也很惊讶地看到常数用手相乘,然后注释加上乘法。这是错误的优化吗?
在PHP中,我是这样做的:
<?php
function timesince($original) {
// array of time period chunks
$chunks = array(
array(60 * 60 * 24 * 365 , 'year'),
array(60 * 60 * 24 * 30 , 'month'),
array(60 * 60 * 24 * 7, 'week'),
array(60 * 60 * 24 , 'day'),
array(60 * 60 , 'hour'),
array(60 , 'minute'),
);
$today = time(); /* Current unix time */
$since = $today - $original;
if($since > 604800) {
$print = date("M jS", $original);
if($since > 31536000) {
$print .= ", " . date("Y", $original);
}
return $print;
}
// $j saves performing the count function each time around the loop
for ($i = 0, $j = count($chunks); $i < $j; $i++) {
$seconds = $chunks[$i][0];
$name = $chunks[$i][1];
// finding the biggest chunk (if the chunk fits, break)
if (($count = floor($since / $seconds)) != 0) {
break;
}
}
$print = ($count == 1) ? '1 '.$name : "$count {$name}s";
return $print . " ago";
} ?>
var ts = new TimeSpan(DateTime.Now.Ticks - dt.Ticks);
我将为此提供一些方便的扩展方法,并使代码更可读。首先,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