diff --git a/bsdate.go b/bsdate.go index 0bf8bda..8e98bd3 100644 --- a/bsdate.go +++ b/bsdate.go @@ -197,7 +197,29 @@ func NewFromGregorian(gregorianDay, gregorianMonth, gregorianYear int) (Date, er // we use this value to check if the gregorian Date is in the actual BS month if _, ok := calendardata[bsYear]; !ok { - return nil, errors.New("cannot convert date, missing data") + return nil, errors.New("cannot convert date, invalid or missing data") + } + + // Months with 31 days + if gregorianMonth == 2 || gregorianMonth == 4 || gregorianMonth == 6 || + gregorianMonth == 9 || gregorianMonth == 11 { + if gregorianDay > 30 { + return nil, errors.New("cannot convert date, invalid or missing data") + } + } + // is the year leap year? Leap year has 29 days in february + if (gregorianYear%4 == 0 && gregorianYear%100 != 0) || gregorianYear%400 == 0 { + if gregorianMonth == 2 && gregorianDay > 29 { + return nil, errors.New("cannot convert date, invalid or missing data") + } + } else { + if gregorianMonth == 2 && gregorianDay > 28 { + return nil, errors.New("cannot convert date, invalid or missing data") + } + } + + if gregorianMonth > 12 || gregorianDay > 31 { + return nil, errors.New("cannot convert date, invalid or missing data") } year := time.Date(gregorianYear, time.Month(gregorianMonth), gregorianDay, 0, 0, 0, 0, time.UTC) @@ -225,7 +247,7 @@ func NewFromGregorian(gregorianDay, gregorianMonth, gregorianYear int) (Date, er bsMonth = 1 bsYear++ if _, ok := calendardata[bsYear]; !ok { - return nil, errors.New("cannot convert date, missing data") + return nil, errors.New("cannot convert date, invalid or missing data") } } daysSinceJanFirstToEndOfBsMonth += calendardata[bsYear][bsMonth] @@ -277,12 +299,12 @@ func (d date) isValid() bool { return true } -func (d date) GetGregorianDate() (time.Time, error) { +func (d date) GetGregorianDate() (time.Time, error) { var daysAfterJanFirstOfGregorianYear = 0 //we will add all the days that went by since the 1st. //January and then we can get the gregorian Date var gregorianYear int - var nepaliMonthToCheck = d.Month - var nepaliYearToCheck = d.Year + var nepaliMonthToCheck = d.Month + var nepaliYearToCheck = d.Year //get the correct year @@ -302,13 +324,13 @@ func (d date) GetGregorianDate() (time.Time, error) { //now we loop through all nepali months and add the amount of days to daysAfterJanFirstOfGregorianYear //we do this till we reach Paush (9th month). 1st. January always falls in this month - for ; nepaliMonthToCheck != 9 ;nepaliMonthToCheck-- { + for ; nepaliMonthToCheck != 9; nepaliMonthToCheck-- { if nepaliMonthToCheck <= 0 { nepaliMonthToCheck = 12 nepaliYearToCheck-- //do we have data of that year? if _, ok := calendardata[nepaliYearToCheck]; !ok { - return time.Time{}, errors.New("cannot convert date, missing data") + return time.Time{}, errors.New("cannot convert date, invalid or missing data") } } daysAfterJanFirstOfGregorianYear += calendardata[nepaliYearToCheck][nepaliMonthToCheck] diff --git a/bsdate_test.go b/bsdate_test.go index 02f7d1e..65f4eca 100644 --- a/bsdate_test.go +++ b/bsdate_test.go @@ -63,6 +63,7 @@ var invalidDates = []TestDateStruc{ {1, 1, "", 2101}, //no data after BS 2100 {32, 1, "", 2076}, //this month has only 31 days {31, 12, "", 2067}, //this month has only 30 days + {30, 13, "", 2070}, } var convertedDates = []TestDateConversionStruc{ @@ -89,6 +90,7 @@ var convertedDates = []TestDateConversionStruc{ {"2076-02-32", "2019-06-15"}, //end of a month with 32 days {"2076-03-01", "2019-06-16"}, //a month after a month with 32 days {"2100-12-30", "2044-04-12"}, //last day, we can convert in both directions + {"2076-11-18", "2020-03-01"}, } func TestValidBSDates(t *testing.T) { for _, testCase := range validDates { @@ -167,7 +169,7 @@ func TestConversionInvalidToGregorian(t *testing.T) { var convertedGregorianDate time.Time convertedGregorianDate, err = nepaliDate.GetGregorianDate() expectedGregorianDate, _ := time.Parse("2006-01-02", "0001-01-01") - assert.Equal(t, err.Error(), "cannot convert date, missing data") + assert.Equal(t, err.Error(), "cannot convert date, invalid or missing data") assert.Equal(t, convertedGregorianDate, expectedGregorianDate) }) } @@ -193,6 +195,10 @@ var impossibleToConvertFromGregorianDates = [] string { "2045-01-01", //2045 and after cannot be converted because 2045+56=2101 and we do not have data for that BS year "2045-05-01", "2044-04-13", //this date would be BS 2101-01-01 and we do not have data for that BS year + "2019-02-29", + "2019-13-22", + "2010-11-32", + "2020-02-30", } func TestCreateFromInvalidGregorian(t *testing.T) { for _, testCase := range impossibleToConvertFromGregorianDates { @@ -200,7 +206,7 @@ func TestCreateFromInvalidGregorian(t *testing.T) { var gregorianYear, gregorianMonth, gregorianDay = splitDateString(testCase) bsDate, err := NewFromGregorian(gregorianDay, gregorianMonth, gregorianYear) - assert.Equal(t, err.Error(), "cannot convert date, missing data") + assert.Equal(t, err.Error(), "cannot convert date, invalid or missing data") assert.Equal(t, bsDate, nil) }) }