Q:

Add nanoseconds from Win32 epoch to Go time

I'm trying to process some WMI counters using Go (as part of learning Go) and am trying to figure out how to generate the necessary time object. 
The base is the Win32 epoch (1601-01-01) and a sample timestamp is 13224382394716547600ns (or rather, 132243823947165476 100ns units). 
Here's what I've tried:
test 1 (add nanoseconds)
win_epoch := time.Date(1601,1,1, 0, 0, 0, 0, time.UTC)
current_ts_1 := win_epoch.Add(13224382394716547600*time.Nanosecond)

test 2 (add days)
win_epoch := time.Date(1601,1,1, 0, 0, 0, 0, time.UTC)
current_ts_2 := win_epoch.AddDate(0,0,(132243823947165476/10000000 / 3600 / 24))

current_ts_1 in test 1 fails with an overflow error.
current_ts_2 in test 2 only gives me resolution at the date level.
Ideally I'd be able to get the millisecond resolution on this. Does there exist a way to not overflow the Duration being passed to .Add() and still get this resolution?

A:

This conversion requires dealing with some huge numbers. Your example time 
13,224,382,394,716,547,600 is too big to fit into an int64 (max 9,223,372,036,854,775,807) but does fit into a unit64.
You cannot use time.Duration when dealing with this because that is a int64 nanosecond count; as the docs say "The representation limits the largest representable duration to approximately 290 years". This is why your first attempt fails.
However there is another way of creating a time that will work better here func Unix(sec int64, nsec int64) Time. This takes data in the unix format and this is the time since January 1, 1970 UTC (or 11644473600000000000 represented as ns since the windows epoch).
Using this information it's possible to perform the conversion:
func main() {
    const unixTimeBaseAsWin = 11644473600000000000 // The unix base time (January 1, 1970 UTC) as ns since Win32 epoch (1601-01-01) 
    const nsToSecFactor = 1000000000

    timeToConvert := uint64(13224382394716547600)

    unixsec := int64(timeToConvert  - unixTimeBaseAsWin ) / nsToSecFactor
    unixns := int64(timeToConvert  % nsToSecFactor)

    time := time.Unix(unixsec, unixns)
    fmt.Println(time.Local())
}

Note: I have checked this with a few figures but would suggest further testing before you rely upon it.

