go-hep.org/x/hep@v0.38.1/groot/rbase/datime.go (about) 1 // Copyright ©2022 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package rbase 6 7 import ( 8 "fmt" 9 "reflect" 10 "time" 11 12 "go-hep.org/x/hep/groot/rbytes" 13 "go-hep.org/x/hep/groot/rtypes" 14 "go-hep.org/x/hep/groot/rvers" 15 ) 16 17 // Datime is a ROOT date + time. 18 // Note that ROOT's TDatime is relative to 1995. 19 type Datime time.Time 20 21 func (*Datime) Class() string { 22 return "TDatime" 23 } 24 25 func (*Datime) RVersion() int16 { 26 return rvers.Datime 27 } 28 29 // MarshalROOT implements rbytes.Marshaler 30 func (dt *Datime) MarshalROOT(w *rbytes.WBuffer) (int, error) { 31 if w.Err() != nil { 32 return 0, w.Err() 33 } 34 35 // TDatime does not write a version header. 36 w.WriteU32(time2datime(time.Time(*dt))) 37 38 return 4, w.Err() 39 } 40 41 // UnmarshalROOT implements rbytes.Unmarshaler 42 func (dt *Datime) UnmarshalROOT(r *rbytes.RBuffer) error { 43 if r.Err() != nil { 44 return r.Err() 45 } 46 47 // TDatime does not write a version header. 48 *dt = Datime(datime2time(r.ReadU32())) 49 50 return r.Err() 51 } 52 53 func (dt Datime) String() string { 54 return dt.Time().String() 55 } 56 57 func (dt Datime) Time() time.Time { return time.Time(dt) } 58 59 func init() { 60 f := func() reflect.Value { 61 var o Datime 62 return reflect.ValueOf(&o) 63 } 64 rtypes.Factory.Add("TDatime", f) 65 } 66 67 // time2datime converts a time.Time to a uint32 representing a ROOT's TDatime. 68 func time2datime(t time.Time) uint32 { 69 var ( 70 year = uint32(t.Year()) 71 month = uint32(t.Month()) 72 day = uint32(t.Day()) 73 hour = uint32(t.Hour()) 74 min = uint32(t.Minute()) 75 sec = uint32(t.Second()) 76 ) 77 78 if year < 1995 { 79 panic(fmt.Errorf("rbase: TDatime year must be >= 1995")) 80 } 81 82 return (year-1995)<<26 | month<<22 | day<<17 | hour<<12 | min<<6 | sec 83 } 84 85 // datime2time converts a uint32 holding a ROOT's TDatime into a time.Time 86 func datime2time(d uint32) time.Time { 87 88 // ROOT's TDatime begins in January 1995... 89 var year uint32 = (d >> 26) + 1995 90 var month uint32 = (d << 6) >> 28 91 var day uint32 = (d << 10) >> 27 92 var hour uint32 = (d << 15) >> 27 93 var min uint32 = (d << 20) >> 26 94 var sec uint32 = (d << 26) >> 26 95 nsec := 0 96 return time.Date(int(year), time.Month(month), int(day), 97 int(hour), int(min), int(sec), nsec, time.UTC) 98 }