关于日期:如何在Java中计算“时间之前”?

How to calculate “time ago” in Java?

在Ruby on Rails中,有一项功能允许您获取任何Date并打印出它的"很久以前"。

例如:

1
2
3
4
5
8 minutes ago
8 hours ago
8 days ago
8 months ago
8 years ago

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


看一下PrettyTime库。

使用起来非常简单:

1
2
3
4
5
import org.ocpsoft.prettytime.PrettyTime;

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

您还可以传递国际化消息的语言环境:

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

如评论中所述,Android在android.text.format.DateUtils类中内置了此功能。


您是否考虑过TimeUnit枚举?对于这种事情可能非常有用

1
2
3
4
5
6
7
8
9
10
11
12
13
    try {
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        Date past = format.parse("01/10/2010");
        Date now = new Date();

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


我接受RealHowTo和Ben J的答案,并制作自己的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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));
}}

这将打印以下内容

1
2
3
4
5
6
7
8
9
10
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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
  public class TimeUtils {

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

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

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

      public final static long ONE_DAY = ONE_HOUR * 24;

      private TimeUtils() {
      }

      /**
       * converts time (in milliseconds) to human-readable format
       * "<w> days, <x> hours, <y> minutes and (z) seconds"
       */

      public static String millisToLongDHMS(long duration) {
        StringBuffer res = new StringBuffer();
        long temp = 0;
        if (duration >= ONE_SECOND) {
          temp = duration / ONE_DAY;
          if (temp > 0) {
            duration -= temp * ONE_DAY;
            res.append(temp).append(" day").append(temp > 1 ?"s" :"")
               .append(duration >= ONE_MINUTE ?"," :"");
          }

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

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

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

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


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

    }
}

更多@将持续时间(以毫秒为单位)格式化为人类可读的格式


这基于RealHowTo的答案,因此,如果您喜欢它,也请给他/她一些爱。

此清理版本允许您指定可能感兴趣的时间范围。

它对"和"部分的处理也有所不同。我经常发现,使用分隔符连接字符串时,跳过复杂的逻辑并在完成后仅删除最后一个分隔符会更容易。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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();
    }
}

小代码让它旋转:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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("\
Again in only hours and minutes\
"
);

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

}

将输出以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
0 seconds
5 seconds
1 day and 1 hour
1 day and 2 seconds
1 day, 1 hour and 2 minutes
4 days, 3 hours, 2 minutes and 1 second
5 days, 4 hours, 1 minute and 23 seconds
42 days

Again in only hours and minutes

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

万一有人需要它,这是一个类,它将把上述字符串转换成毫秒。允许人们在可读文本中指定各种内容的超时非常有用。


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

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

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

而已..


关于内置解决方案:

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

在后一种情况下,我建议使用我的库Time4J(或Android上的Time4A)。它提供了最大的灵活性和最强大的功能。为此,类net.time4j.PrettyTime具有七个方法printRelativeTime...(...)。使用测试时钟作为时间源的示例:

1
2
3
4
5
6
7
8
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作为输入的另一个示例:

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

该库通过其最新版本(v4.17)支持80种语言,并且还支持某些国家/地区特定的语言环境(尤其是西班牙语,英语,阿拉伯语,法语)。 i18n数据主要基于最新的CLDR版本v29。使用此库的其他重要原因还包括对复数规则(在其他地区通常与英语不同的规则)的良好支持,缩写的格式样式(例如:" 1秒前")以及考虑时区的表达方式。 Time4J甚至在相对时间的计算中还知道诸如跳秒之类的奇特细节(虽然并不重要,但它形成了与期望范围相关的信息)。与Java-8的兼容性是由于java.time.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数据的未确认贡献。


如果您要查找简单的"今天","昨天"或" x天前"。

1
2
3
4
5
6
7
private String getDaysAgo(Date date){
    long days = (new Date().getTime() - date.getTime()) / 86400000;

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

java.time

使用Java 8及更高版本中内置的java.time框架。

1
2
3
4
5
6
7
8
9
10
LocalDateTime t1 = LocalDateTime.of(2015, 1, 1, 0, 0, 0);
LocalDateTime t2 = LocalDateTime.now();
Period period = Period.between(t1.toLocalDate(), t2.toLocalDate());
Duration duration = Duration.between(t1, t2);

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


基于此处的一系列答案,我为用例创建了以下内容。

用法示例:

1
2
String relativeDate = String.valueOf(
                TimeUtils.getRelativeTime( 1000L * myTimeInMillis() ));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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();
    }
}


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

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

如果您要开发用于Android的应用程序,它将为所有此类需求提供实用程序类DateUtils。看一下DateUtils#getRelativeTimeSpanString()实用程序方法。

来自的文档

CharSequence getRelativeTimeSpanString(时间长,现在很长,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".

您现在将传递timestamp作为时间,并传递System.currentTimeMillis()minResolution可让您指定要报告的最短时间。

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.


您可以使用此功能计算时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
 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以微秒为单位


joda-time程序包具有句点的概念。您可以使用Periods和DateTimes进行算术运算。

从文档:

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

java.time

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

对于未附加到时间轴上的年-月-日-天的时间范围,请使用Period。对于表示24小时时间段与日历和小时-分钟-秒无关的天,请使用Duration。混合两个音阶几乎没有任何意义。

Duration

首先使用Instant类获取UTC中所示的当前时刻。

1
2
3
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 );

生成小时,分钟和秒的文本。

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

转储到控制台。

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

首先获取当前日期。

时区对于确定日期至关重要。在任何给定时刻,日期都会在全球范围内变化。例如,法国巴黎午夜过后的几分钟是新的一天,而在魁北克蒙特利尔仍然是"昨天"。

如果未指定时区,则JVM隐式应用其当前的默认时区。该默认值可能会在运行时(!)期间随时更改,因此您的结果可能会有所不同。最好将您的期望/期望时区明确指定为参数。如果紧急,请与您的用户确认区域。

Continent/Region格式指定正确的时区名称,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用2-4个字母的缩写,例如ESTIST,因为它们不是真实的时区,不是标准化的,甚至不是唯一的(!)。

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

重新创建日期八天,几个月和几年前。

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

计算经过的时间。

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

构建"时间之前"片段的字符串。

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

转储到控制台。

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

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧版旧式日期时间类,例如java.util.DateCalendarSimpleDateFormat

要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。

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

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

  • Java SE 8,Java SE 9,Java SE 10,Java SE 11和更高版本-标准Java API的一部分,具有捆绑的实现。

    • Java 9添加了一些次要功能和修复。
  • Java SE 6和Java SE 7

    • 大多数Java.time功能都在ThreeTen-Backport中反向移植到Java 6和7。
  • 安卓系统

    • 更高版本的Android捆绑了java.time类的实现。
    • 对于早期的Android(<26),ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。请参阅如何使用ThreeTenABP…。

ThreeTen-Extra项目使用其他类扩展了java.time。该项目是将来可能向java.time添加内容的试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuarter等。


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


如果考虑性能,这是更好的代码,它减少了计算数量。
原因
仅当秒数大于60时才计算分钟数,仅当分钟数大于60时才计算小时数,依此类推...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class timeAgo {

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

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

}

}


经过长期的研究,我发现了这一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    public class GetTimeLapse {
    public static String getlongtoago(long createdAt) {
        DateFormat userDateFormat = new SimpleDateFormat("E MMM dd HH:mm:ss Z yyyy");
        DateFormat dateFormatNeeded = new SimpleDateFormat("MM/dd/yyyy HH:MM:SS");
        Date date = null;
        date = new Date(createdAt);
        String crdate1 = dateFormatNeeded.format(date);

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

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

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

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

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

            }

        }
        return time;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private const val SECOND_MILLIS = 1
private const val MINUTE_MILLIS = 60 * SECOND_MILLIS
private const val HOUR_MILLIS = 60 * MINUTE_MILLIS
private const val DAY_MILLIS = 24 * HOUR_MILLIS

object TimeAgo {

fun timeAgo(time: Int): String {

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

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

}

呼叫

val字符串= timeAgo(unixTimeStamp)

在Kotlin得到时间


对于Android
就像拉维所说的一样,但是由于很多人只想复制粘贴内容,所以就在这里。

1
2
3
4
5
6
7
8
9
  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("");
    }

给更多时间的人的解释

  • 您可以从某处获取数据。首先,您必须弄清楚它的格式。
  • 例如我从服务器获取数据的格式为
    2016年1月27日,星期三09:32:35 GMT [这可能不是您的情况]

    这被翻译成

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

    我怎么知道在此处阅读文档。

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

    如果您没有弄清楚正确的解析字符串,将会得到一个异常,例如:字符5处的异常。请看字符5,并更正您的初始解析字符串。正确的公式。


    如在Whatsapp通知中看到的,getrelativeDateTime函数将为您提供日期时间。
    要获取将来的相对日期时间,请为其添加条件。 这是专门为获取日期时间(如Whatsapp通知)而创建的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    private static String getRelativeDateTime(long date) {
        SimpleDateFormat DateFormat = new SimpleDateFormat("MMM dd, yyyy", Locale.getDefault());
        SimpleDateFormat TimeFormat = new SimpleDateFormat(" hh:mm a", Locale.getDefault());
        long now = Calendar.getInstance().getTimeInMillis();
        long startOfDay = StartOfDay(Calendar.getInstance().getTime());
        String Day ="";
        String Time ="";
        long millSecInADay = 86400000;
        long oneHour = millSecInADay / 24;
        long differenceFromNow = now - date;

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

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


    这是我的测试用例,希望对您有帮助:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
        val currentCalendar = Calendar.getInstance()
        currentCalendar.set(2019, 6, 2, 5, 31, 0)

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

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

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


    以下解决方案全部使用纯Java:

    选项1:不舍入,仅使用最大时间容器

    以下功能将仅显示最大的时间容器,例如,如果实际经过时间为"1 month 14 days ago",则此功能将仅显示"1 month ago"。此功能还将始终舍入,因此与"50 days ago"等效的时间将显示为"1 month"

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public String formatTimeAgo(long millis) {
            String[] ids = new String[]{"second","minute","hour","day","month","year"};

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

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

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

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

            return"0 seconds ago";
        }

    选项2:四舍五入

    只需用Math.round(...)语句包装要舍入的时间容器,因此,如果要将50 days舍入为2 months,请将long months = days / 30修改为long months = Math.round(days / 30.0)


    这是我的Java实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
        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();
        }
      }

    您可以使用Java的Library RelativeDateTimeFormatter,它确实可以做到:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    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"


    为此,在本示例中,我已经完成了Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years ago,您可以解析日期,例如2018-09-05T06:40:46.183Z this或下面的任何其他内容

    在string.xml中添加以下值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
      <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代码尝试下面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
      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 ="\
    yesterday";
                        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;
        }


    这是非常基本的脚本。它很容易即兴创作。
    结果:(过去XXX小时)或(过去XX天/昨天/今天)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <span id='hourpost'></span>
    ,or
    <span id='daypost'></span>


    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 ;

    这个对我有用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    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;
        } }

    由于缺乏简洁性和更新的响应,请遵循最新的Java 8及更高版本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import java.time.*;
    import java.time.temporal.*;

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

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

    该版本使用Java Time API尝试解决过去处理日期和时间的问题。

    Java文档

    版本8
    https://docs.oracle.com/javase/8/docs/api/index.html?java/time/package-summary.html

    版本11
    https://docs.oracle.com/cn/java/javase/11/docs/api/java.base/java/time/package-summary.html

    W3Schools教程-https://www.w3schools.com/java/java_date.asp

    DZone文章-https://dzone.com/articles/java-8-date-and-time


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
        /*
        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;
        }