Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/403.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用Joda time计算从现在起经过的时间?_Java_Algorithm_Datetime_Grails_Jodatime - Fatal编程技术网

Java 如何使用Joda time计算从现在起经过的时间?

Java 如何使用Joda time计算从现在起经过的时间?,java,algorithm,datetime,grails,jodatime,Java,Algorithm,Datetime,Grails,Jodatime,我需要计算从一个特定日期到现在所经过的时间,并以与StackOverflow问题相同的格式显示,即: 15s ago 2min ago 2hours ago 2days ago 25th Dec 08 您知道如何使用Java库实现它吗?有没有已经实现它的helper方法,或者我应该自己编写算法?有一个称为helper的小类,我非常满意。要使用JodaTime计算经过的时间,请使用。若要以所需的人员表示形式格式化经过的时间,请使用您可以使用的方式进行构建 以下是一个启动示例: DateTime

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

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

您知道如何使用Java库实现它吗?有没有已经实现它的helper方法,或者我应该自己编写算法?

有一个称为helper的小类,我非常满意。

要使用JodaTime计算经过的时间,请使用。若要以所需的人员表示形式格式化经过的时间,请使用您可以使用的方式进行构建

以下是一个启动示例:

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 3秒钟前 51分钟前 7小时前 六天前 10个月前 31年前
(Cough,old,Cough)您可以看到,我也考虑了数月和数年,并将其配置为在值为零时忽略这些值。

您可以使用PeriodFormatter实现这一点,但您不必像中那样努力创建自己的PeriodFormattBuilder。如果适合您的情况,您可以使用默认的格式化程序:

Period period = new Period(startDate, endDate);
System.out.println(PeriodFormat.getDefault().print(period))
(关于一个类似的问题,我正在交叉发布以提高可发现性)

用于简单的运行时间。 我试着以@sfussenegger的回答,使用JodaTime的
句点
,但我发现的最简单、最清晰的方法是库

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

五分钟前 不久以前 注意:我尝试过使用该库更精确的功能,但它会产生一些奇怪的结果,因此请小心使用,并在不危及生命的项目中使用


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

“08年12月25日”不是“从一个特定日期到现在的时间”(你用粗体写的),我知道。但在这样的时间里展示问题也是如此。如果周期足够长,那么它会显示确切的日期。我对StackOverflow处理日期很不满意。一开始你会得到非常精确的数字(37秒前),但很快就会变得非常模糊(2天前)。只有当时间以绝对格式显示后,您才能再次看到精确的(至少到分钟)日期和时间。我相信这种相对信息只在绝对信息之外有用,但不能替代它。你可以在工具提示中获得确切的日期时间。只需将日期时间悬停一段时间:)Joda Time对于在需要额外功能时打印相对(已用)时间来说设计得不好。被接受的答案是可以的,但不可本地化(仅适用于英语)。如果您需要本地化支持,那么有更好的第三方库。ocpsoft/PrettyTime是一个更好的选择,但只适用于旧类
java.util.Date
。然而,对于打印相对时间(ago格式)或“3个月,4天”格式的时间,我的库是最好的库。它还可以本地化为72种语言。我用你的代码作为我算法的基础。我基本上用1个字段显示经过的时间(或仅显示2个最大值)。如果有人对代码感兴趣,我可以把它作为答案贴在这里。我使用上面的代码进行了测试,发现格式化程序缺少weeks字段,即第6天之后的days wrap。所以我添加了:.appendWeeks().appendSuffix(“几周前”\n”)@fabien7474您是如何调整它以只显示一个字段的?请将其作为答案发布。@fabien7474您是如何将其调整为仅显示一个字段的?请检查此字段,以仅显示一个字段。这很好。在答案中添加一个简单的输入和输出示例将非常有用。我刚刚尝试了这个方法,它将所有字段中的周期细分为毫秒,因此getDefault()没有多大帮助。我刚刚尝试了这个方法,它将所有字段中的周期细分为毫秒,因此getDefault()很有用。(感谢@snappieT)这对于大多数用例来说都是简洁和足够的。
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;
} 
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";
    }
}
long now = System.currentTimeMillis();
getTimeAgo(now);