Skip to content

Commit

Permalink
Merge pull request #10 from aj3sh/refactor/date-converter
Browse files Browse the repository at this point in the history
 Refactored dateConverter code with one single reference point #8
  • Loading branch information
sugat009 authored Feb 19, 2023
2 parents 8184b16 + ebcaf61 commit 75730b7
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 40 deletions.
127 changes: 87 additions & 40 deletions dateConverter/converter.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// This package contains the date converter functions.
// Reference date for conversion is 2000/01/01 BS and 1943/4/14 AD
//
// USAGE:
// y, m, d := EnglishToNepali(2023, 1, 15)
Expand All @@ -11,6 +10,10 @@ import (
"math"
)

// Reference date for conversion is 2000/01/01 BS and 1943/4/14 AD
var npInitialYear int16 = 2000
var referenceEnDate = [3]int16{1943, 4, 14}

type NepaliMonthData struct {
monthData [12]int8
yearDays int16
Expand All @@ -20,7 +23,7 @@ var enMonths = [12]int8{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
var enLeapMonths = [12]int8{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

var npMonthData = [100]NepaliMonthData{
{[12]int8{30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31}, 365}, // 2000 BS - 1944 AD
{[12]int8{30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31}, 365}, // 2000 BS - 1943/1944 AD
{[12]int8{31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30}, 365}, // 2001 BS
{[12]int8{31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30}, 365},
{[12]int8{31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31}, 366},
Expand Down Expand Up @@ -122,11 +125,63 @@ var npMonthData = [100]NepaliMonthData{
{[12]int8{31, 31, 32, 31, 31, 31, 30, 29, 29, 30, 30, 30}, 365}, // 2099 BS - 2042 AD
}

func enMinYear() int {
return int(referenceEnDate[0]) + 1
}

func enMaxYear() int {
return int(referenceEnDate[0]) + len(npMonthData) - 1
}

func npMinYear() int {
return int(npInitialYear)
}

func npMaxYear() int {
return int(npInitialYear) + len(npMonthData) - 1
}

/* Checks if the english year is leap year or not */
func isLeapYear(year int) bool {
if year%4 == 0 {
if year%100 == 0 {
return (year%400 == 0)
}
return true
}
return false
}

func getEnMonths(year int) *[12]int8 {
if isLeapYear(year) {
return &enLeapMonths
}
return &enMonths
}

/*
Returns diff from the reference with its absolute reference.
Used in function `NepaliToEnglish`.
Eg. ref: 1943/4/14 - 1943/01/01
*/
func getDiffFromEnAbsoluteReference() int {
var diff int = 0

// adding sum of month of year till the reference month
months := getEnMonths(int(referenceEnDate[0]))
for i := 0; i < int(referenceEnDate[1])-1; i++ {
diff += int(months[i])
}

return diff + int(referenceEnDate[2]) - 1 // added day too
}

// ENGLISH DATE CONVERSION

// checks if english date in within range 1944 - 2042
func checkEnglishDate(year int, month int, day int) bool {
if year < 1944 || year > 2042 {
if year < enMinYear() || year > enMaxYear() {
return false
}
if month < 1 || month > 12 {
Expand Down Expand Up @@ -156,27 +211,27 @@ func getTotalDaysFromEnglishDate(year int, month int, day int) int {

// NEPALI DATE CONVERSION

// checks if nepali date is in range 2000-2098
// checks if nepali date is in range
func checkNepaliDate(year int, month int, day int) bool {
if year < 2000 || year > 2098 {
if year < npMinYear() || year > npMaxYear() {
return false
}
if month < 1 || month > 12 {
return false
}

if day < 1 || day > int(npMonthData[year-2000].monthData[month-1]) {
if day < 1 || day > int(npMonthData[year-int(npInitialYear)].monthData[month-1]) {
return false
}
return true
}

// counts and returns total days from the nepali date 2000-01-01
// counts and returns total days from the nepali initial date
func getTotalDaysFromNepaliDate(year int, month int, day int) int {
var totalDays int = day - 1

// adding days of months of 2000
var yearIndex int = year - 2000
// adding days of months of initial year
var yearIndex int = year - int(npInitialYear)
for i := 0; i < month-1; i++ {
totalDays = totalDays + int(npMonthData[yearIndex].monthData[i])
}
Expand All @@ -188,22 +243,11 @@ func getTotalDaysFromNepaliDate(year int, month int, day int) int {
return totalDays
}

// checks if the english year is leap year or not"""
func isLeapYear(year int) bool {
if year%4 == 0 {
if year%100 == 0 {
return (year%400 == 0)
}
return true
}
return false
}

// Public methods

// Converts english date to nepali.
// Accepts the input parameters year, month, day
// Returns multi value of year, month, day
// Accepts the input parameters year, month, day.
// Returns dates in array and error.
func EnglishToNepali(year int, month int, day int) (*[3]int, error) {
// VALIDATION
// checking if date is in range
Expand All @@ -212,14 +256,19 @@ func EnglishToNepali(year int, month int, day int) (*[3]int, error) {
}

// REFERENCE
// Setting nepali reference to 2000/01/01 with english date 1943/04/14
npYear := 2000
npMonth := 1
npDay := 1
npYear, npMonth, npDay := int(npInitialYear), 1, 1

// DIFFERENCE
// calculating difference days from 1943/04/14
var difference int = int(math.Abs(float64(getTotalDaysFromEnglishDate(year, month, day) - getTotalDaysFromEnglishDate(1943, 4, 14))))
// calculating days count from the reference date
var difference int = int(
math.Abs(float64(
getTotalDaysFromEnglishDate(
year, month, day,
) - getTotalDaysFromEnglishDate(
int(referenceEnDate[0]), int(referenceEnDate[1]), int(referenceEnDate[2]),
),
)),
)

// YEAR
// Incrementing year until the difference remains less than 365
Expand Down Expand Up @@ -247,8 +296,8 @@ func EnglishToNepali(year int, month int, day int) (*[3]int, error) {
}

// Converts nepali date to english.
// Accepts the input parameters year, month, day
// Returns multi value of year, month, day
// Accepts the input parameters year, month, day.
// Returns dates in array and error.
func NepaliToEnglish(year int, month int, day int) (*[3]int, error) {
// VALIDATION
// checking if date is in range
Expand All @@ -257,14 +306,15 @@ func NepaliToEnglish(year int, month int, day int) (*[3]int, error) {
}

// REFERENCE
// Setting english reference to 1944/01/01 with nepali date 2000/09/17
enYear := 1944
enMonth := 1
enDay := 1
// For absolute reference, moving date to Jan 1
// Eg. ref: 1943/4/14 => 1943/01/01
enYear, enMonth, enDay := int(referenceEnDate[0]), 1, 1
// calculating difference from the adjusted reference (eg. 1943/4/14 - 1943/01/01)
referenceDiff := getDiffFromEnAbsoluteReference()

// DIFFERENCE
// calculating difference days from 2000/09/17
var difference int = int(math.Abs(float64(getTotalDaysFromNepaliDate(year, month, day) - getTotalDaysFromNepaliDate(2000, 9, 17))))
// calculating days count from the reference date
var difference int = getTotalDaysFromNepaliDate(year, month, day) + referenceDiff

// YEAR
// Incrementing year until the difference remains less than 365 (or 365)
Expand All @@ -279,10 +329,7 @@ func NepaliToEnglish(year int, month int, day int) (*[3]int, error) {

// MONTH
// Incrementing month until the difference remains less than next english month (mostly 31)
var monthDays [12]int8 = enMonths
if isLeapYear(enYear) {
monthDays = enLeapMonths
}
monthDays := getEnMonths(enYear)

var i int = 0
for difference >= int(monthDays[i]) {
Expand Down
24 changes: 24 additions & 0 deletions dateConverter/converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ func TestEnglishToNepaliReturnsValidFutureNepaliDate(t *testing.T) {
assert.EqualValues(t, *date, [3]int{2087, 8, 10})
}

func TestEnglishToNepaliForMinEdgeDate(t *testing.T) {
date, err := dateConverter.EnglishToNepali(1944, 1, 1)
assert.Nil(t, err)
assert.EqualValues(t, *date, [3]int{2000, 9, 17})
}

func TestEnglishToNepaliForMaxEdgeDate(t *testing.T) {
date, err := dateConverter.EnglishToNepali(2042, 12, 31)
assert.Nil(t, err)
assert.EqualValues(t, *date, [3]int{2099, 9, 16})
}

// NepaliToEnglish

func TestNepaliToEnglishReturnErrorOnMaxYearRange(t *testing.T) {
Expand Down Expand Up @@ -128,3 +140,15 @@ func TestNepaliToEnglishReturnsValidEnglishLeapYearDate(t *testing.T) {
assert.Nil(t, err)
assert.EqualValues(t, *date, [3]int{2024, 3, 28})
}

func TestNepaliToEnglishForMinEdgeDate(t *testing.T) {
date, err := dateConverter.NepaliToEnglish(2000, 1, 1)
assert.Nil(t, err)
assert.EqualValues(t, *date, [3]int{1943, 4, 14})
}

func TestNepaliToEnglishForMaxEdgeDate(t *testing.T) {
date, err := dateConverter.NepaliToEnglish(2099, 12, 30)
assert.Nil(t, err)
assert.EqualValues(t, *date, [3]int{2043, 4, 13})
}

0 comments on commit 75730b7

Please sign in to comment.