3

So I'm using Joda time and want it to display only one number (I know how to handle pluralisation in Joda, just a quick example at the end).

Example:
2 years 2 months 2 weeks ago should just show 2 years ago
2 days 2 hours 2 minutes ago should just show 2 days ago

I'm looking for some way to short circuit the appends when it gets a non-zero number. I have searched and found examples for other frameworks but we are already using Joda time and I dont want to pull inn other dependencies if it is possible.

The code I have now is the following:

protected final String toRelativeTime(final DateTime dateTime) {
    DateTime now = new DateTime();
    Period period = new Period(dateTime, now);

    PeriodFormatter formatter = new PeriodFormatterBuilder()
            .appendYears().appendSuffix(" years")
            .appendMonths().appendSuffix(" months")
            .appendWeeks().appendSuffix(" weeks")
            .appendDays().appendSuffix(" days")
            .appendHours().appendSuffix(" hours")
            .appendMinutes().appendSuffix(" minutes")
            .appendSeconds().appendSuffix(" seconds")
            .printZeroNever()
            .toFormatter();
    return formatter.print(period);
}
Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
Anders
  • 9,988
  • 7
  • 30
  • 36
  • Which other frameworks have you searched for? I am just curious. Joda-Time is pretty awkward to handle on this area as you can see in suggested answer. – Meno Hochschild Jan 16 '15 at 10:33

2 Answers2

1

The below function will do exactly you require.

protected final String toRelativeTime(final DateTime dateTime) {
    long nowLngTime = System.currentTimeMillis();
    DateTime now = new DateTime();
    long difference = Math.abs(dateTime.getTime() - nowLngTime);
    Period period = new Period(dateTime, now);
    PeriodFormatterBuilder formatterBuilder = new PeriodFormatterBuilder();
    if (difference > DateUtils.YEAR_IN_MILLIS) {
        formatterBuilder.appendYears().appendSuffix(" year");
    } else if (difference > DateUtils.DAY_IN_MILLIS * 30) {
        formatterBuilder.appendMonths().appendSuffix(" month");
    } else if (difference > DateUtils.WEEK_IN_MILLIS) {
        formatterBuilder.appendWeeks().appendSuffix(" week");
    } else if (difference > DateUtils.DAY_IN_MILLIS) {
        formatterBuilder.appendDays().appendSuffix(" day");
    } else if (difference > DateUtils.HOUR_IN_MILLIS) {
        formatterBuilder.appendHours().appendSuffix(" hour");
    } else if (difference > DateUtils.MINUTE_IN_MILLIS) {
        formatterBuilder.appendMinutes().appendSuffix(" minute");
    } else if (difference > DateUtils.SECOND_IN_MILLIS) {
        formatterBuilder.appendSeconds().appendSuffix(" second");
    }
    String ends = formatterBuilder.printZeroNever().toFormatter().print(period);
    String plural = ends.startsWith("1 ")?"":"s";
    return plural;
}
Sridhar DD
  • 1,972
  • 1
  • 10
  • 17
1

I ended up doing this

private final String toRelativeTime(LocalDateTime startTime, LocalDateTime endTime) {
    final String sufix = " ago";
    final Long seconds = ChronoUnit.SECONDS.between(startTime, endTime);
    final Long minutes = ChronoUnit.MINUTES.between(startTime, endTime);
    final Long hours = ChronoUnit.HOURS.between(startTime, endTime);
    final Long days = ChronoUnit.DAYS.between(startTime, endTime);
    final Long weeks = ChronoUnit.WEEKS.between(startTime, endTime);
    final Long months = ChronoUnit.MONTHS.between(startTime, endTime);
    final Long years = ChronoUnit.YEARS.between(startTime, endTime);

    if(years > 0) {
        return years.toString() + " " + checkPluralisation(years, "year", "years") + sufix;
    } else if(months > 0) {
        return months.toString() + " " + checkPluralisation(months, "month", "months") + sufix;
    }else if(weeks > 0) {
        return weeks.toString() + " " + checkPluralisation(weeks, "week", "weeks") + sufix;
    }else if(days > 0) {
        return days.toString() + " " + checkPluralisation(days, "day", "days") + sufix;
    }else if(hours > 0) {
        return hours.toString() + " " + checkPluralisation(hours, "hour", "hours") + sufix;
    }else if(minutes > 0) {
        return minutes.toString() + " " + checkPluralisation(minutes, "minute", "minutes") + sufix;
    } else {
        return seconds.toString() + " " + checkPluralisation(seconds, "second", "seconds") + sufix;
    }
}
Anders
  • 9,988
  • 7
  • 30
  • 36
  • Ah, Java 8. Also a lot of work similar to Joda-Time instead of a one-liner ;-) – Meno Hochschild Jan 16 '15 at 13:19
  • Anyway, your answer demonstrates that Joda-Time does not offer enough features to stop the (officially recommended) migration to java.time in Java-8. At least your (still lengthy) workaround is about the same effort as in Joda-Time and can show people willing to migrate how to replace the missing `PeriodFormatter`, hence my upvote. – Meno Hochschild Jan 16 '15 at 13:43
  • @MenoHochschild agree, this feels a bit length. I didn't really get it smaller in Joda-Time so I just used Java 8. – Anders Jan 17 '15 at 23:18