diff --git a/pkg/converters/iif/iif_transaction_data_file_importer_test.go b/pkg/converters/iif/iif_transaction_data_file_importer_test.go index ae2639ab..177ad419 100644 --- a/pkg/converters/iif/iif_transaction_data_file_importer_test.go +++ b/pkg/converters/iif/iif_transaction_data_file_importer_test.go @@ -383,8 +383,8 @@ func TestIIFTransactionDataFileParseImportedData_ParseShortMonthDayTwoDigitsYear "TRNS\t09/2/24\tTest Account\t123.45\n"+ "SPL\t09/2/24\tTest Account2\t-123.45\n"+ "ENDTRNS\t\t\t\n"+ - "TRNS\t9/3/24\tTest Account\t123.45\n"+ - "SPL\t9/3/24\tTest Account2\t-123.45\n"+ + "TRNS\t24/9/3\tTest Account\t123.45\n"+ + "SPL\t24/9/3\tTest Account2\t-123.45\n"+ "ENDTRNS\t\t\t\n"), 0, nil, nil, nil, nil, nil) assert.Nil(t, err) diff --git a/pkg/converters/iif/iif_transaction_data_table.go b/pkg/converters/iif/iif_transaction_data_table.go index f2256a26..e340710d 100644 --- a/pkg/converters/iif/iif_transaction_data_table.go +++ b/pkg/converters/iif/iif_transaction_data_table.go @@ -1,9 +1,7 @@ package iif import ( - "fmt" "strings" - "time" "github.com/mayswind/ezbookkeeping/pkg/converters/datatable" "github.com/mayswind/ezbookkeeping/pkg/core" @@ -441,25 +439,13 @@ func (t *iifTransactionDataRowIterator) parseTransactionTime(dataset *iifTransac day := dateParts[1] year := dateParts[2] - if utils.IsValidYearMonthDayLongOrShortDateFormat(date) { + if utils.IsValidYearMonthDayLongOrShortDateFormat(date) && !utils.IsValidMonthDayYearLongOrShortDateFormat(date) { year = dateParts[0] month = dateParts[1] day = dateParts[2] } - if len(year) == 2 { - year = utils.IntToString(time.Now().Year()/100) + year - } - - if len(month) < 2 { - month = "0" + month - } - - if len(day) < 2 { - day = "0" + day - } - - return fmt.Sprintf("%s-%s-%s 00:00:00", year, month, day), nil + return utils.FormatYearMonthDayToLongDateTime(year, month, day) } func createNewIIfTransactionDataTable(ctx core.Context, accountDatasets []*iifAccountDataset, transactionDatasets []*iifTransactionDataset) (*iifTransactionDataTable, error) { diff --git a/pkg/utils/datetimes.go b/pkg/utils/datetimes.go index 63d9b994..08ca9bcc 100644 --- a/pkg/utils/datetimes.go +++ b/pkg/utils/datetimes.go @@ -65,6 +65,35 @@ func FormatUnixTimeToLongDateTime(unixTime int64, timezone *time.Location) strin return t.Format(longDateTimeFormat) } +func FormatYearMonthDayToLongDateTime(year string, month string, day string) (string, error) { + if len(year) == 2 { + yearLast2Digits, err := StringToInt(year) + + if err != nil { + return "", err + } + + currentYear := time.Now().Year() + currentYearLast2Digits := currentYear % 100 + + if yearLast2Digits <= currentYearLast2Digits { + year = IntToString(currentYear/100) + year + } else { + year = IntToString(currentYear/100-1) + year + } + } + + if len(month) < 2 { + month = "0" + month + } + + if len(day) < 2 { + day = "0" + day + } + + return fmt.Sprintf("%s-%s-%s 00:00:00", year, month, day), nil +} + // FormatUnixTimeToLongDateTimeInServerTimezone returns a textual representation of the unix time formatted by long date time format func FormatUnixTimeToLongDateTimeInServerTimezone(unixTime int64) string { return parseFromUnixTime(unixTime).Format(longDateTimeFormat) diff --git a/pkg/utils/datetimes_test.go b/pkg/utils/datetimes_test.go index aa6cc404..d695b3d0 100644 --- a/pkg/utils/datetimes_test.go +++ b/pkg/utils/datetimes_test.go @@ -46,6 +46,23 @@ func TestFormatUnixTimeToLongDateTime(t *testing.T) { assert.Equal(t, expectedValue, actualValue) } +func TestFormatYearMonthDayToLongDateTime(t *testing.T) { + expectedValue := "2025-06-01 00:00:00" + actualValue, err := FormatYearMonthDayToLongDateTime("25", "06", "01") + assert.Nil(t, err) + assert.Equal(t, expectedValue, actualValue) + + expectedValue = "2025-06-01 00:00:00" + actualValue, err = FormatYearMonthDayToLongDateTime("25", "6", "1") + assert.Nil(t, err) + assert.Equal(t, expectedValue, actualValue) + + expectedValue = "1990-06-01 00:00:00" + actualValue, err = FormatYearMonthDayToLongDateTime("90", "06", "01") + assert.Nil(t, err) + assert.Equal(t, expectedValue, actualValue) +} + func TestFormatUnixTimeToLongDateTimeWithoutSecond(t *testing.T) { unixTime := int64(1617228083) utcTimezone := time.FixedZone("Test Timezone", 0) // UTC diff --git a/pkg/utils/regexps.go b/pkg/utils/regexps.go index 49ec3313..c9b5c087 100644 --- a/pkg/utils/regexps.go +++ b/pkg/utils/regexps.go @@ -9,9 +9,9 @@ var ( longDateTimePattern = regexp.MustCompile("^([1-9][0-9]{3})-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[01]) ([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$") longDateTimeWithoutSecondPattern = regexp.MustCompile("^([1-9][0-9]{3})-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[01]) ([0-1][0-9]|2[0-3]):([0-5][0-9])$") longDatePattern = regexp.MustCompile("^([1-9][0-9]{3})-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[01])$") - longOrShortYearMonthDayDatePattern = regexp.MustCompile("^([1-9][0-9]{3})[-/.']([1-9]|0[1-9]|1[0-2])[-/.']([1-9]|0[1-9]|1[0-9]|2[0-9]|3[01])$") - longOrShortMonthDayYearDatePattern = regexp.MustCompile("^([1-9]|0[1-9]|1[0-2])[-/.']([1-9]|0[1-9]|1[0-9]|2[0-9]|3[01])[-/.']([1-9][0-9]{3})$") - longOrShortDayMonthYearDatePattern = regexp.MustCompile("^([1-9]|0[1-9]|1[0-9]|2[0-9]|3[01])[-/.']([1-9]|0[1-9]|1[0-2])[-/.']([1-9][0-9]{3})$") + longOrShortYearMonthDayDatePattern = regexp.MustCompile("^(([1-9][0-9])?[0-9]{2})[-/.']([1-9]|0[1-9]|1[0-2])[-/.']([1-9]|0[1-9]|1[0-9]|2[0-9]|3[01])$") + longOrShortMonthDayYearDatePattern = regexp.MustCompile("^([1-9]|0[1-9]|1[0-2])[-/.']([1-9]|0[1-9]|1[0-9]|2[0-9]|3[01])[-/.'](([1-9][0-9])?[0-9]{2})$") + longOrShortDayMonthYearDatePattern = regexp.MustCompile("^([1-9]|0[1-9]|1[0-9]|2[0-9]|3[01])[-/.']([1-9]|0[1-9]|1[0-2])[-/.'](([1-9][0-9])?[0-9]{2})$") ) // IsValidUsername reports whether username is valid diff --git a/pkg/utils/regexps_test.go b/pkg/utils/regexps_test.go index d480cf66..8c81bc48 100644 --- a/pkg/utils/regexps_test.go +++ b/pkg/utils/regexps_test.go @@ -236,6 +236,11 @@ func TestIsValidYearMonthDayLongOrShortDateFormat_ValidFormat(t *testing.T) { actualValue := IsValidYearMonthDayLongOrShortDateFormat(datetime) assert.Equal(t, expectedValue, actualValue) + datetime = "24-09-01" + expectedValue = true + actualValue = IsValidYearMonthDayLongOrShortDateFormat(datetime) + assert.Equal(t, expectedValue, actualValue) + datetime = "2024-09-1" expectedValue = true actualValue = IsValidYearMonthDayLongOrShortDateFormat(datetime) @@ -278,6 +283,11 @@ func TestIsValidMonthDayYearLongOrShortDateFormat_ValidFormat(t *testing.T) { actualValue := IsValidMonthDayYearLongOrShortDateFormat(datetime) assert.Equal(t, expectedValue, actualValue) + datetime = "09-01-24" + expectedValue = true + actualValue = IsValidMonthDayYearLongOrShortDateFormat(datetime) + assert.Equal(t, expectedValue, actualValue) + datetime = "09-1-2024" expectedValue = true actualValue = IsValidMonthDayYearLongOrShortDateFormat(datetime) @@ -320,6 +330,11 @@ func TestIsValidDayMonthYearLongDateFormat_ValidLongDateFormat(t *testing.T) { actualValue := IsValidDayMonthYearLongOrShortDateFormat(datetime) assert.Equal(t, expectedValue, actualValue) + datetime = "01-09-24" + expectedValue = true + actualValue = IsValidDayMonthYearLongOrShortDateFormat(datetime) + assert.Equal(t, expectedValue, actualValue) + datetime = "1-09-2024" expectedValue = true actualValue = IsValidDayMonthYearLongOrShortDateFormat(datetime)