Вопрос

В Ruby on Rails есть функция, которая позволяет вам предпринять любую дату и распечатать, как «давно» это было.

Например:

8 minutes ago
8 hours ago
8 days ago
8 months ago
8 years ago

Есть ли простой способ сделать это в Java?

Это было полезно?

Решение

Посмотрите на Красивый библиотека.

Это довольно просто использовать:

import org.ocpsoft.prettytime.PrettyTime;

PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
// prints "moments ago"

Вы также можете пройти в локали для интернационализированных сообщений:

PrettyTime p = new PrettyTime(new Locale("fr"));
System.out.println(p.format(new Date()));
// prints "à l'instant"

Как отмечено в комментариях, Android имеет эту функциональность, встроенную в android.text.format.DateUtils сорт.

Другие советы

Вы считали Таймно enum? Это может быть довольно полезно для такого рода вещи

    try {
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        Date past = format.parse("01/10/2010");
        Date now = new Date();

        System.out.println(TimeUnit.MILLISECONDS.toMillis(now.getTime() - past.getTime()) + " milliseconds ago");
        System.out.println(TimeUnit.MILLISECONDS.toMinutes(now.getTime() - past.getTime()) + " minutes ago");
        System.out.println(TimeUnit.MILLISECONDS.toHours(now.getTime() - past.getTime()) + " hours ago");
        System.out.println(TimeUnit.MILLISECONDS.toDays(now.getTime() - past.getTime()) + " days ago");
    }
    catch (Exception j){
        j.printStackTrace();
    }

Я принимаю Realhowto и Ben J отвечает и сделаю свою собственную версию:

public class TimeAgo {
public static final List<Long> times = Arrays.asList(
        TimeUnit.DAYS.toMillis(365),
        TimeUnit.DAYS.toMillis(30),
        TimeUnit.DAYS.toMillis(1),
        TimeUnit.HOURS.toMillis(1),
        TimeUnit.MINUTES.toMillis(1),
        TimeUnit.SECONDS.toMillis(1) );
public static final List<String> timesString = Arrays.asList("year","month","day","hour","minute","second");

public static String toDuration(long duration) {

    StringBuffer res = new StringBuffer();
    for(int i=0;i< TimeAgo.times.size(); i++) {
        Long current = TimeAgo.times.get(i);
        long temp = duration/current;
        if(temp>0) {
            res.append(temp).append(" ").append( TimeAgo.timesString.get(i) ).append(temp != 1 ? "s" : "").append(" ago");
            break;
        }
    }
    if("".equals(res.toString()))
        return "0 seconds ago";
    else
        return res.toString();
}
public static void main(String args[]) {
    System.out.println(toDuration(123));
    System.out.println(toDuration(1230));
    System.out.println(toDuration(12300));
    System.out.println(toDuration(123000));
    System.out.println(toDuration(1230000));
    System.out.println(toDuration(12300000));
    System.out.println(toDuration(123000000));
    System.out.println(toDuration(1230000000));
    System.out.println(toDuration(12300000000L));
    System.out.println(toDuration(123000000000L));
}}

который будет распечатать следующее

0 second ago
1 second ago
12 seconds ago
2 minutes ago
20 minutes ago
3 hours ago
1 day ago
14 days ago
4 months ago
3 years ago
  public class TimeUtils {

      public final static long ONE_SECOND = 1000;
      public final static long SECONDS = 60;

      public final static long ONE_MINUTE = ONE_SECOND * 60;
      public final static long MINUTES = 60;

      public final static long ONE_HOUR = ONE_MINUTE * 60;
      public final static long HOURS = 24;

      public final static long ONE_DAY = ONE_HOUR * 24;

      private TimeUtils() {
      }

      /**
       * converts time (in milliseconds) to human-readable format
       *  "<w> days, <x> hours, <y> minutes and (z) seconds"
       */
      public static String millisToLongDHMS(long duration) {
        StringBuffer res = new StringBuffer();
        long temp = 0;
        if (duration >= ONE_SECOND) {
          temp = duration / ONE_DAY;
          if (temp > 0) {
            duration -= temp * ONE_DAY;
            res.append(temp).append(" day").append(temp > 1 ? "s" : "")
               .append(duration >= ONE_MINUTE ? ", " : "");
          }

          temp = duration / ONE_HOUR;
          if (temp > 0) {
            duration -= temp * ONE_HOUR;
            res.append(temp).append(" hour").append(temp > 1 ? "s" : "")
               .append(duration >= ONE_MINUTE ? ", " : "");
          }

          temp = duration / ONE_MINUTE;
          if (temp > 0) {
            duration -= temp * ONE_MINUTE;
            res.append(temp).append(" minute").append(temp > 1 ? "s" : "");
          }

          if (!res.toString().equals("") && duration >= ONE_SECOND) {
            res.append(" and ");
          }

          temp = duration / ONE_SECOND;
          if (temp > 0) {
            res.append(temp).append(" second").append(temp > 1 ? "s" : "");
          }
          return res.toString();
        } else {
          return "0 second";
        }
      }


      public static void main(String args[]) {
        System.out.println(millisToLongDHMS(123));
        System.out.println(millisToLongDHMS((5 * ONE_SECOND) + 123));
        System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR));
        System.out.println(millisToLongDHMS(ONE_DAY + 2 * ONE_SECOND));
        System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR + (2 * ONE_MINUTE)));
        System.out.println(millisToLongDHMS((4 * ONE_DAY) + (3 * ONE_HOUR)
            + (2 * ONE_MINUTE) + ONE_SECOND));
        System.out.println(millisToLongDHMS((5 * ONE_DAY) + (4 * ONE_HOUR)
            + ONE_MINUTE + (23 * ONE_SECOND) + 123));
        System.out.println(millisToLongDHMS(42 * ONE_DAY));
        /*
          output :
                0 second
                5 seconds
                1 day, 1 hour
                1 day and 2 seconds
                1 day, 1 hour, 2 minutes
                4 days, 3 hours, 2 minutes and 1 second
                5 days, 4 hours, 1 minute and 23 seconds
                42 days
         */
    }
}

более @Формат продолжительность в миллисекундах в читаемый человеком формат

Это основано на ответе Realhowto, так что если вам это нравится, дайте ему / ее тоже любовь.

Эта очищенная версия позволяет указывать диапазон времени, который вы можете заинтересовать.

Он также обрабатывает «и» часть немного по-другому. Я часто нахожу при присоединении к струнам с разделителем, который проще пропустить сложную логику и просто удалить последний разделитель, когда вы закончите.

import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

public class TimeUtils {

    /**
     * Converts time to a human readable format within the specified range
     *
     * @param duration the time in milliseconds to be converted
     * @param max      the highest time unit of interest
     * @param min      the lowest time unit of interest
     */
    public static String formatMillis(long duration, TimeUnit max, TimeUnit min) {
        StringBuilder res = new StringBuilder();

        TimeUnit current = max;

        while (duration > 0) {
            long temp = current.convert(duration, MILLISECONDS);

            if (temp > 0) {
                duration -= current.toMillis(temp);
                res.append(temp).append(" ").append(current.name().toLowerCase());
                if (temp < 2) res.deleteCharAt(res.length() - 1);
                res.append(", ");
            }

            if (current == min) break;

            current = TimeUnit.values()[current.ordinal() - 1];
        }

        // clean up our formatting....

        // we never got a hit, the time is lower than we care about
        if (res.lastIndexOf(", ") < 0) return "0 " + min.name().toLowerCase();

        // yank trailing  ", "
        res.deleteCharAt(res.length() - 2);

        //  convert last ", " to " and"
        int i = res.lastIndexOf(", ");
        if (i > 0) {
            res.deleteCharAt(i);
            res.insert(i, " and");
        }

        return res.toString();
    }
}

Маленький код, чтобы дать ему Whirl:

import static java.util.concurrent.TimeUnit.*;

public class Main {

    public static void main(String args[]) {
        long[] durations = new long[]{
            123,
            SECONDS.toMillis(5) + 123,
            DAYS.toMillis(1) + HOURS.toMillis(1),
            DAYS.toMillis(1) + SECONDS.toMillis(2),
            DAYS.toMillis(1) + HOURS.toMillis(1) + MINUTES.toMillis(2),
            DAYS.toMillis(4) + HOURS.toMillis(3) + MINUTES.toMillis(2) + SECONDS.toMillis(1),
            DAYS.toMillis(5) + HOURS.toMillis(4) + MINUTES.toMillis(1) + SECONDS.toMillis(23) + 123,
            DAYS.toMillis(42)
        };

        for (long duration : durations) {
            System.out.println(TimeUtils.formatMillis(duration, DAYS, SECONDS));
        }

        System.out.println("\nAgain in only hours and minutes\n");

        for (long duration : durations) {
            System.out.println(TimeUtils.formatMillis(duration, HOURS, MINUTES));
        }
    }

}

Который будет выводить следующее:

0 seconds
5 seconds 
1 day and 1 hour 
1 day and 2 seconds 
1 day, 1 hour and 2 minutes 
4 days, 3 hours, 2 minutes and 1 second 
5 days, 4 hours, 1 minute and 23 seconds 
42 days 

Again in only hours and minutes

0 minutes
0 minutes
25 hours 
24 hours 
25 hours and 2 minutes 
99 hours and 2 minutes 
124 hours and 1 minute 
1008 hours 

И в случае, если кто-то когда-либо нуждается в этом, вот класс, который преобразует любую строку, как вышеупомянутое Вернуться в миллисекунды. Отказ Это довольно полезно для разрешения людей указывать тайм-ауты разных вещей в читабельном тексте.

Есть простой способ сделать это:

Допустим, вы хотите время 20 минут назад:

Long minutesAgo = new Long(20);
Date date = new Date();
Date dateIn_X_MinAgo = new Date (date.getTime() - minutesAgo*60*1000);

Это оно..

Если вы ищете простую «сегодня», «вчера» или «х дней назад».

private String getDaysAgo(Date date){
    long days = (new Date().getTime() - date.getTime()) / 86400000;

    if(days == 0) return "Today";
    else if(days == 1) return "Yesterday";
    else return days + " days ago";
}

Java.Time.

С использованием Java.Time. Рамки встроены в Java 8, а затем.

LocalDateTime t1 = LocalDateTime.of(2015, 1, 1, 0, 0, 0);
LocalDateTime t2 = LocalDateTime.now();
Period period = Period.between(t1.toLocalDate(), t2.toLocalDate());
Duration duration = Duration.between(t1, t2);

System.out.println("First January 2015 is " + period.getYears() + " years ago");
System.out.println("First January 2015 is " + period.getMonths() + " months ago");
System.out.println("First January 2015 is " + period.getDays() + " days ago");
System.out.println("First January 2015 is " + duration.toHours() + " hours ago");
System.out.println("First January 2015 is " + duration.toMinutes() + " minutes ago");

О встроенный Решения:

Java не имеет встроенной поддержки для форматирования относительных времен, а также не Java-8 и ее новый пакет java.time. Отказ Если вам нужен только английский и ничего другого, и только тогда, только тогда ручной раствор может быть приемлемым - см. Ответ @realhowto (хотя у него есть сильный недостаток, чтобы не учитывать часовой пояс для перевода мгновенных дельтас в местное время единицы!). В любом случае, если вы хотите избежать домашнего сложных обходных путей, особенно для других локалей, вам нужна внешняя библиотека.

В последнем случае я рекомендую использовать мою библиотеку Time4J. (или Time4a на Android). Это предлагает Наибольшая гибкость и большинство I18N-Power. Отказ Класс net.time4j.prettytime. имеет семь способов printRelativeTime...(...) Для этого. Пример, используя тестовые часы как источник времени:

TimeSource<?> clock = () -> PlainTimestamp.of(2015, 8, 1, 10, 24, 5).atUTC();
Moment moment = PlainTimestamp.of(2015, 8, 1, 17, 0).atUTC(); // our input
String durationInDays =
  PrettyTime.of(Locale.GERMAN).withReferenceClock(clock).printRelative(
    moment,
    Timezone.of(EUROPE.BERLIN),
    TimeUnit.DAYS); // controlling the precision
System.out.println(durationInDays); // heute (german word for today)

Еще один пример с использованием java.time.Instant в качестве ввода:

String relativeTime = 
  PrettyTime.of(Locale.ENGLISH)
    .printRelativeInStdTimezone(Moment.from(Instant.EPOCH));
System.out.println(relativeTime); // 45 years ago

Эта библиотека поддерживает через свою последнюю версию (v4.17) 80 языков А также несколько местных местных мест (особенно для испанского, английского, арабского, французского). I18N-данные в основном основаны на Новый CLDR-версия V29. Отказ Другие важные причины, почему использовать эту библиотеку хороши Поддержка правил множественного числа (которые часто отличаются от английского в других локалях), Сокращенный стиль формата (например: «1 сек назад») и выразительные пути для Принимая во внимание часовые появления. Отказ Time4J даже осознает такие экзотические детали, как Скакать секунды В расчетах относительных времен (не очень важно, но это формирует сообщение, связанное с горизонтом ожидания). То Совместимость с Java-8 Существует из-за легкодоступных методов преобразования для типов, таких как java.time.Instant или java.time.Period.

Есть ли недостатки? Только два.

  • Библиотека не маленькая (также из-за его большой репозиторий i18n-данных).
  • API не является известным, поэтому знания и поддержка сообщества недоступны, но в противном случае прилагаемая документация довольно подробна и всеобъемлющая.

(Компактные) альтернативы:

Если вы ищете меньшее решение и не нужно так много функций, и готовы терпеть возможные вопросы качества, связанные с i18n-data, то:

  • я бы порекомендовал OCPSOFT / Beytime (Поддержка на самом деле 32 языка (в ближайшее время 34?) Подходит для работы с java.util.Date Только - см. Ответ @ataylor). В отрасли стандартный CLDR (из консорциума Unicode) с его большим фоном сообщества, к сожалению, не основание данных I18N, поэтому дальнейшие улучшения или улучшения данных могут занять некоторое время ...

  • Если вы находитесь на Android, то класс помощника android.text.format.dateutils. Это стройная встраиваемая альтернатива (см. Другие комментарии и ответы здесь, с недостатком того, что оно не имеет поддержки в течение многих лет и месяцев. И я уверен, что только очень мало людей, таких как API-стиль этого класса помощника.

  • Если вы фанат Joda-Time Тогда вы можете посмотреть на свой класс Периодический формат (Поддержка 14 языков в выпуске V2.9.4, с другой стороны: Joda-Time, безусловно, тоже не компактно, поэтому я упоминаю это здесь только для полноты). Эта библиотека не является реальным ответом, потому что относительные времена вообще не поддерживаются. Вам нужно будет добавить букмену «назад», по крайней мере (и вручную отчитываю все нижние единицы от создаваемых форматов списка - неловко). В отличие от Time4j или Android -itytitials, у него нет особой поддержки сокращений или автоматического переключения от относительных времен до абсолютных представлений времени. Как и Beytime, он полностью зависит от неподтвержденных вкладов частных членов Java-сообщества в его i18n-данные.

Я создал простой Java Timeago. порт jquery-timeago. плагин, который делает то, что вы просите.

TimeAgo time = new TimeAgo();
String minutes = time.timeAgo(System.currentTimeMillis() - (15*60*1000)); // returns "15 minutes ago"

Если вы разрабатываете приложение для Android, он предоставляет утилиту Датеэтилс Для всех таких требований. Посмотрите на DateutiLs # GetRelativeImespanString () Метод полезности.

От документов для

Чарсус getrelativeImespanstring (долгое время, долгое время, длинная минрезоляция)

Возвращает строку, описывающую «время» как время, относительно «сейчас». Время продвижения в прошлом отформатированы как «42 минуты назад». Время промежуток в будущем отформатировано как «через 42 минуты».

Вы будете проходить timestamp так как время а также System.currentTimeMillis() так как сейчас. Отказ То minResolution Позволяет указать минимальный Timepan для отчета.

Например, время 3 секунды в прошлом будет сообщено как «0 минут назад», если это установлено значение minute_in_millis. Пройти один из 0, minute_in_millis, hash_in_millis, day_in_millis, неделю_in_millis и т. Д.

То Joda-Time пакет, имеет представление о Периоды. Отказ Вы можете сделать арифметику с периодами и датами.

Из документы:

public boolean isRentalOverdue(DateTime datetimeRented) {
  Period rentalPeriod = new  Period().withDays(2).withHours(12);
  return datetimeRented.plus(rentalPeriod).isBeforeNow();
}

Вы можете использовать эту функцию для расчета времени назад

 private String timeAgo(long time_ago) {
        long cur_time = (Calendar.getInstance().getTimeInMillis()) / 1000;
        long time_elapsed = cur_time - time_ago;
        long seconds = time_elapsed;
        int minutes = Math.round(time_elapsed / 60);
        int hours = Math.round(time_elapsed / 3600);
        int days = Math.round(time_elapsed / 86400);
        int weeks = Math.round(time_elapsed / 604800);
        int months = Math.round(time_elapsed / 2600640);
        int years = Math.round(time_elapsed / 31207680);

        // Seconds
        if (seconds <= 60) {
            return "just now";
        }
        //Minutes
        else if (minutes <= 60) {
            if (minutes == 1) {
                return "one minute ago";
            } else {
                return minutes + " minutes ago";
            }
        }
        //Hours
        else if (hours <= 24) {
            if (hours == 1) {
                return "an hour ago";
            } else {
                return hours + " hrs ago";
            }
        }
        //Days
        else if (days <= 7) {
            if (days == 1) {
                return "yesterday";
            } else {
                return days + " days ago";
            }
        }
        //Weeks
        else if (weeks <= 4.3) {
            if (weeks == 1) {
                return "a week ago";
            } else {
                return weeks + " weeks ago";
            }
        }
        //Months
        else if (months <= 12) {
            if (months == 1) {
                return "a month ago";
            } else {
                return months + " months ago";
            }
        }
        //Years
        else {
            if (years == 1) {
                return "one year ago";
            } else {
                return years + " years ago";
            }
        }
    }

1) Здесь Time_ago находится в микросекунде

На основании куча ответов здесь я создал следующее для моего случая использования.

Пример использования:

String relativeDate = String.valueOf(
                TimeUtils.getRelativeTime( 1000L * myTimeInMillis() ));

import java.util.Arrays;
import java.util.List;

import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * Utilities for dealing with dates and times
 */
public class TimeUtils {

    public static final List<Long> times = Arrays.asList(
        DAYS.toMillis(365),
        DAYS.toMillis(30),
        DAYS.toMillis(7),
        DAYS.toMillis(1),
        HOURS.toMillis(1),
        MINUTES.toMillis(1),
        SECONDS.toMillis(1)
    );

    public static final List<String> timesString = Arrays.asList(
        "yr", "mo", "wk", "day", "hr", "min", "sec"
    );

    /**
     * Get relative time ago for date
     *
     * NOTE:
     *  if (duration > WEEK_IN_MILLIS) getRelativeTimeSpanString prints the date.
     *
     * ALT:
     *  return getRelativeTimeSpanString(date, now, SECOND_IN_MILLIS, FORMAT_ABBREV_RELATIVE);
     *
     * @param date String.valueOf(TimeUtils.getRelativeTime(1000L * Date/Time in Millis)
     * @return relative time
     */
    public static CharSequence getRelativeTime(final long date) {
        return toDuration( Math.abs(System.currentTimeMillis() - date) );
    }

    private static String toDuration(long duration) {
        StringBuilder sb = new StringBuilder();
        for(int i=0;i< times.size(); i++) {
            Long current = times.get(i);
            long temp = duration / current;
            if (temp > 0) {
                sb.append(temp)
                  .append(" ")
                  .append(timesString.get(i))
                  .append(temp > 1 ? "s" : "")
                  .append(" ago");
                break;
            }
        }
        return sb.toString().isEmpty() ? "now" : sb.toString();
    }
}

Это не красиво ... но ближайший я могу думать о том, чтобы использовать Joda-Time (как описано в этом посте: Как рассчитать прошедшее время от времени с Joda Time?

Это лучший код, если мы считаем производительность. Это уменьшает количество расчетов.ПричинаПротокол рассчитывается только в том случае, если количество секунд превышает 60, а часы рассчитываются только в том случае, если количество минут больше 60 и так далее ...

class timeAgo {

static String getTimeAgo(long time_ago) {
    time_ago=time_ago/1000;
    long cur_time = (Calendar.getInstance().getTimeInMillis())/1000 ;
    long time_elapsed = cur_time - time_ago;
    long seconds = time_elapsed;
   // Seconds
    if (seconds <= 60) {
        return "Just now";
    }
    //Minutes
    else{
        int minutes = Math.round(time_elapsed / 60);

        if (minutes <= 60) {
            if (minutes == 1) {
                return "a minute ago";
            } else {
                return minutes + " minutes ago";
            }
        }
        //Hours
        else {
            int hours = Math.round(time_elapsed / 3600);
            if (hours <= 24) {
                if (hours == 1) {
                    return "An hour ago";
                } else {
                    return hours + " hrs ago";
                }
            }
            //Days
            else {
                int days = Math.round(time_elapsed / 86400);
                if (days <= 7) {
                    if (days == 1) {
                        return "Yesterday";
                    } else {
                        return days + " days ago";
                    }
                }
                //Weeks
                else {
                    int weeks = Math.round(time_elapsed / 604800);
                    if (weeks <= 4.3) {
                        if (weeks == 1) {
                            return "A week ago";
                        } else {
                            return weeks + " weeks ago";
                        }
                    }
                    //Months
                    else {
                        int months = Math.round(time_elapsed / 2600640);
                        if (months <= 12) {
                            if (months == 1) {
                                return "A month ago";
                            } else {
                                return months + " months ago";
                            }
                        }
                        //Years
                        else {
                            int years = Math.round(time_elapsed / 31207680);
                            if (years == 1) {
                                return "One year ago";
                            } else {
                                return years + " years ago";
                            }
                        }
                    }
                }
            }
        }
    }

}

}

После долгих исследований я нашел это.

    public class GetTimeLapse {
    public static String getlongtoago(long createdAt) {
        DateFormat userDateFormat = new SimpleDateFormat("E MMM dd HH:mm:ss Z yyyy");
        DateFormat dateFormatNeeded = new SimpleDateFormat("MM/dd/yyyy HH:MM:SS");
        Date date = null;
        date = new Date(createdAt);
        String crdate1 = dateFormatNeeded.format(date);

        // Date Calculation
        DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        crdate1 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(date);

        // get current date time with Calendar()
        Calendar cal = Calendar.getInstance();
        String currenttime = dateFormat.format(cal.getTime());

        Date CreatedAt = null;
        Date current = null;
        try {
            CreatedAt = dateFormat.parse(crdate1);
            current = dateFormat.parse(currenttime);
        } catch (java.text.ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Get msec from each, and subtract.
        long diff = current.getTime() - CreatedAt.getTime();
        long diffSeconds = diff / 1000;
        long diffMinutes = diff / (60 * 1000) % 60;
        long diffHours = diff / (60 * 60 * 1000) % 24;
        long diffDays = diff / (24 * 60 * 60 * 1000);

        String time = null;
        if (diffDays > 0) {
            if (diffDays == 1) {
                time = diffDays + "day ago ";
            } else {
                time = diffDays + "days ago ";
            }
        } else {
            if (diffHours > 0) {
                if (diffHours == 1) {
                    time = diffHours + "hr ago";
                } else {
                    time = diffHours + "hrs ago";
                }
            } else {
                if (diffMinutes > 0) {
                    if (diffMinutes == 1) {
                        time = diffMinutes + "min ago";
                    } else {
                        time = diffMinutes + "mins ago";
                    }
                } else {
                    if (diffSeconds > 0) {
                        time = diffSeconds + "secs ago";
                    }
                }

            }

        }
        return time;
    }
}

Для андроидаТочно так же, как Рави сказал, но так как много людей хотят Просто скопируйте вставку Вещь здесь это.

  try {
      SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
      Date dt = formatter.parse(date_from_server);
      CharSequence output = DateUtils.getRelativeTimeSpanString (dt.getTime());
      your_textview.setText(output.toString());
    } catch (Exception ex) {
      ex.printStackTrace();
      your_textview.setText("");
    }

Объяснение людей, которые имеют больше времени

  1. Вы получаете данные откуда-то. Сначала вы должны понять это формат.

Бывший. Я получаю данные с сервера в формате ср, 27 января 2016 09:32:35 GMT [Это, вероятно, не ваше дело

Это переводится в

SimpleDateFormat Formatter = новый SimpleDateFormat («EEE, DD MMM YYYY HH: MM: SS Z»);

Откуда я это знаю? Прочитать Документация здесь.

Затем после того, как я разбери это, я получаю дату. Эта дата я положил в getrelativeImespanString (без каких-либо дополнительных параметров в порядке, чтобы быть по умолчанию до минут)

Вы получите исключение Если вы не выяснили Правильная разборка струны, Что-то вроде: исключение на персонаже 5.. Посмотрите на символ 5 и исправьте начальную разборочную строку.. Отказ Вы можете получить еще одно исключение, повторите эти шаги, пока у вас нет правильной формулы.

Вот моя Java реализация этого

    public static String relativeDate(Date date){
    Date now=new Date();
    if(date.before(now)){
    int days_passed=(int) TimeUnit.MILLISECONDS.toDays(now.getTime() - date.getTime());
    if(days_passed>1)return days_passed+" days ago";
    else{
        int hours_passed=(int) TimeUnit.MILLISECONDS.toHours(now.getTime() - date.getTime());
        if(hours_passed>1)return days_passed+" hours ago";
        else{
            int minutes_passed=(int) TimeUnit.MILLISECONDS.toMinutes(now.getTime() - date.getTime());
            if(minutes_passed>1)return minutes_passed+" minutes ago";
            else{
                int seconds_passed=(int) TimeUnit.MILLISECONDS.toSeconds(now.getTime() - date.getTime());
                return seconds_passed +" seconds ago";
            }
        }
    }

    }
    else
    {
        return new SimpleDateFormat("HH:mm:ss MM/dd/yyyy").format(date).toString();
    }
  }

меня устраивает

public class TimeDifference {
    int years;
    int months;
    int days;
    int hours;
    int minutes;
    int seconds;
    String differenceString;

    public TimeDifference(@NonNull Date curdate, @NonNull Date olddate) {

        float diff = curdate.getTime() - olddate.getTime();
        if (diff >= 0) {
            int yearDiff = Math.round((diff / (AppConstant.aLong * AppConstant.aFloat)) >= 1 ? (diff / (AppConstant.aLong * AppConstant.aFloat)) : 0);
            if (yearDiff > 0) {
                years = yearDiff;
                setDifferenceString(years + (years == 1 ? " year" : " years") + " ago");
            } else {
                int monthDiff = Math.round((diff / AppConstant.aFloat) >= 1 ? (diff / AppConstant.aFloat) : 0);
                if (monthDiff > 0) {
                    if (monthDiff > AppConstant.ELEVEN) {
                        monthDiff = AppConstant.ELEVEN;
                    }
                    months = monthDiff;
                    setDifferenceString(months + (months == 1 ? " month" : " months") + " ago");
                } else {
                    int dayDiff = Math.round((diff / (AppConstant.bFloat)) >= 1 ? (diff / (AppConstant.bFloat)) : 0);
                    if (dayDiff > 0) {
                        days = dayDiff;
                        if (days == AppConstant.THIRTY) {
                            days = AppConstant.TWENTYNINE;
                        }
                        setDifferenceString(days + (days == 1 ? " day" : " days") + " ago");
                    } else {
                        int hourDiff = Math.round((diff / (AppConstant.cFloat)) >= 1 ? (diff / (AppConstant.cFloat)) : 0);
                        if (hourDiff > 0) {
                            hours = hourDiff;
                            setDifferenceString(hours + (hours == 1 ? " hour" : " hours") + " ago");
                        } else {
                            int minuteDiff = Math.round((diff / (AppConstant.dFloat)) >= 1 ? (diff / (AppConstant.dFloat)) : 0);
                            if (minuteDiff > 0) {
                                minutes = minuteDiff;
                                setDifferenceString(minutes + (minutes == 1 ? " minute" : " minutes") + " ago");
                            } else {
                                int secondDiff = Math.round((diff / (AppConstant.eFloat)) >= 1 ? (diff / (AppConstant.eFloat)) : 0);
                                if (secondDiff > 0) {
                                    seconds = secondDiff;
                                } else {
                                    seconds = 1;
                                }
                                setDifferenceString(seconds + (seconds == 1 ? " second" : " seconds") + " ago");
                            }
                        }
                    }

                }
            }

        } else {
            setDifferenceString("Just now");
        }

    }

    public String getDifferenceString() {
        return differenceString;
    }

    public void setDifferenceString(String differenceString) {
        this.differenceString = differenceString;
    }

    public int getYears() {
        return years;
    }

    public void setYears(int years) {
        this.years = years;
    }

    public int getMonths() {
        return months;
    }

    public void setMonths(int months) {
        this.months = months;
    }

    public int getDays() {
        return days;
    }

    public void setDays(int days) {
        this.days = days;
    }

    public int getHours() {
        return hours;
    }

    public void setHours(int hours) {
        this.hours = hours;
    }

    public int getMinutes() {
        return minutes;
    }

    public void setMinutes(int minutes) {
        this.minutes = minutes;
    }

    public int getSeconds() {
        return seconds;
    }

    public void setSeconds(int seconds) {
        this.seconds = seconds;
    } }

Это очень основной скрипт. легко улучшить.
Результат: (XXX часы назад), или (XX дни назад / вчера / сегодня)

<span id='hourpost'></span>
,or
<span id='daypost'></span>

<script>
var postTime = new Date('2017/6/9 00:01'); 
var now = new Date();
var difference = now.getTime() - postTime.getTime();
var minutes = Math.round(difference/60000);
var hours = Math.round(minutes/60);
var days = Math.round(hours/24);

var result;
if (days < 1) {
result = "Today";
} else if (days < 2) {
result = "Yesterday";
} else {
result = days + " Days ago";
}

document.getElementById("hourpost").innerHTML = hours + "Hours Ago" ;
document.getElementById("daypost").innerHTML = result ;
</script>

для этого я сделал Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years ago В этом примере вы можете проанализировать дату, как 2018-09-05T06:40:46.183Z Это или любой другой, как ниже

Добавьте ниже значение в string.xml.

  <string name="lbl_justnow">Just Now</string>
    <string name="lbl_seconds_ago">seconds ago</string>
    <string name="lbl_min_ago">min ago</string>
    <string name="lbl_mins_ago">mins ago</string>
    <string name="lbl_hr_ago">hr ago</string>
    <string name="lbl_hrs_ago">hrs ago</string>
    <string name="lbl_day_ago">day ago</string>
    <string name="lbl_days_ago">days ago</string>
    <string name="lbl_lstweek_ago">last week</string>
    <string name="lbl_week_ago">weeks ago</string>
    <string name="lbl_onemonth_ago">1 month ago</string>
    <string name="lbl_month_ago">months ago</string>
    <string name="lbl_oneyear_ago" >last year</string>
    <string name="lbl_year_ago" >years ago</string>

Код Java попробую ниже

  public String getFormatDate(String postTime1) {
        Calendar cal=Calendar.getInstance();
        Date now=cal.getTime();
        String disTime="";
        try {
            Date postTime;
            //2018-09-05T06:40:46.183Z
            postTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(postTime1);

            long diff=(now.getTime()-postTime.getTime()+18000)/1000;

            //for months
            Calendar calObj = Calendar.getInstance();
            calObj.setTime(postTime);
            int m=calObj.get(Calendar.MONTH);
            calObj.setTime(now);

            SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); // output month

            int mNow = Integer.parseInt(monthFormatter.format(postTime));

            diff = diff-19800;

            if(diff<15) { //below 15 sec

                disTime = getResources().getString(R.string.lbl_justnow);
            } else if(diff<60) {

                //below 1 min
                disTime= diff+" "+getResources().getString(R.string.lbl_seconds_ago);
            } else if(diff<3600) {//below 1 hr

                // convert min
                long temp=diff/60;

                if(temp==1) {
                    disTime= temp + " " +getResources().getString(R.string.lbl_min_ago);
                } else {
                    disTime = temp  + " " +getResources().getString(R.string.lbl_mins_ago);
                }
            } else if(diff<(24*3600)) {// below 1 day

                // convert hr
                long temp= diff/3600;
                System.out.println("hey temp3:"+temp);
                if(temp==1) {
                    disTime = temp  + " " +getResources().getString(R.string.lbl_hr_ago);
                } else {
                    disTime = temp + " " +getResources().getString(R.string.lbl_hrs_ago);
                }
            } else if(diff<(24*3600*7)) {// below week

                // convert days
                long temp=diff/(3600*24);
                if (temp==1) {
                    //  disTime = "\nyesterday";
                    disTime = temp + " " +getResources().getString(R.string.lbl_day_ago);
                } else {
                    disTime = temp + " " +getResources().getString(R.string.lbl_days_ago);
                }
            } else if(diff<((24*3600*28))) {// below month

                // convert week
                long temp=diff/(3600*24*7);
                if (temp <= 4) {

                    if (temp < 1) {
                        disTime = getResources().getString(R.string.lbl_lstweek_ago);
                    }else{
                        disTime = temp + " " + getResources().getString(R.string.lbl_week_ago);
                    }

                } else {
                    int diffMonth = mNow - m;
                    Log.e("count : ", String.valueOf(diffMonth));
                    disTime = diffMonth + " " + getResources().getString(R.string.lbl_month_ago);
                }
            }else if(diff<((24*3600*365))) {// below year

                // convert month
                long temp=diff/(3600*24*30);

                System.out.println("hey temp2:"+temp);
                if (temp <= 12) {

                    if (temp == 1) {
                        disTime = getResources().getString(R.string.lbl_onemonth_ago);
                    }else{
                        disTime = temp + " " + getResources().getString(R.string.lbl_month_ago);
                    }
                }

            }else if(diff>((24*3600*365))) { // above year

                // convert year
                long temp=diff/(3600*24*30*12);

                System.out.println("hey temp8:"+temp);

                if (temp == 1) {
                    disTime = getResources().getString(R.string.lbl_oneyear_ago);
                }else{
                    disTime = temp + " " + getResources().getString(R.string.lbl_year_ago);
                }
            }

        } catch(Exception e) {
            e.printStackTrace();
        }

        return disTime;
    }

Вы можете использовать библиотеку Java RelativeDateTitimeFormatter., Это делает именно это:

RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance();
 fmt.format(1, Direction.NEXT, RelativeUnit.DAYS); // "in 1 day"
 fmt.format(3, Direction.NEXT, RelativeUnit.DAYS); // "in 3 days"
 fmt.format(3.2, Direction.LAST, RelativeUnit.YEARS); // "3.2 years ago"

 fmt.format(Direction.LAST, AbsoluteUnit.SUNDAY); // "last Sunday"
 fmt.format(Direction.THIS, AbsoluteUnit.SUNDAY); // "this Sunday"
 fmt.format(Direction.NEXT, AbsoluteUnit.SUNDAY); // "next Sunday"
 fmt.format(Direction.PLAIN, AbsoluteUnit.SUNDAY); // "Sunday"

 fmt.format(Direction.LAST, AbsoluteUnit.DAY); // "yesterday"
 fmt.format(Direction.THIS, AbsoluteUnit.DAY); // "today"
 fmt.format(Direction.NEXT, AbsoluteUnit.DAY); // "tomorrow"

 fmt.format(Direction.PLAIN, AbsoluteUnit.NOW); // "now"

Я использую мгновение, дату и datetimeutils. Дата (дата), которая хранится в базе данных в типе строки, а затем преобразовать, чтобы стать мгновенным.

    /*
    This method is to display ago.
    Example: 3 minutes ago.
    I already implement the latest which is including the Instant.
    Convert from String to Instant and then parse to Date.
     */
    public String convertTimeToAgo(String dataDate) {
    //Initialize
    String conversionTime = null;
    String suffix = "Yang Lalu";
    Date pastTime;
    //Parse from String (which is stored as Instant.now().toString()
    //And then convert to become Date
    Instant instant = Instant.parse(dataDate);
    pastTime = DateTimeUtils.toDate(instant);

    //Today date
    Date nowTime = new Date();

    long dateDiff = nowTime.getTime() - pastTime.getTime();
    long second = TimeUnit.MILLISECONDS.toSeconds(dateDiff);
    long minute = TimeUnit.MILLISECONDS.toMinutes(dateDiff);
    long hour = TimeUnit.MILLISECONDS.toHours(dateDiff);
    long day = TimeUnit.MILLISECONDS.toDays(dateDiff);

    if (second < 60) {
        conversionTime = second + " Saat " + suffix;
    } else if (minute < 60) {
        conversionTime = minute + " Minit " + suffix;
    } else if (hour < 24) {
        conversionTime = hour + " Jam " + suffix;
    } else if (day >= 7) {
        if (day > 30) {
            conversionTime = (day / 30) + " Bulan " + suffix;
        } else if (day > 360) {
            conversionTime = (day / 360) + " Tahun " + suffix;
        } else {
            conversionTime = (day / 7) + " Minggu " + suffix;
        }
    } else if (day < 7) {
        conversionTime = day + " Hari " + suffix;
    }
    return conversionTime;
    }

Java.Time.

То Ответ на Habsq. имеет правильную идею, но неправильные методы.

Для пропаганды неприкоснодованного к срокам в масштабе лет месяцев, используйте Period. Отказ В течение нескольких дней отображается 24-часовые кусочки времени, не связанные с календарем и часами - несколько секунд, используйте Duration. Отказ Смешивание двух весов редко имеет смысл.

Duration

Начните с получения текущего момента, как видно в универсальное глобальное время, с использованием Instant сорт.

Instant now = Instant.now();  // Capture the current moment as seen in UTC.
Instant then = now.minus( 8L , ChronoUnit.HOURS ).minus( 8L , ChronoUnit.MINUTES ).minus( 8L , ChronoUnit.SECONDS );
Duration d = Duration.between( then , now );

Создайте текст в течение нескольких часов, минут и секунды.

// Generate text by calling `to…Part` methods.
String output = d.toHoursPart() + " hours ago\n" + d.toMinutesPart() + " minutes ago\n" + d.toSecondsPart() + " seconds ago";

Дамп до консоли.

System.out.println( "From: " + then + " to: " + now );
System.out.println( output );

From: 2019-06-04T11: 53: 55.714965Z до: 2019-06-04T20: 02: 03.714965Z

8 часов назад

8 минут назад

8 секунд назад

Period

Начните с получения текущей даты.

Часовой пояс имеет решающее значение для определения даты. За любой данный момент дата варьируется по всему миру по зоне. Например, через несколько минут после полуночи в Париж, Франция это новый день, пока еще "вчера" в Монреаль, Квебек.

Если не указан часовой пояс, JVM неявно применяет его текущий часовой пояс по умолчанию. Что по умолчанию май изменить в любой момент Во время выполнения (!), поэтому ваши результаты могут варьироваться. Лучше указать желаемый / ожидаемый часовой пояс прямо в качестве аргумента. Если критично, подтвердите зону своим пользователем.

Укажите A. Название часового пояса в формате Continent/Region, Такие как America/Montreal, Africa/Casablanca, или Pacific/Auckland. Отказ Никогда не используйте сокращение 2-4 буквы, такие как EST или IST как они есть нет Истинные часовые пояса, не стандартизированные, а не уникальные (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Воссоздать дату восемь дней, месяцев и лет назад.

LocalDate then = today.minusYears( 8 ).minusMonths( 8 ).minusDays( 7 ); // Notice the 7 days, not 8, because of granularity of months. 

Рассчитать прошедшее время.

Period p = Period.between( then , today );

Построить строку «время назад».

String output = p.getDays() + " days ago\n" + p.getMonths() + " months ago\n" + p.getYears() + " years ago";

Дамп до консоли.

System.out.println( "From: " + then + " to: " + today );
System.out.println( output );

От: 2010-09-27 по: 2019-06-04

8 дней назад

8 месяцев назад

8 лет назад


О Java.Time.

То Java.Time. Рамки встроены в Java 8, а затем. Эти классы вытесняют проблему старого наследие Классы даты времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Чтобы узнать больше, см. Учебник Oracle. Отказ И поиск стека переполнения для многих примеров и пояснений. Спецификация JSR 310..

То Joda-Time Проект, сейчас в Режим технического обслуживания, советует миграцию к Java.Time. классы.

Вы можете обменять Java.Time. Объекты напрямую с вашей базой данных. Использовать JDBC драйвер совместимый с JDBC 4.2 или позже. Нет необходимости в струнах, нет необходимости в java.sql.* классы.

Где получить классы Java.Time?

То Threeten-Extra Проект расширяет Java.Time с дополнительными классами. Этот проект является доказательством для возможных будущих дополнений в Java.Time. Вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter, а также более.

Эта функция будет рассчитать ее в чистом Java, однако эта функция не показывает частичные "1 hour, 3 minutes", Он будет использовать наибольшую ценность контейнера (часы, дни, месяцы и т. Д.) Это может и раунд до ближайшего значения.

private String agoFromTime(long seconds) {
        long minutes = seconds / 60;
        long hours = seconds / 3600;
        long days = seconds / 86400;
        long years = seconds / (86400 * 365);

        String postfix;
        long result;
        if(years > 0) result = Math.round(seconds / (86400.0 * 365.0));
        else if(days > 0) result = Math.round(seconds / 86400.0);
        else if(hours > 0) result = Math.round(seconds / 3600.0);
        else if(minutes > 0) result = Math.round(seconds / 60.0);
        else result = seconds;

        if(years > 0) postfix = " year";
        else if(days > 0) postfix = " day";
        else if(hours > 0) postfix = " hour";
        else if(minutes > 0) postfix = " minute";
        else postfix = " second";

        return result + postfix + ((result != 1) ? "s" : "");
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top