From 04eecf81563fdc0c2f6d2cf1a30fdaa8f0e25e30 Mon Sep 17 00:00:00 2001
From: ko_oler <kooler89@gmail.com>
Date: Tue, 22 Aug 2023 14:32:07 +0300
Subject: [PATCH] =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF?=
 =?UTF-8?q?=D0=BE=20=D0=9F=D0=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 pkg/schema/field/timestamp.go      | 51 ++++++++++++++++++++++--------
 pkg/schema/field/timestamp_test.go | 15 +++++++--
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/pkg/schema/field/timestamp.go b/pkg/schema/field/timestamp.go
index 66f6d4fb..cbe95923 100644
--- a/pkg/schema/field/timestamp.go
+++ b/pkg/schema/field/timestamp.go
@@ -2,11 +2,11 @@ package field
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	"reflect"
-	"strconv"
-	"strings"
+	"time"
+
+	"git.perx.ru/perxis/perxis-go/pkg/errors"
 )
 
 var timestampType = &TimestampType{}
@@ -37,22 +37,45 @@ func (TimestampType) Decode(_ context.Context, _ *Field, v interface{}) (interfa
 
 	switch i := v.(type) {
 	case string:
-		t := strings.Split(i, ":")
-		if len(t) == 3 {
-			hourToSeconds, _ := strconv.Atoi(t[0])
-			minutesToSeconds, _ := strconv.Atoi(t[1])
-			seconds, _ := strconv.Atoi(t[2])
-			return int64(hourToSeconds*3600 + minutesToSeconds*60 + seconds), nil
+		duration, err := time.ParseDuration(i)
+		if err != nil {
+			t, err := time.Parse(time.TimeOnly, i)
+			if err != nil {
+				return nil, errors.Wrap(err, "wrong format")
+			}
+			return t.Sub(time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())).Nanoseconds(), nil
+		}
+		return duration.Nanoseconds(), nil
+	default:
+		v, err := ToInt(i)
+		if err != nil {
+			return nil, fmt.Errorf("TimestampField decode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind())
 		}
-		return nil, errors.New("wrong time format: input in 'HH:MM:SS'")
+		return v, nil
+	}
+}
 
+func ToInt(i interface{}) (interface{}, error) {
+	switch v := i.(type) {
 	case int64:
-		return i, nil
+		return v, nil
+	case int:
+		return int64(v), nil
+	case int8:
+		return int64(v), nil
+	case int32:
+		return int64(v), nil
 	case uint64:
-		return int64(i), nil
+		return v, nil
+	case uint:
+		return uint64(v), nil
+	case uint8:
+		return uint64(v), nil
+	case uint32:
+		return uint64(v), nil
+	default:
+		return 0, errors.Errorf("error convert \"%s\" to timestamp", i)
 	}
-
-	return nil, fmt.Errorf("TimestampField decode error: unsupported value type : \"%s\"", reflect.ValueOf(v).Kind())
 }
 
 func (TimestampType) Encode(_ context.Context, _ *Field, v interface{}) (interface{}, error) {
diff --git a/pkg/schema/field/timestamp_test.go b/pkg/schema/field/timestamp_test.go
index 1665c571..94be768b 100644
--- a/pkg/schema/field/timestamp_test.go
+++ b/pkg/schema/field/timestamp_test.go
@@ -14,14 +14,23 @@ func TestTimestamp_Decode(t *testing.T) {
 		want    interface{}
 		wantErr bool
 	}{
-		{"Correct", Timestamp(), int64(2), int64(2), false},       // #0
-		{"Correct", Timestamp(), uint64(2), int64(2), false},      // #1
-		{"Correct", Timestamp(), "13:10:44", int64(47444), false}, // #2
+		{"Correct", Timestamp(), int64(2), int64(2), false},                 // #0
+		{"Correct", Timestamp(), uint64(2), uint64(2), false},               // #1
+		{"Correct", Timestamp(), 2, int64(2), false},                        // #2
+		{"Correct", Timestamp(), "13h10m44s", int64(47444000000000), false}, // #3
+		{"Correct", Timestamp(), "24h", int64(86400000000000), false},       // #4
+		{"Correct", Timestamp(), "2.5h", int64(9000000000000), false},       // #5
+		{"Correct", Timestamp(), "-5h", int64(-18000000000000), false},      // #5
+		{"Correct", Timestamp(), "13:10:44", int64(47444000000000), false},  // #6
+		{"Correct", Timestamp(), "23:59:59", int64(86399000000000), false},  // #7
+		{"Correct", Timestamp(), "00:00:00", int64(0), false},               // #8
+		{"Correct", Timestamp(), "00:00:01", int64(1000000000), false},      // #8
 
 		{"Wrong data", Timestamp(), "", nil, true},         // #0
 		{"Wrong data", Timestamp(), []byte(""), nil, true}, // #1
 		{"Wrong data", Timestamp(), 2.2, nil, true},        // #2
 		{"Wrong data", Timestamp(), "13:10", nil, true},    // #3
+		{"Wrong data", Timestamp(), "24:00:00", nil, true}, // #4
 
 	}
 	for _, tt := range tests {
-- 
GitLab