如何使用 Joda-Time 计算从现在开始的运行时间?

我需要计算 从一个特定日期到现在的时间,并用与 StackOverflow 问题相同的格式显示它,即:

15s ago
2min ago
2hours ago
2days ago
25th Dec 08

你知道如何用 Java图书馆实现它吗?是否有一个已经实现了它的助手方法,或者我应该自己编写算法?

31083 次浏览

有一个叫做 人类时间的小型助手类,我对它很满意。

若要使用 JodaTime 计算运行时间,请使用 Period。为了格式化所需的人工表示所花费的时间,可以使用 PeriodFormatter,它可以由 PeriodFormatterBuilder构建。

下面是一个开始的例子:

DateTime myBirthDate = new DateTime(1978, 3, 26, 12, 35, 0, 0);
DateTime now = new DateTime();
Period period = new Period(myBirthDate, now);


PeriodFormatter formatter = new PeriodFormatterBuilder()
.appendSeconds().appendSuffix(" seconds ago\n")
.appendMinutes().appendSuffix(" minutes ago\n")
.appendHours().appendSuffix(" hours ago\n")
.appendDays().appendSuffix(" days ago\n")
.appendWeeks().appendSuffix(" weeks ago\n")
.appendMonths().appendSuffix(" months ago\n")
.appendYears().appendSuffix(" years ago\n")
.printZeroNever()
.toFormatter();


String elapsed = formatter.print(period);
System.out.println(elapsed);

现在这个指纹

3 seconds ago
51 minutes ago
7 hours ago
6 days ago
10 months ago
31 years ago

(咳,老,咳) 您可以看到,我也考虑了数月和数年,并将其配置为在值为零时省略这些值。

您可以使用 periodFormatter 来实现这一点,但是您不必像在 其他答案中那样努力创建自己的 periodFormatBuilder。如果它适合您的情况,您可以只使用默认格式化程序:

Period period = new Period(startDate, endDate);
System.out.println(PeriodFormat.getDefault().print(period))

(在类似的问题上给 这个答案一个帽子提示,我正在交叉发帖以便发现)

对于简单的运行时间使用 美好时光

我尝试了@sfussenegger 回答的 人类时间,并使用 JodaTime 的 Period,但是我发现对于人类可读的运行时间来说,最简单、最干净的方法是 美好时光库。

下面是几个简单的输入和输出示例:

五分钟前

DateTime fiveMinutesAgo = DateTime.now().minusMinutes( 5 );


new PrettyTime().format( fiveMinutesAgo.toDate() );


// Outputs: "5 minutes ago"

不久前

DateTime birthday = new DateTime(1978, 3, 26, 12, 35, 0, 0);


new PrettyTime().format( birthday.toDate() );


// Outputs: "4 decades ago"

注意: 我试过使用这个库的更精确的功能,但是它会产生一些奇怪的结果,所以要小心使用它,并且在没有生命危险的项目中使用它。

JP

这是使用 mysql 时间戳得到现在的运行时间。管理单数和复数。只显示最大时间。

注意: 设置自己的时区。

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

这是我的 解决方案,使用 joda time

private static final int SECOND_MILLIS = 1000;
private static final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
private static final int HOUR_MILLIS = 60 * MINUTE_MILLIS;
private static final int DAY_MILLIS = 24 * HOUR_MILLIS;


public static String getTimeAgo(long time)
{
if(time < 1000000000000L)
{
time *= 1000;
}


long now = System.currentTimeMillis();


if(time > now || time <= 0)
{
return null;
}


final long diff = now - time;


if(diff < MINUTE_MILLIS)
{
return "just now";
}
else if(diff < 2 * MINUTE_MILLIS)
{
return "a minute ago";
}
else if(diff < 50 * MINUTE_MILLIS)
{
return diff / MINUTE_MILLIS + " minutes ago";
}
else if(diff < 90 * MINUTE_MILLIS)
{
return "an hour ago";
}
else if(diff < 24 * HOUR_MILLIS)
{
return diff / HOUR_MILLIS + " hours ago";
}
else if(diff < 48 * HOUR_MILLIS)
{
return "yesterday";
}
else
{
return diff / DAY_MILLIS + " days ago";
}
}

使用方法:

只需调用该方法并在 milliseconds中及时传递。

例如 :

long now = System.currentTimeMillis();
getTimeAgo(now);