Як обчислити "час тому" на Java?


127

У Ruby on Rails є функція, яка дозволяє взяти будь-яку дату і роздрукувати, як це було "давно".

Наприклад:

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

Чи є простий спосіб зробити це на Java?


1
Дивіться: stackoverflow.com/questions/11/how-do-i-calculate-relative-time Це C #, але я впевнений, що ви можете перетворити його з невеликими проблемами.
Брендон

Відповіді:


177

Погляньте на бібліотеку PrettyTime .

Це досить просто у використанні:

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клас.


229
У разі , якщо ви працюєте на Android ви можете використовувати це: android.text.format.DateUtils # getRelativeTimeSpanString ()
Somatik

Чи можете ви, будь ласка, додати ще якусь характеристику до своєї відповіді, відповідь лише на посилання наразі не годиться.
Ajay S

@Somatik, якщо вам потрібно отримати це на не-андроїд платформі, ви можете переглянути цей клас на AOSP.
greg7gkb

@ataylor як це використовувати в Android ??
Хардік Пармар

getRelativeTimeSpanString не ідеально підходить для всіх ситуацій, і саме тому я створив власний клас на основі безлічі прикладів. Дивіться моє рішення нижче: stackoverflow.com/a/37042254/468360
Codeversed

67

Чи розглядали ви перелічення TimeUnit ? Це може бути дуже корисно для подібних речей

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

4
Я не думаю, що це повноцінна відповідь, оскільки одиниці часу незалежні. Напр. - час у мілісекундах становить лише хвилини * 60 * 1000. Вам потрібно зменшити з кожної одиниці часу наступну більшу одиницю часу (після перетворення її на нижчу одиницю часу), щоб мати можливість використовувати її за "час тому" "рядок.
Nativ

@Benj - Це правильно? вище рішення? оскільки один раз у 12-годинному форматі, а інший - у 24-годинному форматі. Повідомте мені ваш відгук щодо мого запиту. Дякую за передовий.
Швидкий

це невірно, хоча ... кожна одиниця не залежить від іншого, як уже було сказано.
Джонатан Лаліберте

1
android робить це для вас. Якщо ви працюєте на android, ви можете використовувати це: android.text.format.DateUtils.getRelativeTimeSpanString (мілісекунд)
Wajid Ali

50

Я приймаю відповіді 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

Дійсно здорово. І насправді легко додати інші одиниці часу, такі як тиждень (ів)
Piotr,

1
ця заслуговує більшої кількості нагород. Перш за все, не потрібна бібліотека. Він все ще чистий, елегантний і легко змінюється.
fangzhzh

невеликий помилок: усередині коду ви посилаєтесь на статичні властивості "Списки" замість "TimeAgo". Lists.times.get (i) має бути TimeAgo.get (i) ... і так далі
Diogo Gomes

2
Невелика пропозиція: використовувати .append(temp != 1 ? "s" : "")замість того, .append(temp > 1 ? "s" : "")що 0 також повинен мати sсуфікс
berkus

1
@ShajeelAfzal так, параметр тривалості в мілісекундах, але це різниця між часом, не абсолютним значенням. Ви отримуєте час, який минув з 1 січня 1970 року з дати початку Unix часової позначки
Ріккардо Касатта

42
  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
         */
    }
}

докладніше @ Відформатуйте тривалість у мілісекундах у читаному для людини форматі


Я в кінцевому рахунку використовував переглянуту версію цього. Опублікував мої редакції для вас.
Девід Блевінс

5
Девід Blevins, більше прикладів про PrettyTime: stackoverflow.com/questions/3859288 / ... Big -1 для винаходити колесо ще раз і не рекомендує 3 - ї бібліотечний партія :-P
zakmck

9

Це ґрунтується на відповіді 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();
    }
}

Маленький код, щоб дати йому крутити:

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 

І на випадок, коли комусь це знадобиться, ось клас, який перетворить будь-який рядок, як описано вище, в мілісекунди . Це досить корисно, що дозволяє людям вказувати час очікування різних речей у читаному тексті.


9

є простий спосіб зробити це:

скажімо, ви хочете часу 20 хвилин тому:

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

Це воно..


1
У більшості випадків потрібно "розумний" дисплей, тобто. замість 5125 хвилин тому, ви кажете x днів тому.
PhiLho

7

Про вбудовані рішення:

У Java немає вбудованої підтримки для форматування відносно часу, також не Java-8 та її новий пакет java.time . Якщо вам потрібна лише англійська мова та більше нічого, і лише тоді рішення, виготовлене вручну, може бути прийнятним - дивіться відповідь @RealHowTo (хоча це має сильний недолік - не враховувати часовий пояс для перекладу миттєвих дельт на місцевий час одиниці!). У будь-якому випадку, якщо ви хочете уникати складних способів вирішення в домашніх умовах, особливо для інших місцевостей, вам потрібна зовнішня бібліотека.

В останньому випадку я рекомендую використовувати свою бібліотеку Time4J (або Time4A на Android). Він пропонує найбільшу гнучкість та найбільшу потужність i18n . Для цього у класі 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

Ця бібліотека підтримує 80 останніх версій (v4.17) 80 мов, а також деякі локальні мови (особливо для іспанської, англійської, арабської, французької). Дані i18n в основному базуються на новітній версії CLDR v29 . Інші важливі причини, чому слід використовувати цю бібліотеку, - це хороша підтримка множинних правил (які часто відрізняються від англійських в інших мовах), стилі скороченого формату (наприклад: "1 сек тому") та виразні способи врахування часових поясів . Time4J навіть усвідомлює такі екзотичні подробиці, як стрибкові секунди в розрахунках відносного часу (не дуже важливо, але це формує повідомлення, пов'язане з горизонтом очікування). Сумісність з Java-8існує завдяки легко доступним методам конверсії для типів, таких як java.time.Instantабо java.time.Period.

Чи є якісь недоліки? Лише два.

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

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

Якщо ви шукаєте менший спосіб вирішення і не потребуєте такої кількості функцій і готові терпіти можливі проблеми якості, пов'язані з i18n-даними, тоді:

  • Я б порекомендував ocpsoft / PrettyTime (підтримка фактично 32 мов (скоро 34?), java.util.DateЯкі підходять лише для роботи - див. Відповідь @ataylor). Галузевий стандарт CLDR (від консорціуму Unicode) з великим фоном спільноти, на жаль, не є базою даних i18n, тому подальше вдосконалення або вдосконалення даних може зайняти деякий час ...

  • Якщо ви перебуваєте на Android, то клас helper android.text.format.DateUtils - це тонка вбудована альтернатива (дивіться інші коментарі та відповіді тут, з недоліком, що він не підтримує роками та місяцями. І я впевнений, що лише дуже мало кому подобається API цього класу помічників.

  • Якщо ви шануєте Joda -Time, тоді ви можете подивитися на його клас PeriodFormat (підтримка 14 мов у випуску v2.9.4, з іншого боку: Joda-Time, напевно, теж не компактний, тому я згадую його тут лише для повнота). Ця бібліотека не є реальною відповіддю, оскільки відносні часи взагалі не підтримуються. Вам потрібно буде додати буквальне "назад" принаймні (і вручну зняти всі нижчі одиниці з створених форматів списку - незручно). На відміну від Time4J або Android-DateUtils, він не має спеціальної підтримки абревіатур або автоматичного перемикання з відносного часу на абсолютні часові уявлення. Як і PrettyTime, він повністю залежить від непідтвердженого внеску приватних членів спільноти Java у свої i18n-дані.


5

Якщо ви шукаєте прості "Сьогодні", "Вчора" або "х днів тому".

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

5

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

1
Ці Durationметоди повідомляють про всю тривалість як загальну кількість годин і як загальну кількість хвилин. У Java 8 класу як не дивно бракувало будь-яких методів, щоб отримати кожну частину години, хвилин і секунд. Java 9 приносить ті методи, to…Part.
Василь Бурк


4

Якщо ви розробляєте додаток для Android, він надає клас утиліти DateUtils для всіх таких вимог. Погляньте на утилітний метод DateUtils # getRelativeTimeSpanString () .

З документів для

CharSequence getRelativeTimeSpanString (давно, давно, довгий хв. Розв’язання)

Повертає рядок, що описує "час" як час відносно "зараз". Часи часу в минулому форматуються як "42 хвилини тому". Часи часу в майбутньому форматуються як "За 42 хвилини".

Ви будете пролітаючи повз , timestampяк час і , System.currentTimeMillis()як в даний час . minResolutionДозволяє визначити мінімальний TimeSpan повідомити.

Наприклад, час, минулий 3 секунди, буде повідомлятися як "0 хвилин тому", якщо для цього встановлено значення MINUTE_IN_MILLIS. Пройдіть один із 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS тощо


4

Ви можете використовувати цю функцію для обчислення часу тому

 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 знаходиться в мікросекунді


4

Спираючись на купу відповідей тут, я створив наступне для свого випадку використання.

Приклад використання:

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

Це дуже корисно, дуже дякую.
Akkad

3

Пакет joda-time , має поняття Періоди . Ви можете займатися арифметикою з періодами та датами.

З документів :

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


2

Це кращий код, якщо врахувати продуктивність. Це зменшує кількість обчислень. Причина Хвилини обчислюються лише в тому випадку, якщо кількість секунд більше 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";
                            }
                        }
                    }
                }
            }
        }
    }

}

}

1
Якщо ви працюєте на android, ви можете скористатися цим: android.text.format.DateUtils.getRelativeTimeSpanString (мілісекунд)
Wajid Ali

2

java.time

Відповіді на цей питання Habsq має правильну ідею , але неправильні методи.

Використовуйте для періоду часу, не пов’язаного з часовою шкалою в масштабі років-місяців-днів Period. Використовуйте дні, що означають цілодобові шматки часу, не пов'язані з календарем, і години-хвилини-секунди Duration. Змішування двох шкал рідко має сенс.

Duration

Почніть з виведення поточного моменту, як показано в UTC , використовуючи 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 );

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

8 годин тому

8 хвилин тому

8 секунд тому

Period

Почніть з отримання поточної дати.

Часовий пояс має вирішальне значення при визначенні дати. Для будь-якого моменту дата змінюється по всьому світу за зоною. Наприклад, через кілька хвилин після півночі у Парижі Франція - це новий день, а ще «вчора» в Монреалі Квебек .

Якщо часовий пояс не вказаний, JVM неявно застосовує поточний часовий пояс за замовчуванням. Цей дефолт може змінитися в будь-який момент під час виконання (!), Тому результати можуть відрізнятися. Краще вказати бажаний / очікуваний часовий пояс як аргумент. Якщо це критично, підтвердьте зону разом із користувачем.

Вкажіть правильний час ім'я зони в форматі 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, і більш .


Дуже дякую!
Тічергаз

1

Після довгих досліджень я виявив це.

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

1

Для Android Так само, як сказав Раві, але оскільки багато людей хочуть просто скопіювати вставити річ, ось вона є.

  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. Ви отримуєте дані звідкись. Спочатку ви повинні розібратися, що це формат.

Вих. Я отримую дані з сервера у форматі Wed, 27 Jan 2016 09:32:35 GMT [це, мабуть, НЕ ваш випадок]

це перекладається на

SimpleDateFormat формат = новий SimpleDateFormat ("EEE, dd MMM рр. Рр. HH: мм: ss Z");

як я це знаю? Прочитайте документацію тут.

Потім після розбору я отримую побачення. цю дату я вкладаю в getRelativeTimeSpanString (без будь-яких додаткових параметрів мені добре, за замовчуванням до хвилин)

Ви отримаєте виняток, якщо ви не з'ясували правильний синтаксичний аналіз рядка , щось на кшталт: виняток у символі 5 . Подивіться на символ 5 та виправте початковий рядок розбору. . Можливо, ви отримаєте інший виняток, повторіть ці кроки, поки не знайдете правильну формулу.


1
private const val SECOND_MILLIS = 1
private const val MINUTE_MILLIS = 60 * SECOND_MILLIS
private const val HOUR_MILLIS = 60 * MINUTE_MILLIS
private const val DAY_MILLIS = 24 * HOUR_MILLIS

object TimeAgo {

fun timeAgo(time: Int): String {

    val now = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())
    if (time > now || time <= 0) {
        return "in the future"
    }

    val diff = now - time
    return when {
        diff < MINUTE_MILLIS -> "Just now"
        diff < 2 * MINUTE_MILLIS -> "a minute ago"
        diff < 60 * MINUTE_MILLIS -> "${diff / MINUTE_MILLIS} minutes ago"
        diff < 2 * HOUR_MILLIS -> "an hour ago"
        diff < 24 * HOUR_MILLIS -> "${diff / HOUR_MILLIS} hours ago"
        diff < 48 * HOUR_MILLIS -> "yesterday"
        else -> "${diff / DAY_MILLIS} days ago"
    }
}

}

Дзвінок

val String = timeAgo (unixTimeStamp)

щоб дістати час тому в Котліні


0

Ось моя реалізація цього 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();
    }
  }

0

це працює для мене

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

0

Це самий базовий сценарій. його легко імпровізувати.
Результат: (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>

0

для цього я зробив 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;
    }

Якщо ви працюєте на android, ви можете скористатися цим: android.text.format.DateUtils.getRelativeTimeSpanString (мілісекундами)
Wajid Ali

0

Ви можете використовувати бібліотеку Java RelativeDateTimeFormatter Java , вона робить саме це:

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"

1
Це бібліотека Android, а не бібліотека Java.
Madbreaks

0

Я використовую Instant, Date та DateTimeUtils. Дані (дата), які зберігаються в базі даних типу String, а потім перетворюються в миттєві.

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

1
Ви використовуєте страшні старі класи, які були витіснені роками тому класами java.time .
Василь Бурк

@BasilBourque Я досі не можу знайти останній спосіб зробити це.
Тічергаз

@BasilBourque Я додав код, щоб зрозуміти його. github.com/ticherhaz/tarikhmasa
Тіхерхаз

0

Наступні рішення є в чистому Java:

Варіант 1: Без округлення та лише найбільший контейнер часу

Наступна функція відображатиме лише найбільший контейнер часу, наприклад, якщо справжній минувший час "1 month 14 days ago", ця функція відображатиметься лише "1 month ago". Ця функція також завжди буде округлена, тому час, еквівалентний часу "50 days ago", відображатиметься як"1 month"

public String formatTimeAgo(long millis) {
        String[] ids = new String[]{"second","minute","hour","day","month","year"};

        long seconds = millis / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        long days = hours / 24;
        long months = days / 30;
        long years = months / 12;

        ArrayList<Long> times = new ArrayList<>(Arrays.asList(years, months, days, hours, minutes, seconds));

        for(int i = 0; i < times.size(); i++) {
            if(times.get(i) != 0) {
                long value = times.get(i).intValue();

                return value + " " + ids[ids.length - 1 - i] + (value == 1 ? "" : "s") + " ago";
            }
        }

        return "0 seconds ago";
    }

Варіант 2: З округленням

Просто оберніть контейнер часу, який ви хочете округлити, оператором Math.round (...), тому, якщо ви хочете округлити 50 daysйого 2 months, змініть long months = days / 30наlong months = Math.round(days / 30.0)


1
Використовувати Durationйого to…Partметоди було б набагато простіше, як показано в моїй відповіді .
Василь Бурк

0

Ось мій тестовий випадок, сподіваюся, що це допоможе:

    val currentCalendar = Calendar.getInstance()
    currentCalendar.set(2019, 6, 2, 5, 31, 0)

    val targetCalendar = Calendar.getInstance()
    targetCalendar.set(2019, 6, 2, 5, 30, 0)

    val diffTs = currentCalendar.timeInMillis - targetCalendar.timeInMillis
    val diffMins = TimeUnit.MILLISECONDS.toMinutes(diffTs)
    val diffHours = TimeUnit.MILLISECONDS.toHours(diffTs)
    val diffDays = TimeUnit.MILLISECONDS.toDays(diffTs)
    val diffWeeks = TimeUnit.MILLISECONDS.toDays(diffTs) / 7
    val diffMonths = TimeUnit.MILLISECONDS.toDays(diffTs) / 30
    val diffYears = TimeUnit.MILLISECONDS.toDays(diffTs) / 365

    val newTs = when {
        diffYears >= 1 -> "Years $diffYears"
        diffMonths >= 1 -> "Months $diffMonths"
        diffWeeks >= 1 -> "Weeks $diffWeeks"
        diffDays >= 1 -> "Days $diffDays"
        diffHours >= 1 -> "Hours $diffHours"
        diffMins >= 1 -> "Mins $diffMins"
        else -> "now"
    }

1
Страшний Calendarклас витіснили роки тому сучасні класи java.time з прийняттям JSR 310 . Погана порада у 2019 році.
Василь Бурк

Ви, мабуть, мали на увазі var, ні val.
Василь Бурк

0

Функція getrelativeDateTime надасть вам час побачення, як ви бачите в повідомленні Whatsapp.
Щоб отримати майбутній відносний час, додайте для цього умови. Він створений спеціально для отримання часу, наприклад повідомлення Whatsapp.

private static String getRelativeDateTime(long date) {
    SimpleDateFormat DateFormat = new SimpleDateFormat("MMM dd, yyyy", Locale.getDefault());
    SimpleDateFormat TimeFormat = new SimpleDateFormat(" hh:mm a", Locale.getDefault());
    long now = Calendar.getInstance().getTimeInMillis();
    long startOfDay = StartOfDay(Calendar.getInstance().getTime());
    String Day = "";
    String Time = "";
    long millSecInADay = 86400000;
    long oneHour = millSecInADay / 24;
    long differenceFromNow = now - date;

    if (date > startOfDay) {
        if (differenceFromNow < (oneHour)) {
            int minute = (int) (differenceFromNow / (60000));
            if (minute == 0) {
                int sec = (int) differenceFromNow / 1000;
                if (sec == 0) {
                    Time = "Just Now";
                } else if (sec == 1) {
                    Time = sec + " second ago";
                } else {
                    Time = sec + " seconds ago";
                }
            } else if (minute == 1) {
                Time = minute + " minute ago";
            } else if (minute < 60) {
                Time = minute + " minutes ago";
            }
        } else {
            Day = "Today, ";
        }
    } else if (date > (startOfDay - millSecInADay)) {
        Day = "Yesterday, ";
    } else if (date > (startOfDay - millSecInADay * 7)) {
        int days = (int) (differenceFromNow / millSecInADay);
        Day = days + " Days ago, ";
    } else {
        Day = DateFormat.format(date);
    }
    if (Time.isEmpty()) {
        Time = TimeFormat.format(date);
    }
    return Day + Time;
}

public static long StartOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTimeInMillis();
}

Дякуємо, що хочете зробити свій внесок. Це не зовсім те, що просили, але, можливо, хтось може ним скористатися. Ні те, що хтось, ні хтось інший не повинен хотіти користуватися SimpleDateFormatі Calendarхоча. Ці класи погано розроблені та довго застаріли. Замість цього прочитайте відповіді, які використовують java.time, сучасний API дати та часу Java.
Оле В. В.

0

За відсутністю простоти та оновленої відповіді слідкуйте за новішою версією Java 8 та поза нею

import java.time.*;
import java.time.temporal.*;

public class Time {
    public static void main(String[] args) {

        System.out.println(LocalTime.now().minus(8, ChronoUnit.MINUTES));
        System.out.println(LocalTime.now().minus(8, ChronoUnit.HOURS));
        System.out.println(LocalDateTime.now().minus(8, ChronoUnit.DAYS));
        System.out.println(LocalDateTime.now().minus(8, ChronoUnit.MONTHS));
    }
}

Це версія, яка використовує API часу Java, який намагається вирішити проблеми минулого для роботи з датою та часом.

Javadoc

версія 8 https://docs.oracle.com/javase/8/docs/api/index.html?java/time/package-summary.html

версія 11 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html

Підручник для W3Schools - https://www.w3schools.com/java/java_date.asp

Стаття DZone - https://dzone.com/articles/java-8-date-and-time

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.