Search code examples
gotimedata-conversion

Creating a time.Duration from float64 seconds


I have a float64 containing a duration in seconds. I'm looking for a way to convert this value to a time.Duration. I'm able to perform this conversion, but I'm wondering if there is not a more elegant way.

The approach I have is this:

    var timeout float64 // input value of float type

    var res time.Duration // result value of time.Duration type

    res += time.Duration(math.Round(timeout)) * time.Second
    timeout -= math.Round(timeout)
    timeout *= 1000
    res += time.Duration(math.Round(timeout)) * time.Millisecond
    timeout -= math.Round(timeout)
    timeout *= 1000
    res += time.Duration(math.Round(timeout)) * time.Microsecond
    timeout -= math.Round(timeout)
    timeout *= 1000
    res += time.Duration(math.Round(timeout)) * time.Nanosecond

    return res

What I dislike about this is that it is cumbersome and not reliable. I'd expect Go to supply something like this out of the box and to perform these conversions in a way that detects overflows and similar range violations. It seems that Go is not there yet, but maybe I missed something obvious, hence my question.

Notes:

  • This question doesn't address my needs, because it is rather related to the opposite way of conversion. That conversion is actually pretty painless, which makes the it even more surprising that the one I need isn't there.
  • Why don't I use milliseconds instead? Simple reason: Consistency, KISS principle, principle of least surprise. The SI unit for time is the second. Everything else is only derived from this, so I use this as a default.
  • Nitpick concerning the previous statement: Go itself says "There is no definition for units of Day or larger to avoid confusion across daylight savings time zone transitions.". They missed the point, because they still have minutes and hours, even though there are minutes with 58..61 seconds. Not a big deal, just mentioning it for completeness.

Solution

  • As JimB's comment shows, multiply the number of seconds by the number of duration units per second. Durations are measured in nanoseconds, but your code does not need to know that detail.

    return time.Duration(timeout * float64(time.Second))
    

    Convert to floating point for the multiplication and convert to duration to get the result.

    Alternatively you can convert your timeout to a Duration and multiply by the time.Second constant.

    return time.Duration(timeout) * time.Second