## The challenge

Your task in order to complete this challenge is to write a function which formats a duration, given as a number of seconds, in a human-friendly way.

The function must accept a non-negative integer. If it is zero, it just returns `"now"`. Otherwise, the duration is expressed as a combination of `years``days``hours``minutes` and `seconds`.

It is much easier to understand with an example:

 ``````1 2 3 4 5 `````` ``````//returns "1 minute and 2 seconds" TimeFormatter.formatDuration(62) //returns "1 hour, 1 minute and 2 seconds" TimeFormatter.formatDuration(3662) ``````

For the purpose of this challenge, a year is 365 days and a day is 24 hours.

Note that spaces are important.

### Detailed rules

The resulting expression is made of components like `4 seconds``1 year`, etc. In general, a positive integer and one of the valid units of time, separated by a space. The unit of time is used in plural if the integer is greater than 1.

The components are separated by a comma and a space (`", "`). Except the last component, which is separated by `" and "`, just like it would be written in English.

A more significant units of time will occur before than a least significant one. Therefore, `1 second and 1 year` is not correct, but `1 year and 1 second` is.

Different components have different unit of times. So there is not repeated units like in `5 seconds and 1 second`.

A component will not appear at all if its value happens to be zero. Hence, `1 minute and 0 seconds` is not valid, but it should be just `1 minute`.

A unit of time must be used “as much as possible”. It means that the function should not return `61 seconds`, but `1 minute and 1 second` instead. Formally, the duration specified by of a component must not be greater than any valid more significant unit of time.

## The solution in Java code

Option 1:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 `````` ``````import java.util.Arrays; import java.util.stream.*; public class TimeFormatter { public static String formatDuration(int seconds) { return seconds == 0 ? "now" : Arrays.stream( new String[]{ formatTime("year", (seconds / 31536000)), formatTime("day", (seconds / 86400)%365), formatTime("hour", (seconds / 3600)%24), formatTime("minute",(seconds / 60)%60), formatTime("second",(seconds%3600)%60)}) .filter(e->e!="") .collect(Collectors.joining(", ")) .replaceAll(", (?!.+,)", " and "); } public static String formatTime(String s, int time){ return time==0 ? "" : Integer.toString(time)+ " " + s + (time==1?"" : "s"); } } ``````

Option 2:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 `````` ``````public class TimeFormatter { public static String formatDuration(int seconds) { String res = ""; int[] units = new int[] {31536000, 86400, 3600, 60, 1}; String[] labels = new String[] {"year", "day", "hour", "minute", "second"}; if (seconds == 0) return "now"; for (int i = 0; i < 5; i++) { if (seconds >= units[i]) { int q = seconds / units[i]; seconds = seconds % units[i]; res += (res.equals("") ? "" : (seconds == 0 ? " and " : ", ")) + q + " " + labels[i] + (q > 1 ? "s" : ""); } } return res; } } ``````

Option 3:

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 `````` ``````import java.util.*; public class TimeFormatter { private static final String[] TIME_WORDS = { " years", " days", " hours", " minutes", " seconds" }; public static String formatDuration(int seconds) { if(seconds == 0) return "now"; int[] timeUnits = { seconds/(60*60*24*365), (seconds/(60*60*24))%365, (seconds/(60*60))%24, (seconds/60)%60, seconds%60 }; List timeElements = new ArrayList<>(); for(int i=0; i

## Test cases to validate our solution

 `````` 1 2 3 4 5 6 7 8 9 10 11 12 13 `````` ``````import org.junit.Test; import static org.junit.Assert.*; public class TimeFormatterTest { @Test public void exampleTests() { assertEquals("1 second", TimeFormatter.formatDuration(1)); assertEquals("1 minute and 2 seconds", TimeFormatter.formatDuration(62)); assertEquals("2 minutes", TimeFormatter.formatDuration(120)); assertEquals("1 hour", TimeFormatter.formatDuration(3600)); assertEquals("1 hour, 1 minute and 2 seconds", TimeFormatter.formatDuration(3662)); } } ``````