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


70

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

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

您知道如何使用Java Joda-Time实现它吗?有没有已经实现它的辅助方法,还是我应该自己编写算法?


3
“ 08年12月25日”不是“从一个特定日期到现在为止所经过的时间”(您用粗体字写的;)
语法T3rr0r 2010年

我知道。但是SO正在显示这样的问题。如果周期足够长,则显示确切日期。
fabien7474'2

1
我对StackOverflow的处理日期感到非常不满。刚开始时(37秒前)您会获得非常精确的数字,但很快就会变得非常模糊(2天前)。只有在以绝对格式显示时间之后,您才能再次看到准确的日期(至少是分钟)。我认为,这种相对信息仅在绝对信息之外有用,但不能代替绝对信息。
Svante

5
您可以在工具提示中获取确切的日期时间。只需将日期时间悬停一会儿即可:)
BalusC,2010年

当您需要其他功能时,Joda-Time不适用于打印相对(经过)时间。可接受的答案是可以的,但是不能本地化(仅适用于英语)。如果您需要本地化支持,那么会有更好的第三方库。ocpsoft / PrettyTime是一个更好的选择,但java.util.Date仅适用于旧类。但是,我的lib Time4J库是IMHO最好的库,它可以打印相对时间(ago格式)或类似“ 3个月4天”的格式的时间。它实际上也可以本地化为72种语言。
Meno Hochschild

Answers:


113

要使用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秒前
51分钟前
7小时前
6天前
10个月前
31年前

(咳嗽,老咳嗽)您会发现我也考虑了几个月和几年,并将其配置为在零值时忽略这些值。


2
谢谢。我将您的代码用作算法的基础。我基本上用1个字段(或最多2个)显示经过的时间。如果有人对代码感兴趣,可以在此处发布答案。它还符合i18。
fabien7474'2

1
我使用上面的代码进行了测试,发现格式化程序缺少“周”字段-第6天之后的天数。因此我添加了:.appendWeeks()。appendSuffix(“ weeks \ n”)
Mike Hopper 2010年

5
@ fabien7474您如何调整它以仅显示一个字段?请发布它作为答案。
卡尔,

2
@ fabien7474真的,您如何适应它仅显示一个字段?
oko 2014年

1
检查此要点仅显示一个字段。
Laranjeiro

20

PrettyTime用作简单的经过时间。

我试图HumanTime为@sfussenegger回答,并使用JodaTime的Period,但人类可读经过的时间,我发现是最简单,最干净的方法PrettyTime库。

这是带有输入和输出的几个简单示例:

五分钟前

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"

注意:我尝试过使用该库的更精确功能,但是它会产生一些奇怪的结果,因此请谨慎使用它,并在不危及生命的项目中使用。

J.P


11

您可以使用PeriodFormatter来做到这一点,但不必像其他答案那样去制作自己的PeriodFormatBuilder 。如果适合您的情况,则可以使用默认格式化程序:

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

(在类似问题上向该答案提示,我正在交叉发布以提高可发现性)


我刚刚尝试过,它给出了所有字段到毫秒的周期细分,因此getDefault()并没有帮助。
NealeU 2015年

1
我只是尝试这样做,它给通过所有领域毫秒期间的崩溃,所以getDefault()有帮助的。(感谢@snappieT)
Synesso 2015年

对于大多数用例来说,这是简明扼要的,足够了。
詹姆斯·塞瓦库玛


0

这是使用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;
} 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.