给定特定的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);
});
};
}
其他回答
/**
* {@code date1} has to be earlier than {@code date2}.
*/
public static String relativize(Date date1, Date date2) {
assert date2.getTime() >= date1.getTime();
long duration = date2.getTime() - date1.getTime();
long converted;
if ((converted = TimeUnit.MILLISECONDS.toDays(duration)) > 0) {
return String.format("%d %s ago", converted, converted == 1 ? "day" : "days");
} else if ((converted = TimeUnit.MILLISECONDS.toHours(duration)) > 0) {
return String.format("%d %s ago", converted, converted == 1 ? "hour" : "hours");
} else if ((converted = TimeUnit.MILLISECONDS.toMinutes(duration)) > 0) {
return String.format("%d %s ago", converted, converted == 1 ? "minute" : "minutes");
} else if ((converted = TimeUnit.MILLISECONDS.toSeconds(duration)) > 0) {
return String.format("%d %s ago", converted, converted == 1 ? "second" : "seconds");
} else {
return "just now";
}
}
在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";
} ?>
如果您想获得类似“2天4小时12分钟前”的输出,则需要一个时间跨度:
TimeSpan timeDiff = DateTime.Now-CreatedDate;
然后您可以访问您喜欢的值:
timeDiff.Days
timeDiff.Hours
等
您可以使用TimeAgo扩展,如下所示:
public static string TimeAgo(this DateTime dateTime)
{
string result = string.Empty;
var timeSpan = DateTime.Now.Subtract(dateTime);
if (timeSpan <= TimeSpan.FromSeconds(60))
{
result = string.Format("{0} seconds ago", timeSpan.Seconds);
}
else if (timeSpan <= TimeSpan.FromMinutes(60))
{
result = timeSpan.Minutes > 1 ?
String.Format("about {0} minutes ago", timeSpan.Minutes) :
"about a minute ago";
}
else if (timeSpan <= TimeSpan.FromHours(24))
{
result = timeSpan.Hours > 1 ?
String.Format("about {0} hours ago", timeSpan.Hours) :
"about an hour ago";
}
else if (timeSpan <= TimeSpan.FromDays(30))
{
result = timeSpan.Days > 1 ?
String.Format("about {0} days ago", timeSpan.Days) :
"yesterday";
}
else if (timeSpan <= TimeSpan.FromDays(365))
{
result = timeSpan.Days > 30 ?
String.Format("about {0} months ago", timeSpan.Days / 30) :
"about a month ago";
}
else
{
result = timeSpan.Days > 365 ?
String.Format("about {0} years ago", timeSpan.Days / 365) :
"about a year ago";
}
return result;
}
或者使用带有Timeago的Razor扩展的jQuery插件。
这里是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";
}
}