diff options
author | Paul Duncan <pabs@pablotron.org> | 2022-03-15 00:17:07 -0400 |
---|---|---|
committer | Paul Duncan <pabs@pablotron.org> | 2022-03-15 00:17:07 -0400 |
commit | a00d4d0fd4c7e9b4e5ecf97e3bb978f680541dba (patch) | |
tree | fe3f149cb41b456ead3db929f1b18c54edb1777f /cisa/date.go | |
parent | 3c678605abb7003085652cc2008dd8cbd4e3eec2 (diff) | |
download | cvez-a00d4d0fd4c7e9b4e5ecf97e3bb978f680541dba.tar.bz2 cvez-a00d4d0fd4c7e9b4e5ecf97e3bb978f680541dba.zip |
move cisa/date.go to rfc3339/date.go
Diffstat (limited to 'cisa/date.go')
-rw-r--r-- | cisa/date.go | 164 |
1 files changed, 0 insertions, 164 deletions
diff --git a/cisa/date.go b/cisa/date.go deleted file mode 100644 index b3b6528..0000000 --- a/cisa/date.go +++ /dev/null @@ -1,164 +0,0 @@ -package cisa - -import ( - "encoding/json" - "fmt" - "regexp" - "strconv" -) - -// YYYY-MM-DD -type Date uint16 - -// Returns true if the year is a leap year, and false otherwise. -// -// Reference: -// https://www.timeanddate.com/date/leapyear.html -func isLeapYear(y uint16) bool { - // leap year rules: - // 1. year is evenly divisible by 4 and is not evenly divisible by 100 - // 2. year is evenly divisible by 4 and is evenly divisible by 400 - return (((y % 4) == 0) && ((y % 100) != 0)) || // rule 1 - (((y % 4) == 0) && ((y % 400) == 0)) // rule 2 -} - -// maximum month days -var maxMonthDays = []uint16 { - 31, // jan - 28, // feb (incorrect for leap years!) - 31, // mar - 30, // apr - 31, // may - 30, // jun - 31, // jul - 31, // aug - 30, // sep - 31, // oct - 30, // nov - 31, // dec -} - -// Get the maximum day for the given year and month. -func getMaxMonthDay(y, m uint16) uint16 { - if m == 2 && isLeapYear(y) { - return 29 - } else { - return maxMonthDays[m - 1] - } -} - -// Parse date component and check range. -func parseDateComponent(name string, s []byte, min, max uint16) (uint16, error) { - // parse value - vr, err := strconv.ParseUint(string(s), 10, 32) - if err != nil { - return 0, err - } - - v := uint16(vr) - - // check range - if v < min || v > max { - return 0, fmt.Errorf("%s component out of range [%d, %d]: %d", name, v, min, max) - } - - return uint16(v), nil -} - -var dateRe = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`) - -// Create date from byte slice. -func NewDate(s []byte) (Date, error) { - var r Date - - if !dateRe.Match(s) { - return r, fmt.Errorf("invalid date: \"%s\"", s) - } - - // parse year - y, err := parseDateComponent("year", s[0:4], 1999, 2126) - if err != nil { - return r, err - } - - // parse month - m, err := parseDateComponent("month", s[5:7], 1, 12) - if err != nil { - return r, err - } - - // parse day - d, err := parseDateComponent("month", s[8:10], 1, getMaxMonthDay(y, m)) - if err != nil { - return r, err - } - - // encode return date - r = Date((((y - 1999) & 0x3f) << 9) | - (((m - 1) & 0xf) << 5) | - ((d - 1) & 0x1f)) - - // return result - return r, nil -} - -// Get year, month, and day components. -func (me Date) GetComponents() (uint16, uint16, uint16) { - // extract components - y := uint16((uint16(me) >> 9) + 1999) - m := uint16(((uint16(me) >> 5) & 0xf) + 1) - d := uint16((uint16(me) & 0x1f) + 1) - - return y, m, d -} - -// Get year component. -func (me Date) Year() uint16 { - y, _, _ := me.GetComponents() - return y -} - -// Get month component. -func (me Date) Month() uint16 { - _, m, _ := me.GetComponents() - return m -} - -// Get day component. -func (me Date) Day() uint16 { - _, _, d := me.GetComponents() - return d -} - -// Convert to string. -func (me Date) String() string { - // extract date components - y, m, d := me.GetComponents() - - // return string - return fmt.Sprintf("%04d-%02d-%02d", y, m, d) -} - -// Unmarshal date from JSON string. -func (me *Date) UnmarshalJSON(b []byte) error { - // decode json string - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // create date - d, err := NewDate([]byte(s)) - if err != nil { - return err - } - - // save result, return success - *me = d - return nil -} - -// Marshal Date as JSON string. -func (d Date) MarshalJSON() ([]byte, error) { - return json.Marshal(d.String()) -} |