Skip to content

Commit

Permalink
fix: date and datetime regression (hay-kot#282)
Browse files Browse the repository at this point in the history
* use custom types.Date implementation

* fix user registration bug

* remove sanity check

* fix datetime bug
  • Loading branch information
hay-kot authored and OrellBuehler committed Jun 24, 2023
1 parent 3d6181b commit dd0d7b6
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 53 deletions.
18 changes: 5 additions & 13 deletions backend/internal/core/services/service_items_csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"io"
"strconv"
"strings"
"time"

"github.com/thechosenlan/homebox/backend/internal/data/repo"
"github.com/thechosenlan/homebox/backend/internal/data/types"
)

func determineSeparator(data []byte) (rune, error) {
Expand Down Expand Up @@ -62,15 +62,6 @@ func parseFloat(s string) float64 {
return f
}

func parseDate(s string) time.Time {
if s == "" {
return time.Time{}
}

p, _ := time.Parse("01/02/2006", s)
return p
}

func parseBool(s string) bool {
switch strings.ToLower(s) {
case "true", "yes", "1":
Expand All @@ -92,6 +83,7 @@ type csvRow struct {
}

func newCsvRow(row []string) csvRow {

return csvRow{
Location: row[1],
LabelStr: row[2],
Expand All @@ -109,13 +101,13 @@ func newCsvRow(row []string) csvRow {
Manufacturer: row[9],
Notes: row[10],
PurchaseFrom: row[11],
PurchaseTime: parseDate(row[13]),
PurchaseTime: types.DateFromString(row[13]),
LifetimeWarranty: parseBool(row[14]),
WarrantyExpires: parseDate(row[15]),
WarrantyExpires: types.DateFromString(row[15]),
WarrantyDetails: row[16],
SoldTo: row[17],
SoldPrice: parseFloat(row[18]),
SoldTime: parseDate(row[19]),
SoldTime: types.DateFromString(row[19]),
SoldNotes: row[20],
},
}
Expand Down
6 changes: 3 additions & 3 deletions backend/internal/core/services/service_items_csv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ func Test_CorrectDateParsing(t *testing.T) {
entity := newCsvRow(record)
expected := expected[i-1]

assert.Equal(t, expected, entity.Item.PurchaseTime, fmt.Sprintf("Failed on row %d", i))
assert.Equal(t, expected, entity.Item.WarrantyExpires, fmt.Sprintf("Failed on row %d", i))
assert.Equal(t, expected, entity.Item.SoldTime, fmt.Sprintf("Failed on row %d", i))
assert.Equal(t, expected, entity.Item.PurchaseTime.Time(), fmt.Sprintf("Failed on row %d", i))
assert.Equal(t, expected, entity.Item.WarrantyExpires.Time(), fmt.Sprintf("Failed on row %d", i))
assert.Equal(t, expected, entity.Item.SoldTime.Time(), fmt.Sprintf("Failed on row %d", i))
}
}

Expand Down
1 change: 1 addition & 0 deletions backend/internal/data/repo/repo_items.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/thechosenlan/homebox/backend/internal/data/ent/label"
"github.com/thechosenlan/homebox/backend/internal/data/ent/location"
"github.com/thechosenlan/homebox/backend/internal/data/ent/predicate"
"github.com/thechosenlan/homebox/backend/internal/data/types"
)

type ItemsRepository struct {
Expand Down
55 changes: 18 additions & 37 deletions backend/internal/data/types/date.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
package types

import (
"errors"
"strings"
"time"
)
import "time"

// Date is a custom type that implements the MarshalJSON interface
// that applies date only formatting to the time.Time fields in order
Expand Down Expand Up @@ -38,21 +34,17 @@ func DateFromString(s string) Date {
return Date{}
}

try := [...]string{
"2006-01-02",
"01/02/2006",
"2006/01/02",
time.RFC3339,
}
t, err := time.Parse("2006-01-02", s)
if err != nil {
// TODO: Remove - used by legacy importer
t, err = time.Parse("01/02/2006", s)

for _, format := range try {
t, err := time.Parse(format, s)
if err == nil {
return DateFromTime(t)
if err != nil {
return Date{}
}
}

return Date{}
return DateFromTime(t)
}

func (d Date) String() string {
Expand All @@ -71,35 +63,24 @@ func (d Date) MarshalJSON() ([]byte, error) {
return []byte(`"` + d.String() + `"`), nil
}

func (d *Date) UnmarshalJSON(data []byte) (err error) {
// unescape the string if necessary `\"` -> `"`
str := strings.Trim(string(data), "\"")
if str == "" || str == "null" || str == `""` {
func (d *Date) UnmarshalJSON(data []byte) error {
str := string(data)
if str == `""` {
*d = Date{}
return nil
}

try := [...]string{
"2006-01-02",
"01/02/2006",
time.RFC3339,
}

set := false
// Try YYYY-MM-DD format
var t time.Time

for _, format := range try {
t, err = time.Parse(format, str)
if err == nil {
set = true
break
t, err := time.Parse("2006-01-02", str)
if err != nil {
// Try default interface
err = t.UnmarshalJSON(data)
if err != nil {
return err
}
}

if !set {
return errors.New("invalid date format")
}

// strip the time and timezone information
*d = DateFromTime(t)

Expand Down

0 comments on commit dd0d7b6

Please sign in to comment.