给定特定的DateTime值,如何显示相对时间,例如:
2小时前3天前一个月前
给定特定的DateTime值,如何显示相对时间,例如:
2小时前3天前一个月前
当前回答
iPhone Objective-C版本
+ (NSString *)timeAgoString:(NSDate *)date {
int delta = -(int)[date timeIntervalSinceNow];
if (delta < 60)
{
return delta == 1 ? @"one second ago" : [NSString stringWithFormat:@"%i seconds ago", delta];
}
if (delta < 120)
{
return @"a minute ago";
}
if (delta < 2700)
{
return [NSString stringWithFormat:@"%i minutes ago", delta/60];
}
if (delta < 5400)
{
return @"an hour ago";
}
if (delta < 24 * 3600)
{
return [NSString stringWithFormat:@"%i hours ago", delta/3600];
}
if (delta < 48 * 3600)
{
return @"yesterday";
}
if (delta < 30 * 24 * 3600)
{
return [NSString stringWithFormat:@"%i days ago", delta/(24*3600)];
}
if (delta < 12 * 30 * 24 * 3600)
{
int months = delta/(30*24*3600);
return months <= 1 ? @"one month ago" : [NSString stringWithFormat:@"%i months ago", months];
}
else
{
int years = delta/(12*30*24*3600);
return years <= 1 ? @"one year ago" : [NSString stringWithFormat:@"%i years ago", years];
}
}
其他回答
在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";
} ?>
下面是我作为DateTime类的扩展方法添加的一个实现,它处理未来和过去的日期,并提供了一个近似选项,允许您指定要查找的详细程度(“3小时前”与“3小时、23分钟、12秒前”):
using System.Text;
/// <summary>
/// Compares a supplied date to the current date and generates a friendly English
/// comparison ("5 days ago", "5 days from now")
/// </summary>
/// <param name="date">The date to convert</param>
/// <param name="approximate">When off, calculate timespan down to the second.
/// When on, approximate to the largest round unit of time.</param>
/// <returns></returns>
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();
}
使用解构主义和Linq得到“n(最大时间单位)前”的“一行”:
TimeSpan timeSpan = DateTime.Now - new DateTime(1234, 5, 6, 7, 8, 9);
(string unit, int value) = new Dictionary<string, int>
{
{"year(s)", (int)(timeSpan.TotalDays / 365.25)}, //https://en.wikipedia.org/wiki/Year#Intercalation
{"month(s)", (int)(timeSpan.TotalDays / 29.53)}, //https://en.wikipedia.org/wiki/Month
{"day(s)", (int)timeSpan.TotalDays},
{"hour(s)", (int)timeSpan.TotalHours},
{"minute(s)", (int)timeSpan.TotalMinutes},
{"second(s)", (int)timeSpan.TotalSeconds},
{"millisecond(s)", (int)timeSpan.TotalMilliseconds}
}.First(kvp => kvp.Value > 0);
Console.WriteLine($"{value} {unit} ago");
你在786年前
当前年份和月份,如
TimeSpan timeSpan = DateTime.Now - new DateTime(2020, 12, 6, 7, 8, 9);
您4天前收到
实际日期,比如
TimeSpan timeSpan = DateTime.Now - DateTime.Now.Date;
9小时前到达
我认为已经有很多关于这篇文章的答案了,但你可以使用它,它就像插件一样容易使用,程序员也很容易阅读。发送您的特定日期,并以字符串形式获取其值:
public string RelativeDateTimeCount(DateTime inputDateTime)
{
string outputDateTime = string.Empty;
TimeSpan ts = DateTime.Now - inputDateTime;
if (ts.Days > 7)
{ outputDateTime = inputDateTime.ToString("MMMM d, yyyy"); }
else if (ts.Days > 0)
{
outputDateTime = ts.Days == 1 ? ("about 1 Day ago") : ("about " + ts.Days.ToString() + " Days ago");
}
else if (ts.Hours > 0)
{
outputDateTime = ts.Hours == 1 ? ("an hour ago") : (ts.Hours.ToString() + " hours ago");
}
else if (ts.Minutes > 0)
{
outputDateTime = ts.Minutes == 1 ? ("1 minute ago") : (ts.Minutes.ToString() + " minutes ago");
}
else outputDateTime = "few seconds ago";
return outputDateTime;
}
using System;
using System.Collections.Generic;
using System.Linq;
public static class RelativeDateHelper
{
private static Dictionary<double, Func<double, string>> sm_Dict = null;
private static Dictionary<double, Func<double, string>> DictionarySetup()
{
var dict = new Dictionary<double, Func<double, string>>();
dict.Add(0.75, (mins) => "less than a minute");
dict.Add(1.5, (mins) => "about a minute");
dict.Add(45, (mins) => string.Format("{0} minutes", Math.Round(mins)));
dict.Add(90, (mins) => "about an hour");
dict.Add(1440, (mins) => string.Format("about {0} hours", Math.Round(Math.Abs(mins / 60)))); // 60 * 24
dict.Add(2880, (mins) => "a day"); // 60 * 48
dict.Add(43200, (mins) => string.Format("{0} days", Math.Floor(Math.Abs(mins / 1440)))); // 60 * 24 * 30
dict.Add(86400, (mins) => "about a month"); // 60 * 24 * 60
dict.Add(525600, (mins) => string.Format("{0} months", Math.Floor(Math.Abs(mins / 43200)))); // 60 * 24 * 365
dict.Add(1051200, (mins) => "about a year"); // 60 * 24 * 365 * 2
dict.Add(double.MaxValue, (mins) => string.Format("{0} years", Math.Floor(Math.Abs(mins / 525600))));
return dict;
}
public static string ToRelativeDate(this DateTime input)
{
TimeSpan oSpan = DateTime.Now.Subtract(input);
double TotalMinutes = oSpan.TotalMinutes;
string Suffix = " ago";
if (TotalMinutes < 0.0)
{
TotalMinutes = Math.Abs(TotalMinutes);
Suffix = " from now";
}
if (null == sm_Dict)
sm_Dict = DictionarySetup();
return sm_Dict.First(n => TotalMinutes < n.Key).Value.Invoke(TotalMinutes) + Suffix;
}
}
与此问题的另一个答案相同,但作为静态字典的扩展方法。