diff options
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()) -} | 
