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

2小时前3天前一个月前


当前回答

在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

var ts = new TimeSpan(DateTime.Now.Ticks - dt.Ticks);
public static string ToRelativeDate(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";
    }

    var aValue = new SortedList<double, Func<string>>();
    aValue.Add(0.75, () => "less than a minute");
    aValue.Add(1.5, () => "about a minute");
    aValue.Add(45, () => string.Format("{0} minutes", Math.Round(TotalMinutes)));
    aValue.Add(90, () => "about an hour");
    aValue.Add(1440, () => string.Format("about {0} hours", Math.Round(Math.Abs(oSpan.TotalHours)))); // 60 * 24
    aValue.Add(2880, () => "a day"); // 60 * 48
    aValue.Add(43200, () => string.Format("{0} days", Math.Floor(Math.Abs(oSpan.TotalDays)))); // 60 * 24 * 30
    aValue.Add(86400, () => "about a month"); // 60 * 24 * 60
    aValue.Add(525600, () => string.Format("{0} months", Math.Floor(Math.Abs(oSpan.TotalDays / 30)))); // 60 * 24 * 365 
    aValue.Add(1051200, () => "about a year"); // 60 * 24 * 365 * 2
    aValue.Add(double.MaxValue, () => string.Format("{0} years", Math.Floor(Math.Abs(oSpan.TotalDays / 365))));

    return aValue.First(n => TotalMinutes < n.Key).Value.Invoke() + Suffix;
}

http://refactormycode.com/codes/493-twitter-esque-relative-dates

C#6版本:

static readonly SortedList<double, Func<TimeSpan, string>> offsets = 
   new SortedList<double, Func<TimeSpan, string>>
{
    { 0.75, _ => "less than a minute"},
    { 1.5, _ => "about a minute"},
    { 45, x => $"{x.TotalMinutes:F0} minutes"},
    { 90, x => "about an hour"},
    { 1440, x => $"about {x.TotalHours:F0} hours"},
    { 2880, x => "a day"},
    { 43200, x => $"{x.TotalDays:F0} days"},
    { 86400, x => "about a month"},
    { 525600, x => $"{x.TotalDays / 30:F0} months"},
    { 1051200, x => "about a year"},
    { double.MaxValue, x => $"{x.TotalDays / 365:F0} years"}
};

public static string ToRelativeDate(this DateTime input)
{
    TimeSpan x = DateTime.Now - input;
    string Suffix = x.TotalMinutes > 0 ? " ago" : " from now";
    x = new TimeSpan(Math.Abs(x.Ticks));
    return offsets.First(n => x.TotalMinutes < n.Key).Value(x) + Suffix;
}

我将为此提供一些方便的扩展方法,并使代码更可读。首先,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

我认为已经有很多关于这篇文章的答案了,但你可以使用它,它就像插件一样容易使用,程序员也很容易阅读。发送您的特定日期,并以字符串形式获取其值:

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