Browse Source

FileTime type

Jonathan Turner 9 years ago
parent
commit
03cddf6299
2 changed files with 66 additions and 0 deletions
  1. 50 0
      mstypes/filetime.go
  2. 16 0
      mstypes/filetime_test.go

+ 50 - 0
mstypes/filetime.go

@@ -0,0 +1,50 @@
+package mstypes
+
+import (
+	"time"
+)
+
+/*
+FILETIME is a windows data structure.
+Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284%28v=vs.85%29.aspx
+It contains two parts that are 32bit integers:
+	dwLowDateTime
+	dwHighDateTime
+We need to combine these two into one 64bit integer.
+This gives the number of 100 nano second period from January 1, 1601, Coordinated Universal Time (UTC)
+*/
+
+const UNIX_EPOCH_DIFF = 116444736000000000
+
+type FileTime struct {
+	LowDateTime  uint32
+	HighDateTime uint32
+}
+
+// Return a golang Time type from the FileTime
+func (ft FileTime) Time() time.Time {
+	ns := (ft.MSEpoch() - UNIX_EPOCH_DIFF) * 100
+	return time.Unix(0, int64(ns)).UTC()
+}
+
+// MSEpoch returns the FileTime as a Microsoft epoch, the number of 100 nano second periods elapsed from January 1, 1601 UTC.
+func (ft FileTime) MSEpoch() int64 {
+	return (int64(ft.HighDateTime) << 32) + int64(ft.LowDateTime)
+}
+
+// Unix returns the FileTime as a Unix time, the number of seconds elapsed since January 1, 1970 UTC.
+func (ft FileTime) Unix() int64 {
+	return (ft.MSEpoch() - UNIX_EPOCH_DIFF) / 10000000
+}
+
+// Get a FileTime type from the provided Golang Time type.
+func GetFileTime(t time.Time) FileTime {
+	ns := t.UnixNano()
+	fp := (ns / 100) + UNIX_EPOCH_DIFF
+	hd := fp >> 32
+	ld := fp - (hd << 32)
+	return FileTime{
+		LowDateTime:  uint32(ld),
+		HighDateTime: uint32(hd),
+	}
+}

+ 16 - 0
mstypes/filetime_test.go

@@ -0,0 +1,16 @@
+package mstypes
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+	"time"
+)
+
+func TestFileTime(t *testing.T) {
+	//2007-02-22 17:00:01.6382155
+	tt := time.Date(2007, 2, 22, 17, 0, 1, 638215500, time.UTC)
+	ft := GetFileTime(tt)
+	assert.Equal(t, tt.Unix(), ft.Unix(), "Unix epoch time not as expected")
+	assert.Equal(t, int64(128166372016382155), ft.MSEpoch(), "MSEpoch not as expected")
+	assert.Equal(t, tt, ft.Time(), "Golang time object returned from FileTime not as expected")
+}