`time.Duration`

is an `int64`

value representing a duration in nanoseconds. As stated, max value of `int64`

is about 290 years, so bigger durations cannot be represented by it.

## Simplest, naive solution

One simple solution is to convert your input to `time.Duration`

, which will represent one hundredth of your actual duration, because the input is in 100-nanosecond units. You may add this duration to a time starting with the reference date: `1601-01-01 UTC`

a hundred times, and you're done:

```
func getTime(input int64) time.Time {
t := time.Date(1601, 1, 1, 0, 0, 0, 0, time.UTC)
d := time.Duration(input)
for i := 0; i < 100; i++ {
t = t.Add(d)
}
return t
}
```

Testing it:

```
fmt.Println(getTime(132118740000000000))
```

Output (try it on the Go Playground):

```
2019-09-02 05:00:00 +0000 UTC
```

## Naive solution optimized

Yes, the above solution has a loop with 100 iterations, which may not be optimal.

One way to speed up the above is to reduce the number of iterations. We may do so if the input is not "very" large. For example if the input multiplied by 2 also fits into `int64`

, we could pre-multiply it by `2`

, and then we would only need 50 iterations. Similarly, if the `input*10`

would also fit into `int64`

, we could pre-multiply it by `10`

and then we would only need 10 iterations.

The input is 100-nanosecond units. `100`

is dividable by 100, 50, 25, 20, 10, 5, 4, 2, so to not lose any nanoseconds, we could check these factors if the input multiplied by these still fits into `int64`

, and if so we can divide the iterations count by it. In the best case scenario (if duration is less than 2.9 years, we can reduce the iterations to 1).

Example doing so:

```
var divisors = []int64{100, 50, 25, 20, 10, 5, 4, 2}
func getTime(input int64) time.Time {
iterations := 100
for _, div := range divisors {
if input <= math.MaxInt64/div {
input *= div
iterations /= int(div)
break
}
}
t := time.Date(1601, 1, 1, 0, 0, 0, 0, time.UTC)
d := time.Duration(input)
for i := 0; i < iterations; i++ {
t = t.Add(d)
}
return t
}
```

This will output the same, try it on the Go Playground. In this example the number of iterations is only 2.

## Fewest iterations

Similar to the above solution, but here in each iteration we will increment the time with the biggest duration possible. That is: `time.Duration(math.MaxInt64)`

, but since the input is in 100-nanosecond units, to be exact, we'll use `time.Duration(math.MaxInt64).Truncate(100 * time.Nanosecond)`

. We keep doing this until the remaining duration is less than the maximum, which will be the final addition to get the time instant we're looking for. As an extra, we also don't need the first loop which looked for the biggest divisor (to which the iterations count could be reduced).

```
func getTime(input int64) time.Time {
maxd := time.Duration(math.MaxInt64).Truncate(100 * time.Nanosecond)
maxdUnits := int64(maxd / 100) // number of 100-ns units
t := time.Date(1601, 1, 1, 0, 0, 0, 0, time.UTC)
for input > maxdUnits {
t = t.Add(maxd)
input -= maxdUnits
}
if input != 0 {
t = t.Add(time.Duration(input * 100))
}
return t
}
```

Output again is the same. Try this one on the Go Playground.

This solution guarantees fewest iterations. E.g. if duration is less than 290 years, there will be a single `time.Add()`

call. If duration is between 290 and 580 years, there will be 2 `time.Add()`

calls etc.

Note that in the final `time.Add()`

call we multiply `input`

by `100`

to convert 100-nanosecond units to nanoseconds. This will always succeed, because the loop before that decrements it as long as its bigger than `maxdUnits`

. We also only call this final `time.Add()`

if there is still something left to add, to ensure the fewest iterations. In practice this will likely always be true, so this `if`

could be left out: even if `input`

is 0, adding zero will not change `t`

, I added it to be true to the "fewest iterations" title.