Skip to main content

This is a new website theme. Help me improve it and give your feedback (opens in a new tab).

Duration and Period

Published:

Tags:

Tor Java
This blog post is more than two years old. It is preserved here in the hope that it is useful to someone, but please be aware that links may be broken and that opinions expressed here may not reflect my current views. If this is a technical article, it may no longer reflect current best practice.

I’m in the process or tidying up the bot behind TorAtlas and I’ve chosen to write it in Java. My undergraduate degree had a lot of Java in it, but that was while ago now, and there are some cool new features I’ve learnt about including Period and Duration.

Some of the tweets coming from the bot talk about how long a relay has been contributing to the Tor network. When fetching the details document I look at the first_seen field and get this as a ZonedDateTime to make sure I’m doing all my calculations in UTC. I then use the between() method on various ChronoUnits to work out how long between the first time the relay was seen and now, and then I produced something human readable from this:

public static String formatAge(Temporal first_seen_date) {
    int years = (int) ChronoUnit.YEARS.between(first_seen_date, ZonedDateTime.now(ZoneOffset.UTC));
    int days = (int) ChronoUnit.DAYS.between(first_seen_date, ZonedDateTime.now(ZoneOffset.UTC));
    int hours = (int) ChronoUnit.HOURS.between(first_seen_date, ZonedDateTime.now(ZoneOffset.UTC));
    int minutes = (int) ChronoUnit.MINUTES.between(first_seen_date, ZonedDateTime.now(ZoneOffset.UTC));
    int seconds = (int) ChronoUnit.SECONDS.between(first_seen_date, ZonedDateTime.now(ZoneOffset.UTC));

    if (years > 0) {
        return String.format("%s years and %s days", years, (days % 365));
    } else if (days > 0) {
        return String.format("%s days and %s hours", days, (hours % 24));
    } else if (hours > 0) {
        return String.format("%s hours and %s minutes", hours, (minutes % 60));
    } else if (minutes > 0) {
        return String.format("%s minutes and %s seconds", minutes, (seconds % 60));
    } else {
        return String.format("%s seconds", seconds);
    }
}

I would be very happy if I could find something to accept a Duration instead, and produce a human-readable representation. I haven’t found anything quite like the library I was using in Python. I also have a restriction that I’d like things to be installable from Debian, so any new library would need to be something that could be maintained in Debian (i.e. active upstream and DFSG-compliant).

In Python, I used humanfriendly.format_timespan() which is a lovely library. If you’re writing Python, I’d definitely recommend it.