62

I was looking at the Duration class in Java 8 and noticed that it does not have:

long toSeconds();

But it has all other toXXXXX() to get days, hours, minutes, millis, nanos. I do see a getSeconds() method that returns the number of seconds within this duration object. There is also a get(TemporalUnit unit) method to get the duration as the requested time unit. But why not keep the toSeconds() method for consistency?

niqueco
  • 2,261
  • 19
  • 39
Ali
  • 1,442
  • 1
  • 15
  • 29
  • because there is already a private method with that name: `private BigDecimal toSeconds()` ?! – user85421 Feb 18 '17 at 15:50
  • 9
    @CarlosHeuberger that's not a reason. If there were a `long toSeconds()` method, `BigDecimal toSeconds()` would simply be called something else; or, the next question is why `BigDecimal toSeconds()` is private. – Andy Turner Feb 18 '17 at 15:51
  • @Andy but since there is a `BigDecimal toSeconds()` there can not be a `long toSeconds()` – user85421 Feb 18 '17 at 15:52
  • 6
    @CarlosHeuberger but it's a private method. If there were a reason to provide a public method `toSeconds()`, it could simply be renamed. – Andy Turner Feb 18 '17 at 15:54
  • 9
    Already done. See `public long toSeconds()` in Java 9. – Basil Bourque Feb 18 '17 at 17:25

4 Answers4

75

Let's look at what the docs say:

This class models a quantity or amount of time in terms of seconds and nanoseconds.

That basically means that the unit used to store the amount of time represented is seconds. For example, to store the duration 5 minutes and 10 nanoseconds, 300 (seconds) and 10 (nanoseconds) are stored. Because of this, there is no need to convert to seconds. You get the seconds using getSeconds().

See what I mean here? All the other methods convert to the corresponding units: days, minutes, hours... That's why they start with to, meaning convertedTo. Since you don't need to do a conversion to get the duration in seconds, the method that returns the duration in seconds starts with get.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • 1
    I agree with your explanation here @Sweeper. Since internally the seconds and nano seconds are already stored in separate variables, and the nano part cannot be converted to a complete second, the seconds can be returned as is. The seconds on the other hand can be converted to nano seconds so there is a toNanos method for the conversion. – Ali Feb 18 '17 at 16:26
  • 50
    This is a somewhat odd argument, though, because the *point* of encapsulation (in a class) is to hide the implementation details. As a consumer of the class, I shouldn't need to read the documentation and find out that *internally* it uses seconds and nanoseconds, and from there deduce that I don't need a toSeconds(); and if at some point it turns out that an internal representation of *just* nanoseconds is a better fit for some reason, the owner of the class should be free to change the internal representation without having to make any externally visible changes. – user Feb 19 '17 at 12:55
  • 2
    @MichaelKjörling I agree with you that there should have been a toSeconds() method included in the Duration class (after reading your explanation). Although, after reading the Duration class's documentation I understood that I can use getSeconds() in place of toSecond(), it was not intuitive. I went off on a tangent to determine why there was not a toSeconds() method. I have a feeling that I will revisit this post once I forget about what I read in the documentation. I am happy that others have given though to this inconsistency and created a fix. – Ali Feb 20 '17 at 06:30
  • When you have a number of libraries as large and as expansive as the Java Platform, you're bound to find (hopefully) a fair amount of consensus in naming conventions, but an inevitable amount of inconsistency. I find the method naming in `java.time` to be largely good, but I can't understand the choices made for `Duration`. Since you have a `Duration` object, in order to represent it as a different form (primitive values), I feel that it would be most consistent to have all these methods named `asXXXX()`. Such methods would read better too: `myDuration.asSeconds();`. – scottb Jan 26 '21 at 22:35
54

This is a known issue whose fix is scheduled for Java 9: https://bugs.openjdk.java.net/browse/JDK-8142936

New method added in Java 9, toSeconds. See source code.

/**
 * Gets the number of seconds in this duration.
 * <p>
 * This returns the total number of whole seconds in the duration.
 * <p>
 * This instance is immutable and unaffected by this method call.
 *
 * @return the whole seconds part of the length of the duration, positive or negative
 */
public long toSeconds() {
    return seconds;
}
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 3
    Did I misunderstand the OP's question? I thought the OP is asking why `getSeconds` is not called `toSeconds`. The issue you linked seems to be about why there isn't any methods to get the different parts of the duration. – Sweeper Feb 18 '17 at 15:49
  • I don't think this is an issue. My thinking in posting the original question was that why isn't the toSeconds included for consistency. But it is explained by @Sweeper below that those are conversions, which makes sense to me. It doesn't make sense to include a method to convert seconds to seconds since the getSeconds method already returns the seconds part. – Ali Feb 18 '17 at 16:16
  • 11
    It's an issue in the sense that the API is not consistent, as the bug report says: programmers look for a toSeconds method because all the other methods are named toXxx(). – JB Nizet Feb 18 '17 at 16:36
  • 13
    @Sweeper the end of the bug report says: *In addition, users have found the lack of a `toSeconds()` method confusing. The method exists, but is named `getSeconds()`, whereas all the similar methods are named `toXxx`. Adding a convenience method here would make the API more usable.* – JB Nizet Feb 18 '17 at 16:37
  • 11
    I think this is the best answer. Recognizing that you don't need it doesn't mean you should not provide it. Sometimes programmers are too consistent ("there is no conversion needed so why give it a stupid name that pretends we convert?") forgetting the perspective of the user who doesn't care what goes on "underneath the hood". Love the fact that this is being recognized and addressed. – Floris Feb 18 '17 at 17:42
  • @Floris: I think this answer shows that this is a good question and the API needs to be redesigned to avoid this question from more people, but the best answer to the question is the accepted one! – dave Feb 19 '17 at 07:18
  • @dave you are entitled to your opinion. So am I. – Floris Feb 19 '17 at 07:20
  • 2
    It seems to me part of what is going on here is that `Duration` exposes its own implementation. I'm not against that if it helps some people write more efficient code, but the addition of the `toSeconds()` function seems to move it a little closer to actually having an abstract interface rather than being a kind of decorated C struct. – David K Feb 19 '17 at 13:50
4

Because Duration

[...] models a quantity or amount of time in terms of seconds and nanosecond [...]

therefore it offers the two methods

There is no logical "to seconds" since it already is in seconds.

luk2302
  • 55,258
  • 23
  • 97
  • 137
  • 6
    Looking at the java docs for Duration, there is a toNanos() method as well as getNano(). The former converts the Duration into total number of nano seconds in this duration while the latter gets only the nano part of the duration. – Ali Feb 18 '17 at 16:11
1

Quote from http://tutorials.jenkov.com/java-date-time/duration.html:

You might be asking yourself if there is not a toSeconds() method. There isn't because that is the same as the seconds part of the Duration. You can obtain the seconds part of the Duration using the getSeconds() method as explained earlier.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Gyrotank
  • 153
  • 1
  • 2
  • 9