Вычислить относительное время в C#

Учитывая конкретное значение DateTime, как мне отобразить 9X_time относительное время, например:

  • 2 часа назад
  • 3 дня назад
  • месяц назад

1635
3

  • moment.js - очень хорошая библиотека для анализа дат. Вы можете рассмотреть возможность ее использования (на стороне сервера или на стороне клиента), в зависимости от ваши ...
38
Общее количество ответов: 38

Ответ #1

Ответ на вопрос: Вычислить относительное время в C#

Джефф, your code — это хорошо, но может быть понятнее 9X_relative-time-span с константами (как предлагается в Code Complete).

const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;

var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
double delta = Math.Abs(ts.TotalSeconds);

if (delta < 1 * MINUTE)
  return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";

if (delta < 2 * MINUTE)
  return "a minute ago";

if (delta < 45 * MINUTE)
  return ts.Minutes + " minutes ago";

if (delta < 90 * MINUTE)
  return "an hour ago";

if (delta < 24 * HOUR)
  return ts.Hours + " hours ago";

if (delta < 48 * HOUR)
  return "yesterday";

if (delta < 30 * DAY)
  return ts.Days + " days ago";

if (delta < 12 * MONTH)
{
  int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
  return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
  int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
  return years <= 1 ? "one year ago" : years + " years ago";
}

1065
12

  • @nick Если вы поместите это в IValueConverter, он автоматически обработает CultureInfo (при условии, что вы сначала установ ...

Ответ #2

Ответ на вопрос: Вычислить относительное время в C#

jquery.timeago plugin

Джефф, поскольку Stack Overflow широко использует 9X_visual-c# jQuery, я рекомендую jquery.timeago plugin.

Преимущества:

  • Избегайте меток времени, датированных «1 минуту назад», даже если страница была открыта 10 минут назад; время назад обновляется автоматически.
  • Вы можете в полной мере воспользоваться преимуществами кэширования страниц и/или фрагментов в своих веб-приложениях, поскольку метки времени не рассчитываются на сервере.
  • Вы можете использовать микроформаты, как крутые дети.

Просто 9X_relative-time-span прикрепите его к своим временным меткам 9X_csharp в DOM:

jQuery(document).ready(function() {
    jQuery('abbr.timeago').timeago();
});

Это превратит все элементы abbr с классом 9X_c-sharp timeago и отметкой времени ISO 8601 в заголовке:

July 17, 2008

во 9X_visual-c# что-то вроде этого:

4 months ago

что дает: 4 месяца назад. По 9X_c-sharp прошествии времени метки времени будут автоматически 9X_c#.net обновляться.

Отказ от ответственности: я написал этот плагин, поэтому я предвзят.

370
8

  • @RyanMcGeary: Вероятно, это неправильное место, чтобы спросить, но у меня есть вопрос об использовании TimeAgo. Я нахожусь в Великобритании (GMT, включая DST), и даты, хранящиеся в моей базе данных, - это UTC. ...

Ответ #3

Ответ на вопрос: Вычислить относительное время в C#

Вот как я это делаю

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

Предложения? Комментарии? Как 9X_c-sharp улучшить этот алгоритм?

347
9

  • Но в настоящее время SO показывает только формат «Время назад» до 2 дней. Бо ...

Ответ #4

Ответ на вопрос: Вычислить относительное время в C#

public static string RelativeDate(DateTime theDate)
{
    Dictionary thresholds = new Dictionary();
    int minute = 60;
    int hour = 60 * minute;
    int day = 24 * hour;
    thresholds.Add(60, "{0} seconds ago");
    thresholds.Add(minute * 2, "a minute ago");
    thresholds.Add(45 * minute, "{0} minutes ago");
    thresholds.Add(120 * minute, "an hour ago");
    thresholds.Add(day, "{0} hours ago");
    thresholds.Add(day * 2, "yesterday");
    thresholds.Add(day * 30, "{0} days ago");
    thresholds.Add(day * 365, "{0} months ago");
    thresholds.Add(long.MaxValue, "{0} years ago");
    long since = (DateTime.Now.Ticks - theDate.Ticks) / 10000000;
    foreach (long threshold in thresholds.Keys) 
    {
        if (since < threshold) 
        {
            TimeSpan t = new TimeSpan((DateTime.Now.Ticks - theDate.Ticks));
            return string.Format(thresholds[threshold], (t.Days > 365 ? t.Days / 365 : (t.Days > 0 ? t.Days : (t.Hours > 0 ? t.Hours : (t.Minutes > 0 ? t.Minutes : (t.Seconds > 0 ? t.Seconds : 0))))).ToString());
        }
    }
    return "";
}

Я предпочитаю эту версию из-за ее лаконичности 9X_datetime-functions и возможности добавления новых контрольных 9X_datetime-operation точек. Это можно было бы инкапсулировать 9X_datediff с расширением Latest() для Timespan вместо длинной 9X_c# строки 1, но для краткости постинга этого 9X_visual-c# вполне достаточно. Это исправляет час назад, 1 час назад, предоставляя час до истечения 2 часов

99
1

  • Хм, хотя этот код может работать, неверно и недействительно предполагать, что порядок ключей в Словаре будет в определенном порядке. Словарь использует Object.GetHashCode(), который возвращает не long, а int !. Если вы хотите, чтобы они б ...

Ответ #5

Ответ на вопрос: Вычислить относительное время в C#

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>();
    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

Версия С# 6:

static readonly SortedList> offsets = 
   new SortedList>
{
    { 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;
}

9X_relative-time-span

75
1

  • Вы, вероятно, захотите вытащить этот словарь в поле, чтобы уменьшить создание экземпляров и отток сборщика мусора. Вам нужно будет изменить `Func <string>` на `Func <double>`.</ ...

Ответ #6

Ответ на вопрос: Вычислить относительное время в C#

Вот перепись из скрипта Джеффа для 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";
    }
}    

9X_datetime-functions

73
1

  • Вопрос: *** C# tagged *** Почему *** PHP code ***?<p>< ...

Ответ #7

Ответ на вопрос: Вычислить относительное время в C#

Вот реализация, которую я добавил в качестве 9X_visual-c# метода расширения к классу DateTime, который 9X_c#-language обрабатывает как будущие, так и прошлые 9X_.cs-file даты и предоставляет опцию аппроксимации, которая 9X_c#.net позволяет вам указать уровень детализации, который 9X_c# вы ищете («3 часа назад» против » 3 часа 9X_datetime 23 минуты 12 секунд назад »):

using System.Text;

/// 
/// Compares a supplied date to the current date and generates a friendly English 
/// comparison ("5 days ago", "5 days from now")
/// 
/// The date to convert
/// When off, calculate timespan down to the second.
/// When on, approximate to the largest round unit of time.
/// 
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();
}

54
0

Ответ #8

Ответ на вопрос: Вычислить относительное время в C#

На Nuget также есть пакет под названием 9X_c# Humanizr, он действительно хорошо работает и находится 9X_time в .NET Foundation.

DateTime.UtcNow.AddHours(-30).Humanize() => "yesterday"
DateTime.UtcNow.AddHours(-2).Humanize() => "2 hours ago"

DateTime.UtcNow.AddHours(30).Humanize() => "tomorrow"
DateTime.UtcNow.AddHours(2).Humanize() => "2 hours from now"

TimeSpan.FromMilliseconds(1299630020).Humanize() => "2 weeks"
TimeSpan.FromMilliseconds(1299630020).Humanize(3) => "2 weeks, 1 day, 1 hour"

Скотт Хансельман написал 9X_c# об этом на своем blog

47
1

  • дружеское примечание: на .net 4.5 или выше не устанавливайте полный Humani ...

Ответ #9

Ответ на вопрос: Вычислить относительное время в C#

Я бы порекомендовал вычислить это и на стороне 9X_c-sharp клиента. Меньше работы на сервере.

Следующая 9X_c#-language версия, которую я использую (от Зака ​​Лезермана)

/*
 * 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);
                });
        };
}

38
1

  • Вопрос: *** C# tag ...

Ответ #10

Ответ на вопрос: Вычислить относительное время в C#

@джефф

ИМХО ваш кажется длинноватым. Однако 9X_c#-language он кажется немного более надежным с поддержкой 9X_relative-time-span «вчера» и «лет». Но по моему опыту, когда 9X_visual-c# это используется, человек, скорее всего, просматривает 9X_visual-c# контент в первые 30 дней. После этого приходят 9X_datediff только действительно хардкорные люди. Итак, я 9X_csharp обычно предпочитаю говорить кратко и просто.

Это 9X_datetime-operation метод, который я сейчас использую на одном 9X_datetime из своих веб-сайтов. Это возвращает только 9X_c#-language относительный день, час и время. И тогда 9X_time пользователь должен нажать «назад» в выводе.

public static string ToLongString(this TimeSpan time)
{
    string output = String.Empty;

    if (time.Days > 0)
        output += time.Days + " days ";

    if ((time.Days == 0 || time.Days == 1) && time.Hours > 0)
        output += time.Hours + " hr ";

    if (time.Days == 0 && time.Minutes > 0)
        output += time.Minutes + " min ";

    if (output.Length == 0)
        output += time.Seconds + " sec";

    return output.Trim();
}

35
0

Ответ #11

Ответ на вопрос: Вычислить относительное время в C#

На вечеринку опоздал на пару лет, но у меня 9X_datetime было требование сделать это как в прошлом, так 9X_c#-language и в будущем, поэтому я объединил в нем теги 9X_datetime Jeff и Vincent's. Это тройная феерия! :)

public static class DateTimeHelper
    {
        private const int SECOND = 1;
        private const int MINUTE = 60 * SECOND;
        private const int HOUR = 60 * MINUTE;
        private const int DAY = 24 * HOUR;
        private const int MONTH = 30 * DAY;

        /// 
        /// Returns a friendly version of the provided DateTime, relative to now. E.g.: "2 days ago", or "in 6 months".
        /// 
        /// The DateTime to compare to Now
        /// A friendly string
        public static string GetFriendlyRelativeTime(DateTime dateTime)
        {
            if (DateTime.UtcNow.Ticks == dateTime.Ticks)
            {
                return "Right now!";
            }

            bool isFuture = (DateTime.UtcNow.Ticks < dateTime.Ticks);
            var ts = DateTime.UtcNow.Ticks < dateTime.Ticks ? new TimeSpan(dateTime.Ticks - DateTime.UtcNow.Ticks) : new TimeSpan(DateTime.UtcNow.Ticks - dateTime.Ticks);

            double delta = ts.TotalSeconds;

            if (delta < 1 * MINUTE)
            {
                return isFuture ? "in " + (ts.Seconds == 1 ? "one second" : ts.Seconds + " seconds") : ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
            }
            if (delta < 2 * MINUTE)
            {
                return isFuture ? "in a minute" : "a minute ago";
            }
            if (delta < 45 * MINUTE)
            {
                return isFuture ? "in " + ts.Minutes + " minutes" : ts.Minutes + " minutes ago";
            }
            if (delta < 90 * MINUTE)
            {
                return isFuture ? "in an hour" : "an hour ago";
            }
            if (delta < 24 * HOUR)
            {
                return isFuture ? "in " + ts.Hours + " hours" : ts.Hours + " hours ago";
            }
            if (delta < 48 * HOUR)
            {
                return isFuture ? "tomorrow" : "yesterday";
            }
            if (delta < 30 * DAY)
            {
                return isFuture ? "in " + ts.Days + " days" : ts.Days + " days ago";
            }
            if (delta < 12 * MONTH)
            {
                int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
                return isFuture ? "in " + (months <= 1 ? "one month" : months + " months") : months <= 1 ? "one month ago" : months + " months ago";
            }
            else
            {
                int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
                return isFuture ? "in " + (years <= 1 ? "one year" : years + " years") : years <= 1 ? "one year ago" : years + " years ago";
            }
        }
    }

26
0

Ответ #12

Ответ на вопрос: Вычислить относительное время в C#

Учитывая, что мир и ее муж, похоже, публикуют 9X_c# образцы кода, вот что я написал некоторое 9X_csharp время назад на основе пары этих ответов.

У 9X_datetime-manipulation меня была особая потребность в локализации 9X_datetime этого кода. Итак, у меня есть два класса 9X_datediff - Grammar, который определяет локализуемые термины, и 9X_datetime-functions FuzzyDateExtensions, который содержит набор методов расширения. У 9X_c#.net меня не было необходимости иметь дело с 9X_datetime-manipulation будущими датами, поэтому я не пытаюсь справиться 9X_datetime с ними с помощью этого кода.

Я оставил часть 9X_time XMLdoc в источнике, но удалил большую часть 9X_c# (там, где они были бы очевидны) для краткости. Я 9X_c-sharp также не включил сюда всех учеников:

public class Grammar
{
    ///  Gets or sets the term for "just now". 
    public string JustNow { get; set; }
    ///  Gets or sets the term for "X minutes ago". 
    /// 
    ///     This is a  pattern, where {0}
    ///     is the number of minutes.
    /// 
    public string MinutesAgo { get; set; }
    public string OneHourAgo { get; set; }
    public string HoursAgo { get; set; }
    public string Yesterday { get; set; }
    public string DaysAgo { get; set; }
    public string LastMonth { get; set; }
    public string MonthsAgo { get; set; }
    public string LastYear { get; set; }
    public string YearsAgo { get; set; }
    ///  Gets or sets the term for "ages ago". 
    public string AgesAgo { get; set; }

    /// 
    ///     Gets or sets the threshold beyond which the fuzzy date should be
    ///     considered "ages ago".
    /// 
    public TimeSpan AgesAgoThreshold { get; set; }

    /// 
    ///     Initialises a new  instance with the
    ///     specified properties.
    /// 
    private void Initialise(string justNow, string minutesAgo,
        string oneHourAgo, string hoursAgo, string yesterday, string daysAgo,
        string lastMonth, string monthsAgo, string lastYear, string yearsAgo,
        string agesAgo, TimeSpan agesAgoThreshold)
    { ... }
}

Класс 9X_datetime-operation FuzzyDateString содержит:

public static class FuzzyDateExtensions
{
    public static string ToFuzzyDateString(this TimeSpan timespan)
    {
        return timespan.ToFuzzyDateString(new Grammar());
    }

    public static string ToFuzzyDateString(this TimeSpan timespan,
        Grammar grammar)
    {
        return GetFuzzyDateString(timespan, grammar);
    }

    public static string ToFuzzyDateString(this DateTime datetime)
    {
        return (DateTime.Now - datetime).ToFuzzyDateString();
    }

    public static string ToFuzzyDateString(this DateTime datetime,
       Grammar grammar)
    {
        return (DateTime.Now - datetime).ToFuzzyDateString(grammar);
    }


    private static string GetFuzzyDateString(TimeSpan timespan,
       Grammar grammar)
    {
        timespan = timespan.Duration();

        if (timespan >= grammar.AgesAgoThreshold)
        {
            return grammar.AgesAgo;
        }

        if (timespan < new TimeSpan(0, 2, 0))    // 2 minutes
        {
            return grammar.JustNow;
        }

        if (timespan < new TimeSpan(1, 0, 0))    // 1 hour
        {
            return String.Format(grammar.MinutesAgo, timespan.Minutes);
        }

        if (timespan < new TimeSpan(1, 55, 0))    // 1 hour 55 minutes
        {
            return grammar.OneHourAgo;
        }

        if (timespan < new TimeSpan(12, 0, 0)    // 12 hours
            && (DateTime.Now - timespan).IsToday())
        {
            return String.Format(grammar.HoursAgo, timespan.RoundedHours());
        }

        if ((DateTime.Now.AddDays(1) - timespan).IsToday())
        {
            return grammar.Yesterday;
        }

        if (timespan < new TimeSpan(32, 0, 0, 0)    // 32 days
            && (DateTime.Now - timespan).IsThisMonth())
        {
            return String.Format(grammar.DaysAgo, timespan.RoundedDays());
        }

        if ((DateTime.Now.AddMonths(1) - timespan).IsThisMonth())
        {
            return grammar.LastMonth;
        }

        if (timespan < new TimeSpan(365, 0, 0, 0, 0)    // 365 days
            && (DateTime.Now - timespan).IsThisYear())
        {
            return String.Format(grammar.MonthsAgo, timespan.RoundedMonths());
        }

        if ((DateTime.Now - timespan).AddYears(1).IsThisYear())
        {
            return grammar.LastYear;
        }

        return String.Format(grammar.YearsAgo, timespan.RoundedYears());
    }
}

Одной из ключевых вещей, которых 9X_.cs-file я хотел достичь, помимо локализации, было 9X_datetime-functions то, что «сегодня» будет означать только 9X_c-sharp «этот календарный день», поэтому методы 9X_datediff IsToday, IsThisMonth, IsThisYear выглядят следующим образом:

public static bool IsToday(this DateTime date)
{
    return date.DayOfYear == DateTime.Now.DayOfYear && date.IsThisYear();
}

и методы 9X_c-sharp округления выглядят следующим образом (я 9X_datetime-manipulation включил RoundedMonths, поскольку он немного отличается):

public static int RoundedDays(this TimeSpan timespan)
{
    return (timespan.Hours > 12) ? timespan.Days + 1 : timespan.Days;
}

public static int RoundedMonths(this TimeSpan timespan)
{
    DateTime then = DateTime.Now - timespan;

    // Number of partial months elapsed since 1 Jan, AD 1 (DateTime.MinValue)
    int nowMonthYears = DateTime.Now.Year * 12 + DateTime.Now.Month;
    int thenMonthYears = then.Year * 12 + then.Month;                    

    return nowMonthYears - thenMonthYears;
}

Надеюсь, людям 9X_datediff это будет полезно и / или интересно: o)

21
0

Ответ #13

Ответ на вопрос: Вычислить относительное время в C#

используя Fluent DateTime

var dateTime1 = 2.Hours().Ago();
var dateTime2 = 3.Days().Ago();
var dateTime3 = 1.Months().Ago();
var dateTime4 = 5.Hours().FromNow();
var dateTime5 = 2.Weeks().FromNow();
var dateTime6 = 40.Seconds().FromNow();

9X_datetime-manipulation

21
0

Ответ #14

Ответ на вопрос: Вычислить относительное время в C#

Есть ли простой способ сделать это на Java? Класс 9X_.cs-file java.util.Date кажется довольно ограниченным.

Вот мое быстрое 9X_datediff и грязное решение для 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;
}

20
1

  • Вопрос: *** C# tagged *** ...

Ответ #15

Ответ на вопрос: Вычислить относительное время в C#

Версия для 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];
    }
}

9X_time

20
0

Ответ #16

Ответ на вопрос: Вычислить относительное время в C#

Я решил попробовать, используя классы и 9X_c#-language полиморфизм. У меня была предыдущая итерация, в 9X_datetime-operation которой использовалось подклассирование, что 9X_c#-language привело к слишком большим накладным расходам. Я 9X_datetime-operation переключился на более гибкую объектную модель 9X_datediff делегата/публичного имущества, которая значительно 9X_relative-time-span лучше. Мой код немного более точен, я хотел 9X_csharp бы придумать лучший способ генерировать 9X_datetime-manipulation «месяцы назад», который не казался слишком 9X_relative-time-span сложным.

Думаю, я бы по-прежнему придерживался 9X_c#.net каскада «если-то» Джеффа, потому что в нем 9X_c#.net меньше кода и он проще (определенно проще 9X_datetime убедиться, что он будет работать должным 9X_datetime-functions образом).

Для приведенного ниже кода PrintRelativeTime.GetRelativeTimeMessage(TimeSpan ago) возвращает 9X_time сообщение относительного времени (например, «вчера»).

public class RelativeTimeRange : IComparable
{
    public TimeSpan UpperBound { get; set; }

    public delegate string RelativeTimeTextDelegate(TimeSpan timeDelta);

    public RelativeTimeTextDelegate MessageCreator { get; set; }

    public int CompareTo(object obj)
    {
        if (!(obj is RelativeTimeRange))
        {
            return 1;
        }
        // note that this sorts in reverse order to the way you'd expect, 
        // this saves having to reverse a list later
        return (obj as RelativeTimeRange).UpperBound.CompareTo(UpperBound);
    }
}

public class PrintRelativeTime
{
    private static List timeRanges;

    static PrintRelativeTime()
    {
        timeRanges = new List{
            new RelativeTimeRange
            {
                UpperBound = TimeSpan.FromSeconds(1),
                MessageCreator = (delta) => 
                { return "one second ago"; }
            }, 
            new RelativeTimeRange
            {
                UpperBound = TimeSpan.FromSeconds(60),
                MessageCreator = (delta) => 
                { return delta.Seconds + " seconds ago"; }

            }, 
            new RelativeTimeRange
            {
                UpperBound = TimeSpan.FromMinutes(2),
                MessageCreator = (delta) => 
                { return "one minute ago"; }
            }, 
            new RelativeTimeRange
            {
                UpperBound = TimeSpan.FromMinutes(60),
                MessageCreator = (delta) => 
                { return delta.Minutes + " minutes ago"; }
            }, 
            new RelativeTimeRange
            {
                UpperBound = TimeSpan.FromHours(2),
                MessageCreator = (delta) => 
                { return "one hour ago"; }
            }, 
            new RelativeTimeRange
            {
                UpperBound = TimeSpan.FromHours(24),
                MessageCreator = (delta) => 
                { return delta.Hours + " hours ago"; }
            }, 
            new RelativeTimeRange
            {
                UpperBound = TimeSpan.FromDays(2),
                MessageCreator = (delta) => 
                { return "yesterday"; }
            }, 
            new RelativeTimeRange
            {
                UpperBound = DateTime.Now.Subtract(DateTime.Now.AddMonths(-1)),
                MessageCreator = (delta) => 
                { return delta.Days + " days ago"; }
            }, 
            new RelativeTimeRange
            {
                UpperBound = DateTime.Now.Subtract(DateTime.Now.AddMonths(-2)),
                MessageCreator = (delta) => 
                { return "one month ago"; }
            }, 
            new RelativeTimeRange
            {
                UpperBound = DateTime.Now.Subtract(DateTime.Now.AddYears(-1)),
                MessageCreator = (delta) => 
                { return (int)Math.Floor(delta.TotalDays / 30) + " months ago"; }
            }, 
            new RelativeTimeRange
            {
                UpperBound = DateTime.Now.Subtract(DateTime.Now.AddYears(-2)),
                MessageCreator = (delta) => 
                { return "one year ago"; }
            }, 
            new RelativeTimeRange
            {
                UpperBound = TimeSpan.MaxValue,
                MessageCreator = (delta) => 
                { return (int)Math.Floor(delta.TotalDays / 365.24D) + " years ago"; }
            }
        };

        timeRanges.Sort();
    }

    public static string GetRelativeTimeMessage(TimeSpan ago)
    {
        RelativeTimeRange postRelativeDateRange = timeRanges[0];

        foreach (var timeRange in timeRanges)
        {
            if (ago.CompareTo(timeRange.UpperBound) <= 0)
            {
                postRelativeDateRange = timeRange;
            }
        }

        return postRelativeDateRange.MessageCreator(ago);
    }
}

17
0

Ответ #17

Ответ на вопрос: Вычислить относительное время в C#

Когда вы знаете часовой пояс зрителя, может 9X_visual-c# быть понятнее использовать календарные дни 9X_csharp в дневной шкале. Я не знаком с библиотеками 9X_c-sharp .NET, поэтому, к сожалению, не знаю, как 9X_c# вы это сделаете на С#.

На потребительских 9X_c#.net сайтах вы также можете отказаться менее 9X_c#.net чем за минуту. «Меньше минуты назад» или 9X_visual-c# «только что» может быть достаточно.

15
0

Ответ #18

Ответ на вопрос: Вычислить относительное время в C#

В PHP я делаю так:

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

} ?>

9X_visual-c#

15
1

  • Вопрос в *** C# помечен ***. Почему этот *** ...

Ответ #19

Ответ на вопрос: Вычислить относительное время в C#

using System;
using System.Collections.Generic;
using System.Linq;

public static class RelativeDateHelper
{
    private static Dictionary> sm_Dict = null;

    private static Dictionary> DictionarySetup()
    {
        var dict = new Dictionary>();
        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;
    }
}

То же, что и another answer to this question, но как метод расширения со 9X_datetime-manipulation статическим словарем.

15
0

Ответ #20

Ответ на вопрос: Вычислить относительное время в C#

@Джефф

var ts = new TimeSpan(DateTime.UtcNow.Ticks - dt.Ticks);

Вычитание DateTime все равно возвращает TimeSpan.

Так 9X_datetime-operation что вы можете просто сделать

(DateTime.UtcNow - dt).TotalSeconds

Я также удивлен, увидев 9X_datetime-manipulation константы, умноженные вручную, а затем добавленные 9X_visual-c# комментарии с умножениями. Была ли это какая-то 9X_datetime ошибочная оптимизация?

12
0

Ответ #21

Ответ на вопрос: Вычислить относительное время в C#

Вы можете попробовать это, я думаю, это 9X_time сработает правильно.

long delta = new Date().getTime() - date.getTime();
const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;

if (delta < 0L)
{
  return "not yet";
}
if (delta < 1L * MINUTE)
{
  return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
}
if (delta < 2L * MINUTE)
{
  return "a minute ago";
}
if (delta < 45L * MINUTE)
{
  return ts.Minutes + " minutes ago";
}
if (delta < 90L * MINUTE)
{
  return "an hour ago";
}
if (delta < 24L * HOUR)
{
  return ts.Hours + " hours ago";
}
if (delta < 48L * HOUR)
{
  return "yesterday";
}
if (delta < 30L * DAY)
{
  return ts.Days + " days ago";
}
if (delta < 12L * MONTH)
{
  int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
  return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
  int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
  return years <= 1 ? "one year ago" : years + " years ago";
}

12
0

Ответ #22

Ответ на вопрос: Вычислить относительное время в C#

Вы можете использовать TimeAgo extension, как показано ниже:

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

Или 9X_c# используйте jQuery plugin с расширением Razor от Timeago.

12
0

Ответ #23

Ответ на вопрос: Вычислить относительное время в C#

Вы можете уменьшить нагрузку на сервер, выполнив 9X_c#-language эту логику на стороне клиента. Просмотр 9X_csharp исходного кода на некоторых страницах Digg 9X_c#.net для справки. У них есть сервер, который 9X_c#-language выдает значение времени эпохи, которое обрабатывается 9X_.cs-file Javascript. Таким образом, вам не нужно 9X_time управлять часовым поясом конечного пользователя. Новый 9X_datetime-manipulation серверный код будет выглядеть примерно так:

public string GetRelativeTime(DateTime timeStamp)
{
    return string.Format("", timeStamp.ToFileTimeUtc());
}

Вы 9X_datetime-manipulation даже можете добавить туда блок NOSCRIPT 9X_c# и просто выполнить ToString().

11
0

Ответ #24

Ответ на вопрос: Вычислить относительное время в C#

Вот алгоритм, который использует stackoverflow, но 9X_visual-c# переписанный более лаконично в псевдокоде 9X_datediff perlish с исправлением ошибки (не «час назад»). Функция 9X_csharp принимает (положительное) количество секунд 9X_visual-c# назад и возвращает удобную для человека 9X_datetime-manipulation строку, например «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";

10
0

Ответ #25

Ответ на вопрос: Вычислить относительное время в C#

Я получил этот ответ из одного из блогов 9X_.cs-file Билла Гейтса. Мне нужно найти его в истории 9X_c#.net браузера, и я дам вам ссылку.

Код Javascript, выполняющий 9X_time то же самое (по запросу):

function posted(t) {
    var now = new Date();
    var diff = parseInt((now.getTime() - Date.parse(t)) / 1000);
    if (diff < 60) { return 'less than a minute ago'; }
    else if (diff < 120) { return 'about a minute ago'; }
    else if (diff < (2700)) { return (parseInt(diff / 60)).toString() + ' minutes ago'; }
    else if (diff < (5400)) { return 'about an hour ago'; }
    else if (diff < (86400)) { return 'about ' + (parseInt(diff / 3600)).toString() + ' hours ago'; }
    else if (diff < (172800)) { return '1 day ago'; } 
    else {return (parseInt(diff / 86400)).toString() + ' days ago'; }
}

Обычно вы работаете 9X_.cs-file в секундах.

9
0

Ответ #26

Ответ на вопрос: Вычислить относительное время в C#

Я думаю, что уже есть несколько ответов, связанных 9X_.cs-file с этим постом, но можно использовать его, который 9X_c-sharp прост в использовании, как и плагин, а также 9X_c#.net легко читается программистами. Отправьте 9X_c# конкретную дату и получите ее значение в 9X_datetime-manipulation виде строки:

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

8
0

Ответ #27

Ответ на вопрос: Вычислить относительное время в C#

Java для использования gwt на стороне клиента:

import java.util.Date;

public class RelativeDateFormat {

 private static final long ONE_MINUTE = 60000L;
 private static final long ONE_HOUR = 3600000L;
 private static final long ONE_DAY = 86400000L;
 private static final long ONE_WEEK = 604800000L;

 public static String format(Date date) {

  long delta = new Date().getTime() - date.getTime();
  if (delta < 1L * ONE_MINUTE) {
   return toSeconds(delta) == 1 ? "one second ago" : toSeconds(delta)
     + " seconds ago";
  }
  if (delta < 2L * ONE_MINUTE) {
   return "one minute ago";
  }
  if (delta < 45L * ONE_MINUTE) {
   return toMinutes(delta) + " minutes ago";
  }
  if (delta < 90L * ONE_MINUTE) {
   return "one hour ago";
  }
  if (delta < 24L * ONE_HOUR) {
   return toHours(delta) + " hours ago";
  }
  if (delta < 48L * ONE_HOUR) {
   return "yesterday";
  }
  if (delta < 30L * ONE_DAY) {
   return toDays(delta) + " days ago";
  }
  if (delta < 12L * 4L * ONE_WEEK) {
   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 static long toSeconds(long date) {
  return date / 1000L;
 }

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

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

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

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

 private static long toYears(long date) {
  return toMonths(date) / 365L;
 }

}

9X_datetime

8
1

  • Вопрос в *** C# помечен ***. Почему этот *** код Java ***? _IMHO, применяется только ко ...

Ответ #28

Ответ на вопрос: Вычислить относительное время в C#

var ts = new TimeSpan(DateTime.Now.Ticks - dt.Ticks);

9X_c#

6
0

Ответ #29

Ответ на вопрос: Вычислить относительное время в C#

Если вы хотите получить такой результат, как 9X_c# "2 days, 4 hours and 12 minutes ago", вам нужен временной интервал:

TimeSpan timeDiff = DateTime.Now-CreatedDate;

Затем вы 9X_datediff можете получить доступ к понравившимся значениям:

timeDiff.Days
timeDiff.Hours

и 9X_datediff т. д.

6
0

Ответ #30

Ответ на вопрос: Вычислить относительное время в C#

Я бы предоставил для этого несколько удобных 9X_c# методов расширения и сделал бы код более 9X_.cs-file читабельным. Во-первых, пара методов расширения 9X_time для 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;
    }
}

Теперь вы можете сделать 9X_c# что-то вроде следующего:

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

5
0

Ответ #31

Ответ на вопрос: Вычислить относительное время в C#

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

9X_c-sharp

4
0

Ответ #32

Ответ на вопрос: Вычислить относительное время в C#

Турецкая локализованная версия ответа Винсента.

    const int SECOND = 1;
    const int MINUTE = 60 * SECOND;
    const int HOUR = 60 * MINUTE;
    const int DAY = 24 * HOUR;
    const int MONTH = 30 * DAY;

    var ts = new TimeSpan(DateTime.UtcNow.Ticks - yourDate.Ticks);
    double delta = Math.Abs(ts.TotalSeconds);

    if (delta < 1 * MINUTE)
        return ts.Seconds + " saniye önce";

    if (delta < 45 * MINUTE)
        return ts.Minutes + " dakika önce";

    if (delta < 24 * HOUR)
        return ts.Hours + " saat önce";

    if (delta < 48 * HOUR)
        return "dün";

    if (delta < 30 * DAY)
        return ts.Days + " gün önce";

    if (delta < 12 * MONTH)
    {
        int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
        return months + " ay önce";
    }
    else
    {
        int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
        return years + " yıl önce";
    }

9X_time

4
0

Ответ #33

Ответ на вопрос: Вычислить относительное время в C#

Конечно, простым решением проблемы «1 час 9X_c#-language назад» было бы увеличение окна, для которого 9X_c#.net действительно «час назад». Изменить

if (delta < 5400) // 90 * 60
{
    return "an hour ago";
}

в

if (delta < 7200) // 120 * 60
{
    return "an hour ago";
}

Это 9X_c#.net означает, что что-то, что произошло 110 9X_datetime-functions минут назад, будет читаться как «час назад» — это 9X_datetime-functions может быть не идеально, но я бы сказал, что 9X_datediff это лучше, чем текущая ситуация «1 час назад».

3
0

Ответ #34

Ответ на вопрос: Вычислить относительное время в C#

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

Значения конверсии для дней в месяце и году 9X_relative-time-span были взяты из Google.

3
0

Ответ #35

Ответ на вопрос: Вычислить относительное время в C#

В способе, которым вы выполняете свою функцию 9X_visual-c# DateTime при вычислении относительного времени от 9X_datetime-operation секунд до лет, попробуйте что-нибудь вроде 9X_.cs-file этого:

using System;

public class Program {
    public static string getRelativeTime(DateTime past) {
        DateTime now = DateTime.Today;
        string rt = "";
        int time;
        string statement = "";
        if (past.Second >= now.Second) {
            if (past.Second - now.Second == 1) {
                rt = "second ago";
            }
            rt = "seconds ago";
            time = past.Second - now.Second;
            statement = "" + time;
            return (statement + rt);
        }
        if (past.Minute >= now.Minute) {
            if (past.Second - now.Second == 1) {
                rt = "second ago";
            } else {
                rt = "minutes ago";
            }
            time = past.Minute - now.Minute;
            statement = "" + time;
            return (statement + rt);
        }
        // This process will go on until years
    }
    public static void Main() {
        DateTime before = new DateTime(1995, 8, 24);
        string date = getRelativeTime(before);
        Console.WriteLine("Windows 95 was {0}.", date);
    }
}

Не совсем работает, но если вы немного 9X_.cs-file измените и отладите его, он, скорее всего, сработает.

3
0

Ответ #36

Ответ на вопрос: Вычислить относительное время в C#

// Calculate total days in current year
int daysInYear;

for (var i = 1; i <= 12; i++)
    daysInYear += DateTime.DaysInMonth(DateTime.Now.Year, i);

// Past date
DateTime dateToCompare = DateTime.Now.Subtract(TimeSpan.FromMinutes(582));

// Calculate difference between current date and past date
double diff = (DateTime.Now - dateToCompare).TotalMilliseconds;

TimeSpan ts = TimeSpan.FromMilliseconds(diff);

var years = ts.TotalDays / daysInYear; // Years
var months = ts.TotalDays / (daysInYear / (double)12); // Months
var weeks = ts.TotalDays / 7; // Weeks
var days = ts.TotalDays; // Days
var hours = ts.TotalHours; // Hours
var minutes = ts.TotalMinutes; // Minutes
var seconds = ts.TotalSeconds; // Seconds

if (years >= 1)
    Console.WriteLine(Math.Round(years, 0) + " year(s) ago");
else if (months >= 1)
    Console.WriteLine(Math.Round(months, 0) + " month(s) ago");
else if (weeks >= 1)
    Console.WriteLine(Math.Round(weeks, 0) + " week(s) ago");
else if (days >= 1)
    Console.WriteLine(Math.Round(days, 0) + " days(s) ago");
else if (hours >= 1)
    Console.WriteLine(Math.Round(hours, 0) + " hour(s) ago");
else if (minutes >= 1)
    Console.WriteLine(Math.Round(minutes, 0) + " minute(s) ago");
else if (seconds >= 1)
    Console.WriteLine(Math.Round(seconds, 0) + " second(s) ago");

Console.ReadLine();

9X_datediff

2
0

Ответ #37

Ответ на вопрос: Вычислить относительное время в C#

«Однострочный», использующий деконструкцию 9X_datediff и Linq для получения «n [наибольшая единица 9X_.cs-file времени] назад»:

TimeSpan timeSpan = DateTime.Now - new DateTime(1234, 5, 6, 7, 8, 9);

(string unit, int value) = new Dictionary
{
    {"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 year(s) ago

С текущим годом 9X_datetime и месяцем, например

TimeSpan timeSpan = DateTime.Now - new DateTime(2020, 12, 6, 7, 8, 9);

вы получаете 4 day(s) ago

С актуальной 9X_csharp датой, например

TimeSpan timeSpan = DateTime.Now - DateTime.Now.Date;

вы получаете 9 hour(s) ago

2
0

Ответ #38

Ответ на вопрос: Вычислить относительное время в C#

Это моя функция, работает как шарм :)

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

9X_datetime-functions

1
0