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

在 RubyonRails 中,有一个特性允许你获取任何日期并打印出它的“很久以前”。

例如:

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

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

117364 次浏览

看一下 美好时光库。

它的使用非常简单:

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类中内置了这个功能。

Joda 时间包包含了 经期的概念。您可以对句点和日期时间进行算术运算。

来自 医生:

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

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

你有没有考虑过 时间单位枚举? 它可以是非常有用的这类事情

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

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

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

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

我为 Jquery-timeago插件创建了一个简单的 很久以前的爪哇咖啡端口,可以满足您的要求。

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

有个简单的方法:

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

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

就是这样。

如果你在寻找一个简单的“今天”,“昨天”或“ 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";
}

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

爪哇时间

使用内置在 Java8及更高版本中的 爪哇时间框架。

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

经过长时间的研究,我发现了这个。

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

如果你正在为 Android 开发一个应用程序,它为所有这些需求提供了实用类 日期工具。看一下 DateUtils#getRelativeTimeSpanString()实用程序方法。

从医生那里拿到的

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

返回一个字符串,该字符串将“ time”描述为相对于“ now”的时间。过去的时间跨度格式类似于“42分钟前”。未来的时间跨度被格式化为“42分钟后”。

你将以 时间的形式传递 timestamp,以 现在的形式传递 System.currentTimeMillis()minResolution允许您指定要报告的最小时间跨度。

例如,如果设置为 MINUTE _ IN _ MILLIS,过去3秒的时间将报告为“0分钟前”。传递0,MINUTE _ IN _ Millis,HOUR _ IN _ Millis,DAY _ IN _ Millis,WEEK _ IN _ Millis 等。

关于 内置的解决方案:

Java 没有任何格式化相对时间的内置支持,Java-8和它的新包 java.time也没有。如果你只需要英语而不需要其他任何东西,只有这样手工制作的解决方案才是可以接受的——看看@RealHowTo 的答案(尽管它有一个很大的缺点,那就是没有考虑到将即时增量转换成本地时间单位的时区.无论如何,如果您想避免自己开发的复杂工作区,特别是对于其他地区,那么您需要一个外部库。

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

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

另一个使用 java.time.Instant作为输入的例子:

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

这个库通过其最新版本(v4.17) 80种语言和一些特定于国家的语言环境(特别是西班牙语、英语、阿拉伯语、法语)提供支持。I18n 数据主要基于 最新的 CLDR 版本29。为什么要使用这个库的其他重要原因是好的 支持复数规则(在其他地区通常不同于英语) ,缩写格式样式缩写格式样式(例如: “1秒前”)和 考虑到时区的表达方式。Time4J 甚至在计算相对时间时注意到了像 闰秒这样的奇特细节(这并不重要,但是它形成了一个与期望视界相关的消息)。与 Java-8的兼容性之所以存在,是因为像 java.time.Instantjava.time.Period这样的类型很容易获得转换方法。

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

  • 这个库不小(也是因为它的 i18n 数据存储库很大)。
  • API 并不为人所知,因此社区知识和支持尚不可用,否则所提供的文档是相当详细和全面的。

(紧凑型)替代品:

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

  • 我建议使用 Ocpsoft/PrettyTime(实际上支持32种语言(即将到来的34种?)仅适用于 java.util.Date工作-请参阅@ataylor 的答案)。不幸的是,拥有庞大社区背景的行业标准 CLDR (来自统一码联盟)并不是 i18n 数据的基础,因此进一步增强或改进数据可能需要一段时间... ..。

  • 如果你使用的是 Android 系统,那么 helper 类 Format. DateUtils是一个内置的瘦身替代品(请参阅其他评论和答案,缺点是它已经几年几个月没有支持了。我确信只有极少数人喜欢这个 helper 类的 API 风格。

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

你可以用这个函数来计算时间

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

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

为了安卓 就像拉维说的,但因为很多人想要 只是复制粘贴这里的东西。

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

对有更多时间的人的解释

  1. 你从某个地方获取数据,首先,你必须弄清数据的格式。

我从服务器上获得的数据是格式化的 Wed,27 Jan 201609:32:35 GMT 2016年1月27日,星期三,格林尼治标准时间09:32:35[这可能不是你的案子]

翻译过来就是

SimpleDateFormat 格式化程序 = new SimpleDateFormat (“ EEE,dd MMM yyyy HH: mm: ss Z”) ;

我怎么知道? 读 文件。

然后我解析它,我得到一个日期。我放入 getRelativeTimeSpanString 中的日期(没有任何其他参数对我来说是可以的,默认为分钟)

如果你没有算出 正确解析字符串正确解析字符串,你会得到一个异常 ,类似于异常 第五个角色查看字符5,并更正初始解析字符串。.您可能会遇到另一个异常,请重复这些步骤,直到得到正确的公式。

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

示例用法:

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

对我有用

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


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


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


}
}


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


}


public String getDifferenceString() {
return differenceString;
}


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


public int getYears() {
return years;
}


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


public int getMonths() {
return months;
}


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


public int getDays() {
return days;
}


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


public int getHours() {
return hours;
}


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


public int getMinutes() {
return minutes;
}


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


public int getSeconds() {
return seconds;
}


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

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

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


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


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


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

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


}


}

为此,我已经做了 Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years ago在这个例子中,你可以解析日期像 2018-09-05T06:40:46.183Z这样或任何其他喜欢下面

Xml中添加低于值

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

下面是 java 代码尝试

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


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


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


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


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


diff = diff-19800;


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


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


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


// convert min
long temp=diff/60;


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


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


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


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


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


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


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


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


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


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


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


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


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


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


return disTime;
}

你可以使用 Java 的 Library 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"

我正在使用 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;
}

爪哇时间

回答: 哈布斯奎的想法是正确的,但方法是错误的。

对于没有按照年-月-天的比例与时间线相连的时间跨度,使用 Period。对于与日历和小时-分钟-秒无关的24小时时段,使用 Duration。把这两个尺度混合在一起很少有意义。

Duration

首先使用 Instant类获取在 协调世界时中看到的当前时刻。

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

生成长达数小时、数分钟和数秒的文本。

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

转到控制台。

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

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

8小时前

8分钟前

8秒前

Period

从获取当前日期开始。

时区对确定日期至关重要。对于任何给定的时刻,日期在全球各地区不同。例如,在 法国巴黎中午夜后的几分钟是新的一天,而在 魁北克蒙特利尔中仍然是“昨天”。

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

指定 Continent/Region格式的 正确的时区名称,如 America/MontrealAfrica/CasablancaPacific/Auckland。不要使用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

八天前

八个月前

八年前


关于 爪哇时间

< em > java.time 框架内置于 Java8及更高版本中。这些类取代了令人讨厌的旧的 遗产日期时间类,如 java.util.DateCalendarSimpleDateFormat

要了解更多,请参阅 < em > Oracle 教程 。并搜索堆栈溢出许多例子和解释。规范是 JSR 310

现在在 维修模式中的 尤达时间项目建议迁移到 爪哇时间类。

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

从哪里获得 java.time 类?

< strong > Three Ten-Ultra 项目使用其他类扩展 java.time。这个项目是将来可能添加 java.time 的试验场。您可以在这里找到一些有用的类,比如 IntervalYearWeekYearQuarter更多

下面的解决方案都是纯 Java 的:

备选方案1: 没有四舍五入,只有最大的时间容器

下面的函数将只显示最大的时间容器,例如,如果真正经过的时间是 "1 month 14 days ago",这个函数将只显示 "1 month ago"。这个函数也总是四舍五入,所以等效于 "50 days ago"的时间将显示为 "1 month"

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


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


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


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


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


return "0 seconds ago";
}

选择2: 四舍五入

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

下面是我的测试案例,希望能有所帮助:

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


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


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


val newTs = when {
diffYears >= 1 -> "Years $diffYears"
diffMonths >= 1 -> "Months $diffMonths"
diffWeeks >= 1 -> "Weeks $diffWeeks"
diffDays >= 1 -> "Days $diffDays"
diffHours >= 1 -> "Hours $diffHours"
diffMins >= 1 -> "Mins $diffMins"
else -> "now"
}
private const val SECOND_MILLIS = 1
private const val MINUTE_MILLIS = 60 * SECOND_MILLIS
private const val HOUR_MILLIS = 60 * MINUTE_MILLIS
private const val DAY_MILLIS = 24 * HOUR_MILLIS


object TimeAgo {


fun timeAgo(time: Int): String {


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


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

}

Val String = timeAgo (unixTimeStamp)

在 Kotlin 得到的时间

GetrelativeDateTime函数将提供日期时间,正如您在 Whatsapp 通知中看到的那样。
要获取未来的相对日期时间,请为其添加条件。这是专门为获取诸如 Whatsapp 通知之类的日期时间而创建的。

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


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


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

由于缺乏简单性和更新的响应,遵循了更新的 Java8和更高版本

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

这是一个使用 JavaTimeAPI 的版本,该 API 试图解决过去处理 Date 和 Time 的问题。

贾瓦多克

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

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

W3学校教程 -https://www.w3schools.com/java/java_date.asp

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

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

爪哇时间

你可以使用 java.time.Durationjava.time.Period,它们是以 ISO-8601标准为模型的,并且是由 Java-8作为 JSR-310实现的一部分引入的。使用 Java-9介绍了一些比较方便的方法。

  1. 使用 Duration计算基于时间的数量或时间量。可以使用基于持续时间的单位访问它,例如纳秒、秒、分钟和小时。此外,几天单位可以使用,并被视为正好相当于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

Rel = “ nofollow noReferrer”> Trail: Date Time 了解现代日期时间 API。

安卓系统:

用这个:

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

(来自评论)