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

2小时前3天前一个月前


当前回答

这是我的功能,就像一个魅力:)

public static string RelativeDate(DateTime theDate)
{
   var span = DateTime.Now - theDate;
   if (span.Days > 365)
   {
      var years = (span.Days / 365);
      if (span.Days % 365 != 0)
         years += 1;
      return $"about {years} {(years == 1 ? "year" : "years")} ago";
   }
   if (span.Days > 30)
   {
      var months = (span.Days / 30);
      if (span.Days % 31 != 0)
         months += 1;
      return $"about {months} {(months == 1 ? "month" : "months")} ago";
   }
   if (span.Days > 0)
      return $"about {span.Days} {(span.Days == 1 ? "day" : "days")} ago";
   if (span.Hours > 0)
      return $"about {span.Hours} {(span.Hours == 1 ? "hour" : "hours")} ago";
   if (span.Minutes > 0)
      return $"about {span.Minutes} {(span.Minutes == 1 ? "minute" : "minutes")} ago";
   if (span.Seconds > 5)
      return $"about {span.Seconds} seconds ago";

   return span.Seconds <= 5 ? "about 5 seconds ago" : string.Empty;
}

其他回答

/** 
 * {@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";
    }
}

我是这样做的

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";

建议?评论?如何改进此算法?

在Java中有没有一种简单的方法可以做到这一点?java.util.Date类似乎相当有限。

下面是我的快速而肮脏的Java解决方案:

import java.util.Date;
import javax.management.timer.Timer;

String getRelativeDate(Date date) {     
  long delta = new Date().getTime() - date.getTime();
  if (delta < 1L * Timer.ONE_MINUTE) {
    return toSeconds(delta) == 1 ? "one second ago" : toSeconds(delta) + " seconds ago";
  }
  if (delta < 2L * Timer.ONE_MINUTE) {
    return "a minute ago";
  }
  if (delta < 45L * Timer.ONE_MINUTE) {
    return toMinutes(delta) + " minutes ago";
  }
  if (delta < 90L * Timer.ONE_MINUTE) {
    return "an hour ago";
  }
  if (delta < 24L * Timer.ONE_HOUR) {
    return toHours(delta) + " hours ago";
  }
  if (delta < 48L * Timer.ONE_HOUR) {
    return "yesterday";
  }
  if (delta < 30L * Timer.ONE_DAY) {
    return toDays(delta) + " days ago";
  }
  if (delta < 12L * 4L * Timer.ONE_WEEK) { // a month
    long months = toMonths(delta); 
    return months <= 1 ? "one month ago" : months + " months ago";
  }
  else {
    long years = toYears(delta);
    return years <= 1 ? "one year ago" : years + " years ago";
  }
}

private long toSeconds(long date) {
  return date / 1000L;
}

private long toMinutes(long date) {
  return toSeconds(date) / 60L;
}

private long toHours(long date) {
  return toMinutes(date) / 60L;
}

private long toDays(long date) {
  return toHours(date) / 24L;
}

private long toMonths(long date) {
  return toDays(date) / 30L;
}

private long toYears(long date) {
  return toMonths(date) / 365L;
}
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";
}

一个月和一年中的天数的转换值取自谷歌。

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];
    }
}