This repository has been archived by the owner on Feb 11, 2022. It is now read-only.
forked from fraugster/parquet-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
int96_time.go
46 lines (37 loc) · 1.6 KB
/
int96_time.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package goparquet
import (
"encoding/binary"
"time"
)
const (
jan011970 = 2440588
secPerDay = 24 * 60 * 60
)
func timeToJD(t time.Time) (uint32, uint64) {
days := t.Unix() / secPerDay
nSecs := t.UnixNano() - (days * secPerDay * int64(time.Second))
// unix time starts from Jan 1, 1970 AC, this day is 2440588 day after the Jan 1, 4713 BC
return uint32(days) + jan011970, uint64(nSecs)
}
func jdToTime(jd uint32, nsec uint64) time.Time {
sec := int64(jd-jan011970) * secPerDay
return time.Unix(sec, int64(nsec))
}
// Int96ToTime is a utility function to convert a Int96 Julian Date timestamp (https://en.wikipedia.org/wiki/Julian_day) to a time.Time.
// Please be aware that this function is limited to timestamps after the Unix epoch (Jan 01 1970 00:00:00 UTC) and cannot
// convert timestamps before that. The returned time does not contain a monotonic clock reading and is in the machine's current time zone.
func Int96ToTime(parquetDate [12]byte) time.Time {
nano := binary.LittleEndian.Uint64(parquetDate[:8])
dt := binary.LittleEndian.Uint32(parquetDate[8:])
return jdToTime(dt, nano)
}
// TimeToInt96 is a utility function to convert a time.Time to an Int96 Julian Date timestamp (https://en.wikipedia.org/wiki/Julian_day).
// Please be aware that this function is limited to timestamps after the Unix epoch (Jan 01 1970 00:00:00 UTC) and cannot convert
// timestamps before that.
func TimeToInt96(t time.Time) [12]byte {
var parquetDate [12]byte
days, nSecs := timeToJD(t)
binary.LittleEndian.PutUint64(parquetDate[:8], nSecs)
binary.LittleEndian.PutUint32(parquetDate[8:], days)
return parquetDate
}