Explain Codes LogoExplain Codes Logo

How to calculate "time ago" in Java?

java
prompt-engineering
best-practices
functions
Alex KataevbyAlex Kataev·Dec 8, 2024
TLDR

The Java 8's java.time API can be used to calculate "time ago" between two LocalDateTime instances:

LocalDateTime past = LocalDateTime.of(2023, 1, 1, 8, 30); // Replace this with any past date Duration duration = Duration.between(past, LocalDateTime.now()); // Magic happens here String timeAgo = duration.toDays() > 0 ? duration.toDays() + " days ago" : duration.toHours() > 0 ? duration.toHours() + " hours ago" : duration.toMinutes() > 0 ? duration.toMinutes() + " minutes ago" : duration.getSeconds() + " seconds ago"; System.out.println(timeAgo); // It's TARDIS... but for your console!

This snippet returns a well-formatted time ago string like "2 days ago" or "10 minutes ago".

Grammar rules: handling singular and plural forms

When showing time units, consider grammar rules. Specifically, look at singular and plural forms. Here is an improved way to output the correct suffix:

String dayUnit = duration.toDays() == 1 ? " day" : " days"; String timeAgo = duration.toDays() > 0 ? duration.toDays() + dayUnit + " ago" : ...

Repeat this for hours, minutes, and seconds. Because grammar matters, even in code.

Localization with PrettyTime and Android DateUtils

If your application needs to be multilingual, the PrettyTime library could come in handy, generating "time ago" values in various languages:

PrettyTime p = new PrettyTime(new Locale("en")); // Just as multilingual as you are System.out.println(p.format(new Date())); // Prints time ago, but in English

For Android developers, the built-in DateUtils class simplifies the process by providing a similar method: getRelativeTimeSpanString.

Forming the "time ago" string

Building your own solution? Use a StringBuilder to construct your "time ago" string more efficiently:

StringBuilder sb = new StringBuilder(); // StringBuffer: Because String said no to 'roids if (duration.toDays() > 0) { sb.append(duration.toDays()).append(" days "); } ... String timeAgo = sb.toString(); // It's ALIIIIIIVE!!!

Convert time units accurately

For detailed time measurements, you can use TimeUnit conversions:

long milliseconds = ... // Some timestamp long hours = TimeUnit.MILLISECONDS.toHours(milliseconds); // Because life's too short for manual conversion long minutes = TimeUnit.MILLISECONDS.toMinutes(milliseconds) - TimeUnit.HOURS.toMinutes(hours); // The missing piece in your puzzle

These conversions ensure precise calculations for any time unit.

Robustness through error handling

Don't forget to cater edge cases, like 0 seconds or future dates. Safeguard your code with try-catch blocks:

try { // Your code here } catch (DateTimeException e) { // Future is uncertain, just like this date }

Not only days and hours

Include more detail with millisToLongDHMS (a user-defined method) to provide detailed time intervals:

String timeAgoDetailed = millisToLongDHMS(milliseconds); // Rarely known cousin of R2-D2

Reverse time calculation

A bonus would be providing a mechanism to convert back from a "time ago" string into milliseconds. It's like a time machine, but for your strings.

Finishing touch: Cleanup and formatting

Lastly, clean up your generated "time ago" string to remove any extra spaces or trailing characters:

if (sb.length() > 0) sb.setLength(sb.length() - 2); // End of the ride! timeAgo = sb.append("ago").toString();