如何计算“时间之前”在Java中?

发布于 2024-09-26 10:01:42 字数 188 浏览 2 评论 0 原文

在 Ruby on Rails 中,有一个功能允许您获取任何日期并打印出它是“多久以前”的。

例如:

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

在 Java 中是否有一种简单的方法可以做到这一点?

In Ruby on Rails, there is a feature that allows you to take any Date and print out how "long ago" it was.

For example:

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

Is there an easy way to do this in Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

妄断弥空 2024-10-03 10:01:42

查看 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 类。

Take a look at the PrettyTime library.

It's quite simple to use:

import org.ocpsoft.prettytime.PrettyTime;

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

You can also pass in a locale for internationalized messages:

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

As noted in the comments, Android has this functionality built into the android.text.format.DateUtils class.

怀里藏娇 2024-10-03 10:01:42

您是否考虑过 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();
    }

Have you considered the TimeUnit enum? It can be pretty useful for this kind of thing

    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();
    }
浮生面具三千个 2024-10-03 10:01:42

我采用 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

I take RealHowTo and Ben J answers and make my own version:

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

which will print the following

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
吻安 2024-10-03 10:01: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) {
        StringBuilder res = new StringBuilder();
        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
         */
    }
}
  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) {
        StringBuilder res = new StringBuilder();
        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
         */
    }
}
寄风 2024-10-03 10:01:42

这是基于 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 

如果有人需要它,这里有一个类可以转换任何像上面这样的字符串 回到毫秒。它对于允许人们在可读文本中指定各种事物的超时非常有用。

This is based on RealHowTo's answer so if you like it, give him/her some love too.

This cleaned up version allows you to specify the range of time you might be interested in.

It also handles the " and " part a little differently. I often find when joining strings with a delimiter it's ofter easier to skip the complicated logic and just delete the last delimiter when you're done.

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

Little code to give it a 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));
        }
    }

}

Which will output the following:

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 

And in case anyone ever needs it, here's a class that will convert any string like the above back into milliseconds. It's pretty useful for allowing people to specify timeouts of various things in readable text.

撩发小公举 2024-10-03 10:01:42

有一个简单的方法可以做到这一点:

假设您想要 20 分钟前的时间:

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

就是这样..

there's a simple way to do this:

let's say you want the time 20 minutes ago:

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

that's it..

久而酒知 2024-10-03 10:01:42

关于内置解决方案:

Java 没有任何对格式化相对时间的内置支持,Java-8 及其新包 java.time< /代码>。如果您只需要英语而不需要其他任何东西,那么手工解决方案可能是可以接受的 - 请参阅@RealHowTo的答案(尽管它有一个很大的缺点,即不考虑将即时增量转换为本地时间的时区)单位!)。无论如何,如果您想避免本地开发的复杂解决方法,特别是对于其他语言环境,那么您需要一个外部库。

在后一种情况下,我建议使用我的库 Time4J (或 Android 上的 Time4A)。它提供最大的灵活性和最国际化的功能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-data 主要基于最新的 CLDR 版本 v29。使用此库的其他重要原因包括对复数规则的良好支持(这些规则通常与其他语言环境中的英语不同)、缩写格式样式(例如:“1 sec”前”)以及考虑时区的表达方式。 Time4J 甚至在相对时间的计算中意识到诸如闰秒之类的奇特细节(不是很重要,但它形成了与期望范围相关的消息)。 与 Java-8 的兼容性的存在是由于 java.time.Instantjava.time.Period 等类型易于使用的转换方法。

有什么缺点吗?只有两个。

  • 该图书馆并不小(也是因为其庞大的 i18n 数据存储库)。
  • 该 API 并不为人所知,因此无法获得社区知识和支持,否则提供的文档非常详细和全面。

(紧凑)替代方案:

如果您正在寻找更小的解决方案并且不需要那么多功能并且愿意容忍与 i18n-data 相关的可能的质量问题,那么:

  • 我会推荐ocpsoft/PrettyTime (支持实际上 32 种语言(很快 34 种?),仅适用于 java.util.Date - 请参阅 @ataylor 的答案)。不幸的是,具有庞大社区背景的行业标准 CLDR(来自 Unicode 联盟)并不是 i18n 数据的基础,因此数据的进一步增强或改进可能需要一段时间......

  • 如果您使用的是 Android,则帮助程序类android.text.format.DateUtils 是一个精简的内置替代方案(请参阅此处的其他评论和答案,其缺点是它不支持数年和数月。而且我确信只有极少数人们喜欢这个辅助类的 API 风格。

  • 如果您是 Joda-Time 的粉丝,那么您可以看看它的类PeriodFormat (在 v2.9.4 版本中支持 14 种语言,另一方面:Joda-Time 肯定也不紧凑,所以我在这里提到它只是为了完整性)这个库不是真正的答案,因为不支持相对时间。您至少需要附加文字“前”(并手动从生成的列表格式中删除所有较低的单位 - 与 Time4J 或 Android-DateUtils 不同,它没有对缩写或从相对时间自动切换的特殊支持。到绝对时间表示。与 PrettyTime 一样,它完全依赖于 Java 社区私人成员对其 i18n 数据未经证实的贡献。

About built-in solutions:

Java does not have any built-in support for formatting relative times, also not Java-8 and its new package java.time. If you only need English and nothing else then and only then a hand-made solution might be acceptable - see the answer of @RealHowTo (although it has the strong disadvantage to not take into account the timezone for the translation of instant deltas to local time units!). Anyway, if you want to avoid home-grown complex workarounds especially for other locales then you need an external library.

In latter case, I recommend to use my library Time4J (or Time4A on Android). It offers greatest flexibility and most i18n-power. The class net.time4j.PrettyTime has seven methods printRelativeTime...(...) for this purpose. Example using a test clock as time source:

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)

Another example using java.time.Instant as input:

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

This library supports via its latest version (v4.17) 80 languages and also some country-specific locales (especially for Spanish, English, Arabic, French). The i18n-data is mainly based on the newest CLDR-version v29. Other important reasons why to use this library are good support for plural rules (which are often different from English in other locales), abbreviated format style (for example: "1 sec ago") and expressive ways for taking into account timezones. Time4J is even aware of such exotic details like leap seconds in calculations of relative times (not really important but it forms a message related to the expectation horizon). The compatibility with Java-8 exists due to easily available conversion methods for types like java.time.Instant or java.time.Period.

Are there any drawbacks? Only two.

  • The library is not small (also because of its big i18n-data repository).
  • The API is not well known so community knowledge and support are not available yet otherwise the supplied documentation is pretty detailed and comprehensive.

(Compact) alternatives:

If you look for a smaller solution and don't need so many features and are willing to tolerate possible quality issues related to i18n-data then:

  • I would recommend ocpsoft/PrettyTime (support for actually 32 languages (soon 34?) suitable for work with java.util.Date only - see the answer of @ataylor). The industry standard CLDR (from Unicode consortium) with its big community background is unfortunately not a base of the i18n-data so further enhancements or improvements of data can take a while...

  • If you are on Android then the helper class android.text.format.DateUtils is a slim built-in alternative (see other comments and answers here, with the disadvantage that it has no support for years and months. And I am sure that only very few people like the API-style of this helper class.

  • If you are a fan of Joda-Time then you can look at its class PeriodFormat (support for 14 languages in release v2.9.4, on the other side: Joda-Time is surely not compact, too, so I mention it here just for completeness). This library is not a real answer because relative times are not supported at all. You will need to append the literal " ago" at least (and manually stripping off all lower units from generated list formats - awkward). Unlike Time4J or Android-DateUtils, it has no special support for abbreviations or automatic switching from relative times to absolute time representations. Like PrettyTime, it is totally dependent on the unconfirmed contributions of private members of the Java-community to its i18n-data.

淡墨 2024-10-03 10:01:42

java.time

Habsq 的回答有正确的想法,但方法错误。

对于不附加到年-月-日时间线的时间跨度,请使用 期间。对于表示与日历和小时-分钟-秒无关的 24 小时时间段的日期,请使用 持续时间。混合这两种尺度几乎没有任何意义。

Duration

首先使用 UTC 获取当前时刻,使用即时< /code> 类。

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 会隐式应用其当前的默认时区。该默认值可能在运行时随时更改(!),因此您的结果可能会有所不同。最好明确指定您想要/预期的时区作为参数。如果重要,请与您的用户确认该区域。

大陆/地区格式指定正确的时区名称,例如美洲/蒙特利尔非洲/卡萨布兰卡太平洋/奥克兰。切勿使用 2-4 个字母的缩写,例如 ESTIST,因为它们不是真实时区,不是标准化的,甚至不是唯一的(!)。

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日历,& SimpleDateFormat

要了解更多信息,请参阅 Oracle 教程 。并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310

Joda-Time 项目,现已在 维护模式,建议迁移到 java.time 类。

您可以直接与数据库交换java.time对象。使用符合 JDBC 驱动程序 jeps/170" rel="noreferrer">JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* 类。

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 Interval YearWeek YearQuarter ,以及更多

java.time

The Answer by Habsq has the right idea but the wrong methods.

For a span-of-time unattached to the timeline on the scale of years-months-days, use Period. For days meaning 24-hour chunks of time unrelated to calendar and hours-minutes-seconds, use Duration. Mixing the two scales rarely makes any sense.

Duration

Start by fetching the current moment as seen in UTC, using the Instant class.

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 for hours, minutes, and seconds.

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

Dump to console.

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

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

8 hours ago

8 minutes ago

8 seconds ago

Period

Start by getting the current date.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If critical, confirm the zone with your user.

Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true-time zones, not standardized, and not even unique(!).

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

Recreate a date eight days, months, and years ago.

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

Calculate elapsed time.

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

Build the string of "time ago" pieces.

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

Dump to console.

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

From: 2010-09-27 to: 2019-06-04

8 days ago

8 months ago

8 years ago


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

深居我梦 2024-10-03 10:01:42

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.time

Using the java.time framework built into Java 8 and later.

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");
凉城已无爱 2024-10-03 10:01:42

根据这里的一堆答案,我为我的用例创建了以下内容。

用法示例:

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

Based on a bunch of answers here, I created the following for my use case.

Example usage:

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();
    }
}
好久不见√ 2024-10-03 10:01:42

如果您正在寻找简单的“今天”、“昨天”或“x 天前”。

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

If you looking for a simple "Today", "Yesterday" or "x days ago".

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";
}
方觉久 2024-10-03 10:01:42

对于安卓:

public static String getTimeAgoFormat(long timestamp) {
    return android.text.format.DateUtils.getRelativeTimeSpanString(timestamp).toString();
}

For Android:

public static String getTimeAgoFormat(long timestamp) {
    return android.text.format.DateUtils.getRelativeTimeSpanString(timestamp).toString();
}
樱娆 2024-10-03 10:01:42

我创建了一个简单的 Java timeago 端口 jquery-timeago 插件可以满足您的要求。

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

I created a simple Java timeago port of the jquery-timeago plug-in that does what you are asking for.

TimeAgo time = new TimeAgo();
String minutes = time.timeAgo(System.currentTimeMillis() - (15*60*1000)); // returns "15 minutes ago"
寂寞美少年 2024-10-03 10:01:42

如果您正在开发 Android 应用程序,它会提供实用程序类 DateUtils 满足所有此类要求。看一下 DateUtils #getRelativeTimeSpanString() 实用方法。

的文档

来自CharSequence getRelativeTimeSpanString (long time, long now, long minResolution)

返回一个字符串,将“时间”描述为相对于“现在”的时间。过去的时间跨度的格式类似于“42 分钟前”。未来的时间跨度的格式类似于“42 分钟内”。

您将把 timestamp 作为 time 传递,将 System.currentTimeMillis() 作为 now 传递。 minResolution 允许您指定要报告的最小时间跨度。

例如,如果设置为 MINUTE_IN_MILLIS,则过去 3 秒的时间将报告为“0 分钟前”。通过 0、MINUTE_IN_MILLIS、HOUR_IN_MILLIS、DAY_IN_MILLIS、WEEK_IN_MILLIS 等之一。

In case you're developing an app for Android, it provides the utility class DateUtils for all such requirements. Take a look at the DateUtils#getRelativeTimeSpanString() utility method.

From the docs for

CharSequence getRelativeTimeSpanString (long time, long now, long minResolution)

Returns a string describing 'time' as a time relative to 'now'. Time spans in the past are formatted like "42 minutes ago". Time spans in the future are formatted like "In 42 minutes".

You'll be passing your timestamp as time and System.currentTimeMillis() as now. The minResolution lets you specify the minimum timespan to report.

For example, a time 3 seconds in the past will be reported as "0 minutes ago" if this is set to MINUTE_IN_MILLIS. Pass one of 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS etc.

奈何桥上唱咆哮 2024-10-03 10:01:42

joda-time 包具有 期间。您可以使用周期和日期时间进行算术运算。

来自文档

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

The joda-time package, has the notion of Periods. You can do arithmetic with Periods and DateTimes.

From the docs:

public boolean isRentalOverdue(DateTime datetimeRented) {
  Period rentalPeriod = new  Period().withDays(2).withHours(12);
  return datetimeRented.plus(rentalPeriod).isBeforeNow();
}
你是我的挚爱i 2024-10-03 10:01:42

您可以使用此函数来计算 time ago

 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 的单位是微秒

You Can use this function to calculate time ago

 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) Here time_ago is in microsecond

宁愿没拥抱 2024-10-03 10:01:42
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"
    }
}

在 Kotlin 中调用

val String = timeAgo(unixTimeStamp)

获取之前的时间

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

}

Call

val String = timeAgo(unixTimeStamp)

to get the time ago in Kotlin

皇甫轩 2024-10-03 10:01:42

它并不漂亮......但我能想到的最接近的是使用 Joda-Time (如这篇文章中所述:如何使用 Joda Time 计算从现在开始经过的时间?

It's not pretty...but the closest I can think of is using Joda-Time (as described in this post: How to calculate elapsed time from now with Joda Time?

下壹個目標 2024-10-03 10:01:42

如果我们考虑性能,这是一个更好的代码。它减少了计算次数。
原因
仅当秒数大于 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";
                            }
                        }
                    }
                }
            }
        }
    }

}

}

This is a better code if we consider performance.It reduces the number of calculations.
Reason
Minutes are calculated only if the number of seconds is greater than 60 and Hours are calculated only if the number of minutes is greater than 60 and so on...

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

}

}
吃颗糖壮壮胆 2024-10-03 10:01:42

java.time

您可以使用 java.time.Durationjava.time.Period 仿照 ISO-8601 标准,并作为 JSR-310 实现Java-9 引入了一些更方便的方法。

  1. 使用Duration 计算基于时间的数量或时间量。可以使用基于持续时间的单位来访问它,例如纳秒、秒、分钟和小时。此外,DAYS 可以使用单位并被视为恰好等于 24 小时,从而忽略夏令时影响。
  2. 使用Period 计算基于日期的时间量。可以使用基于时间段的单位(例如天、月和年)来访问它。

演示:

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Month;

public class Main {
    public static void main(String[] args) {
        // An arbitrary local date and time
        LocalDateTime startDateTime = LocalDateTime.of(2020, Month.DECEMBER, 10, 15, 20, 25);

        // Current local date and time
        LocalDateTime endDateTime = LocalDateTime.now();

        Duration duration = Duration.between(startDateTime, endDateTime);
        // Default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
                duration.toDays(), duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
                duration.toNanos() % 1000000000);
        System.out.println(formattedElapsedTime);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
                duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
                duration.toNanosPart());
        System.out.println(formattedElapsedTime);
        // ##############################################################################
    }
}

输出:

PT1395H35M7.355288S
58 days, 3 hours, 35 minutes, 7 seconds, 355288000 nanoseconds ago
58 days, 3 hours, 35 minutes, 7 seconds, 355288000 nanoseconds ago

如果您在 UTC 处有两个时刻,则可以使用 Instant 而不是 LocalDateTime 例如

import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

public class Main {
    public static void main(String[] args) {
        // Current moment at UTC
        Instant now = Instant.now();

        // An instant in the past
        Instant startDateTime = now.minus(58, ChronoUnit.DAYS)
                                .minus(2, ChronoUnit.HOURS)
                                .minus(54, ChronoUnit.MINUTES)
                                .minus(24, ChronoUnit.SECONDS)
                                .minus(808624000, ChronoUnit.NANOS);

        Duration duration = Duration.between(startDateTime, now);
        // Default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
                duration.toDays(), duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
                duration.toNanos() % 1000000000);
        System.out.println(formattedElapsedTime);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
                duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
                duration.toNanosPart());
        System.out.println(formattedElapsedTime);
        // ##############################################################################
    }
}

输出:

PT1394H54M24.808624S
58 days, 2 hours, 54 minutes, 24 seconds, 808624000 nanoseconds ago
58 days, 2 hours, 54 minutes, 24 seconds, 808624000 nanoseconds ago

演示Period

import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        // Replace ZoneId.systemDefault() with the applicable timezone ID e.g.
        // ZoneId.of("Europe/London"). For LocalDate in the JVM's timezone, simply use
        // LocalDate.now()
        LocalDate endDate = LocalDate.now(ZoneId.systemDefault());

        // Let's assume the start date is 1 year, 2 months, and 3 days ago
        LocalDate startDate = endDate.minusYears(1).minusMonths(2).minusDays(3);

        Period period = Period.between(startDate, endDate);
        // Default format
        System.out.println(period);

        // Custom format
        String formattedElapsedPeriod = String.format("%d years, %d months, %d days ago", period.getYears(),
                period.getMonths(), period.getDays());
        System.out.println(formattedElapsedPeriod);
    }
}

输出:

P1Y2M3D
1 years, 2 months, 3 days ago

了解现代日期时间 API 跟踪:日期时间

java.time

You can use java.time.Duration and java.time.Period which are modelled on ISO-8601 standards and were introduced with Java-8 as part of JSR-310 implementation. With Java-9 some more convenience methods were introduced.

  1. Use Duration to calculate a time-based quantity or amount of time. It can be accessed using duration-based units, such as nanoseconds, seconds, minutes and hours. In addition, the DAYS unit can be used and is treated as exactly equal to 24 hours, thus ignoring daylight savings effects.
  2. Use Period to calculate a date-based amount of time. It can be accessed using period-based units, such as days, months and years.

Demo:

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Month;

public class Main {
    public static void main(String[] args) {
        // An arbitrary local date and time
        LocalDateTime startDateTime = LocalDateTime.of(2020, Month.DECEMBER, 10, 15, 20, 25);

        // Current local date and time
        LocalDateTime endDateTime = LocalDateTime.now();

        Duration duration = Duration.between(startDateTime, endDateTime);
        // Default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
                duration.toDays(), duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
                duration.toNanos() % 1000000000);
        System.out.println(formattedElapsedTime);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
                duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
                duration.toNanosPart());
        System.out.println(formattedElapsedTime);
        // ##############################################################################
    }
}

Output:

PT1395H35M7.355288S
58 days, 3 hours, 35 minutes, 7 seconds, 355288000 nanoseconds ago
58 days, 3 hours, 35 minutes, 7 seconds, 355288000 nanoseconds ago

If you have two moments at UTC, you can use Instant instead of LocalDateTime e.g.

import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

public class Main {
    public static void main(String[] args) {
        // Current moment at UTC
        Instant now = Instant.now();

        // An instant in the past
        Instant startDateTime = now.minus(58, ChronoUnit.DAYS)
                                .minus(2, ChronoUnit.HOURS)
                                .minus(54, ChronoUnit.MINUTES)
                                .minus(24, ChronoUnit.SECONDS)
                                .minus(808624000, ChronoUnit.NANOS);

        Duration duration = Duration.between(startDateTime, now);
        // Default format
        System.out.println(duration);

        // Custom format
        // ####################################Java-8####################################
        String formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
                duration.toDays(), duration.toHours() % 24, duration.toMinutes() % 60, duration.toSeconds() % 60,
                duration.toNanos() % 1000000000);
        System.out.println(formattedElapsedTime);
        // ##############################################################################

        // ####################################Java-9####################################
        formattedElapsedTime = String.format("%d days, %d hours, %d minutes, %d seconds, %d nanoseconds ago",
                duration.toDaysPart(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart(),
                duration.toNanosPart());
        System.out.println(formattedElapsedTime);
        // ##############################################################################
    }
}

Output:

PT1394H54M24.808624S
58 days, 2 hours, 54 minutes, 24 seconds, 808624000 nanoseconds ago
58 days, 2 hours, 54 minutes, 24 seconds, 808624000 nanoseconds ago

Demo on Period:

import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;

public class Main {
    public static void main(String[] args) {
        // Replace ZoneId.systemDefault() with the applicable timezone ID e.g.
        // ZoneId.of("Europe/London"). For LocalDate in the JVM's timezone, simply use
        // LocalDate.now()
        LocalDate endDate = LocalDate.now(ZoneId.systemDefault());

        // Let's assume the start date is 1 year, 2 months, and 3 days ago
        LocalDate startDate = endDate.minusYears(1).minusMonths(2).minusDays(3);

        Period period = Period.between(startDate, endDate);
        // Default format
        System.out.println(period);

        // Custom format
        String formattedElapsedPeriod = String.format("%d years, %d months, %d days ago", period.getYears(),
                period.getMonths(), period.getDays());
        System.out.println(formattedElapsedPeriod);
    }
}

Output:

P1Y2M3D
1 years, 2 months, 3 days ago

Learn about the modern date-time API from Trail: Date Time.

提笔落墨 2024-10-03 10:01:42

经过长时间的研究我发现了这一点。

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

After long research i found this.

    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;
    }
}
望她远 2024-10-03 10:01:42

您可以使用Java的库RelativeDateTimeFormatter,它正是这样做的:

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"

You can use Java's Library RelativeDateTimeFormatter, it does exactly that:

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"
半枫 2024-10-03 10:01:42

SQL 时间戳到当前已用时间。设置您自己的时区。

注意1:这将处理单数/复数。

注2:这是使用 Joda 时间

String getElapsedTime(String strMysqlTimestamp) {
    
    DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.S");
    DateTime mysqlDate = formatter.parseDateTime(strMysqlTimestamp).
                         withZone(DateTimeZone.forID("Asia/Kuala_Lumpur"));
    
    DateTime now = new DateTime();
    Period period = new Period(mysqlDate, now);
    
    int seconds = period.getSeconds();
    int minutes = period.getMinutes();
    int hours = period.getHours();
    int days = period.getDays();
    int weeks = period.getWeeks();
    int months = period.getMonths();
    int years = period.getYears();
    
    String elapsedTime = "";
    if (years != 0)
        if (years == 1)
            elapsedTime = years + " year ago";
        else
            elapsedTime = years + " years ago";
    else if (months != 0)
        if (months == 1)
            elapsedTime = months + " month ago";
        else
            elapsedTime = months + " months ago";
    else if (weeks != 0)
        if (weeks == 1)
            elapsedTime = weeks + " week ago";
        else
            elapsedTime = weeks + " weeks ago";
    else if (days != 0)
        if (days == 1)
            elapsedTime = days + " day ago";
        else
            elapsedTime = days + " days ago";
    else if (hours != 0)
        if (hours == 1)
            elapsedTime = hours + " hour ago";
        else
            elapsedTime = hours + " hours ago";
    else if (minutes != 0)
        if (minutes == 1)
            elapsedTime = minutes + " minute ago";
        else
            elapsedTime = minutes + " minutes ago";
    else if (seconds != 0)
        if (seconds == 1)
            elapsedTime = seconds + " second ago";
        else
            elapsedTime = seconds + " seconds ago";   
    
    return elapsedTime;
}

SQL timestamp to now elapsed time. Set your own timezone.

NOTE1: This will handle singular/plural.

NOTE2: This is using Joda time

String getElapsedTime(String strMysqlTimestamp) {
    
    DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.S");
    DateTime mysqlDate = formatter.parseDateTime(strMysqlTimestamp).
                         withZone(DateTimeZone.forID("Asia/Kuala_Lumpur"));
    
    DateTime now = new DateTime();
    Period period = new Period(mysqlDate, now);
    
    int seconds = period.getSeconds();
    int minutes = period.getMinutes();
    int hours = period.getHours();
    int days = period.getDays();
    int weeks = period.getWeeks();
    int months = period.getMonths();
    int years = period.getYears();
    
    String elapsedTime = "";
    if (years != 0)
        if (years == 1)
            elapsedTime = years + " year ago";
        else
            elapsedTime = years + " years ago";
    else if (months != 0)
        if (months == 1)
            elapsedTime = months + " month ago";
        else
            elapsedTime = months + " months ago";
    else if (weeks != 0)
        if (weeks == 1)
            elapsedTime = weeks + " week ago";
        else
            elapsedTime = weeks + " weeks ago";
    else if (days != 0)
        if (days == 1)
            elapsedTime = days + " day ago";
        else
            elapsedTime = days + " days ago";
    else if (hours != 0)
        if (hours == 1)
            elapsedTime = hours + " hour ago";
        else
            elapsedTime = hours + " hours ago";
    else if (minutes != 0)
        if (minutes == 1)
            elapsedTime = minutes + " minute ago";
        else
            elapsedTime = minutes + " minutes ago";
    else if (seconds != 0)
        if (seconds == 1)
            elapsedTime = seconds + " second ago";
        else
            elapsedTime = seconds + " seconds ago";   
    
    return elapsedTime;
}
身边 2024-10-03 10:01:42

适用于 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. 您从某个地方获取数据。首先,你必须弄清楚它的格式。

前任。我从服务器获取以下格式的数据
2016 年 1 月 27 日星期三 09:32:35 GMT [这可能不是你的情况]

这被翻译成

SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");

我怎么知道呢?阅读 此处的文档。

然后在解析它之后我得到一个日期。我在 getRelativeTimeSpanString 中输入的日期(没有任何附加参数对我来说很好,默认为分钟)

如果您没有找出正确的解析字符串,您将得到一个异常 strong>,类似字符 5 的异常。 查看字符 5,并更正您的初始解析字符串。。您可能会遇到另一个异常,请重复这些步骤,直到获得正确的公式。

For Android
Exactly like Ravi said, but since lots of people want to just copy-paste the thing here it is.

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

Explanation for people that have more time

  1. You get the data from somewhere. First, you have to figure out its format.

Ex. I get the data from a server in the format
Wed, 27 Jan 2016 09:32:35 GMT [this is probably NOT your case]

this is translated into

SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");

how do I know it? Read the documentation here.

Then after I parse it I get a date. that date I put in the getRelativeTimeSpanString (without any additional parameters is fine by me, to default to minutes)

You WILL get an exception if you didn't figure out the correct parsing String, Something like exception at character 5. Look at character 5, and correct your initial parsing string.. You might get another exception, repeat these steps until you have the correct formula.

千年*琉璃梦 2024-10-03 10:01:42

这是我的 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();
    }
  }

Here is my Java Implementation of this

    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();
    }
  }
寂寞清仓 2024-10-03 10:01:42

这对我有用

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

it works for me

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;
    } }
哎呦我呸! 2024-10-03 10:01:42

这是非常基本的脚本。它很容易即兴创作。
结果:(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>

This is the very basic script. its easy to improvized.
Result : (XXX Hours Ago), or (XX Days Ago/Yesterday/Today)

<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>
风尘浪孓 2024-10-03 10:01:42

为此,我已经完成了刚刚、几秒前、几分钟前、几小时前、几天前、几周前、几个月前、几年前,在此示例中,您可以像 2018-09 一样解析日期-05T06:40:46.183Z 这个或任何其他类似的

中添加以下值尝试下面

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

string.xml 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;
    }

for this I've done Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years ago in this example you can parse date like 2018-09-05T06:40:46.183Z this or any other like below

add below value in 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 code try below

  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;
    }
埖埖迣鎅 2024-10-03 10:01:42

我正在使用 Instant、Date 和 DateTimeUtils。
将数据(日期)以String类型存储在数据库中,然后转换为Instant。

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

I'm using the Instant, Date and DateTimeUtils.
The data (date) which is stored in the database in type of String and then convert to become Instant.

    /*
    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;
    }
時窥 2024-10-03 10:01:42

以下解决方案均采用纯 Java:

选项 1:不舍入,仅显示最大时间容器

以下函数将仅显示最大时间容器,例如,如果真实的经过时间为 “1 个月 14 天前”< /code>,该函数只会显示“1个月前”。此函数也将始终向下舍入,因此相当于 “50 天前” 的时间将显示为 “1 个月”

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 天 舍入为 2 个月,请修改 long Months =天 / 30长月 = Math.round(days / 30.0)

The following solutions are all in pure Java:

Option 1: No rounding and only largest time container

The following function will only display the largest time container, for example, if the true elapsed time is "1 month 14 days ago", this function will only display "1 month ago". This function will also always round down, so a time equivalent to "50 days ago" will display as "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";
    }

Option 2: With rounding

Simply wrap the time container you'd like to round with a Math.round(...) statement, so if you wanted to round 50 days to 2 months, modify long months = days / 30 to long months = Math.round(days / 30.0)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文