Skip to content

Commit

Permalink
More interface refinement
Browse files Browse the repository at this point in the history
  • Loading branch information
neomantra committed Aug 12, 2023
1 parent 4025f80 commit f6107d2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 15 deletions.
49 changes: 37 additions & 12 deletions ymdflag.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ type YMDFlag struct {

///////////////////////////////////////////////////////////////////////////////

// TODO: internal error consts how?

// YMDtoTime returns the Time corresponding to the YYYYMMDD in the specified location.
// A nil location implies local time.
func YMDToTime(yyyymmdd int, loc *time.Location) time.Time {
Expand All @@ -52,6 +54,27 @@ func TimeToYMD(t time.Time) int {
}
}

// ValidateYMD returns nil if the passed `yyyymmdd` is of a proper YYYYMMDD form. Zero is a valid value, indicating auto-detection.
// Otherwise, returns an error.
// This function is not forgiving like `time.Date`, e.g. 10/32 (Oct 32) is not considered 11/01 (Nov 1).
func ValidateYMD(yyyymmdd int) error {
if yyyymmdd == 0 {
return nil
} else if yyyymmdd < 0 {
return fmt.Errorf("yyyymmdd is negative")
} else if yyyymmdd > 99999999 {
return fmt.Errorf("yyyymmdd is more than 8 digits")
}
var year int = yyyymmdd / 10000
var month int = (yyyymmdd % 10000) / 100
var day int = yyyymmdd % 100
dt := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.Local)
if year != dt.Year() || month != int(dt.Month()) || day != dt.Day() {
return fmt.Errorf("yyyymmdd is bad or unnormalized")
}
return nil
}

///////////////////////////////////////////////////////////////////////////////
// flag.Value interface

Expand Down Expand Up @@ -110,9 +133,12 @@ func NewYMDFlagWithLocation(loc *time.Location) YMDFlag {
}

// NewYMDFlag creates a new YMDFlag for the given integral `YYYYMMDD` value, for example `20230704`.
// No validation is performed.
func NewYMDFlagFromInt(i int, loc *time.Location) YMDFlag {
return YMDFlag{yyyymmdd: i, loc: loc}
// Returns a non-nil error if YMDFlag is malformed. `0` is a valid value.
func NewYMDFlagFromInt(i int, loc *time.Location) (YMDFlag, error) {
if err := ValidateYMD(i); err != nil {
return YMDFlag{}, err
}
return YMDFlag{yyyymmdd: i, loc: loc}, nil
}

// GetYMD returns the YMDFlag as integer `YYYYMMDD`. It may be zero.
Expand Down Expand Up @@ -151,13 +177,13 @@ func (ymd *YMDFlag) AsYMDString() string {
// AsDirPath returns the YMDFlag as `"YYYY/MM/DD"` using the OS path seperator
// If the YMDFlag is nil, then a date fetch occurs, updating it to the current date according to the YMDFlag timezone.
func (ymd *YMDFlag) AsDirPath() string {
return formatDirPath(ymd.AsTime())
return formatDirPath(ymd.AsTime(), os.PathSeparator)
}

// AsDirPathNoCheck returns the YMDFlag as `"YYYY/MM/DD"` using the OS path seperator
// Note: This method does not check if zeroed. Ensure you call it with a non-zero YMDFlag
func (ymd YMDFlag) AsDirPathNoCheck() string {
return formatDirPath(ymd.AsTimeNoCheck())
// AsDirPath returns the YMDFlag as `"YYYY/MM/DD"` using given path seperator
// If the YMDFlag is nil, then a date fetch occurs, updating it to the current date according to the YMDFlag timezone.
func (ymd *YMDFlag) AsDirPathSep(separator rune) string {
return formatDirPath(ymd.AsTime(), separator)
}

// AsTime returns the YMDFlag as a time.Time in the YMDFlag's location.
Expand Down Expand Up @@ -188,10 +214,9 @@ func (ymd *YMDFlag) UpdateNilToNow() {

//////////////////////////////////////////////////////////////////////////////

// formatDirPath returns the `time` as `"YYYY/MM/DD"` using the OS path seperator.
func formatDirPath(time time.Time) string {
return time.Format(fmt.Sprintf(
"2006%c01%c02", os.PathSeparator, os.PathSeparator))
// formatDirPath returns the `time` as `"YYYY/MM/DD"` using the given path seperator.
func formatDirPath(time time.Time, sep rune) string {
return time.Format(fmt.Sprintf("2006%c01%c02", sep, sep))
}

// isInt checks if a string can be converted safely to an int
Expand Down
6 changes: 3 additions & 3 deletions ymdflag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ func Test_uninitializaed_flag_becomes_today_when_accessed(t *testing.T) {
func TestNonMutatingMethods(t *testing.T) {
ymdFlag := NewYMDFlag(time.Date(2020, time.January, 2, 1, 2, 3, 4, time.UTC))

var dirPath = ymdFlag.AsDirPathNoCheck()
assert.Equal(t, "2020/01/02", dirPath, "should match given date")

var timeValue = ymdFlag.AsTimeNoCheck()
assert.Equal(t, time.Date(2020, time.January, 2, 0, 0, 0, 0, time.UTC), timeValue, "should not have a time component")

var dirPath = formatDirPath(timeValue, '/')
assert.Equal(t, "2020/01/02", dirPath, "should match given date path")
}

0 comments on commit f6107d2

Please sign in to comment.