Неожиданный сбой с маршалингом / демаршаллингом объекта времени в Голанге - PullRequest
0 голосов
/ 04 сентября 2018

Не удается распаковать маршалированный объект времени из-за нескольких символов

Test

объявить следующее:

// values
now := time.Now()
timeToJSON, _ := json.Marshal(now)
var obj time.Time
json.Unmarshal(timeToJSON, &obj)

затем выполните следующую тестовую логику:

if !assert.Equal(t,
    now.String(),
    obj.String()) {
    t.FailNow()
}

Ожидается

тест для прохождения, и два объекта должны быть равны

Фактический

Не удалось:

--- FAIL: TestFromJSON (0.00s)
    D:\dev2017\GO\src\ezsoft\apiserver_sdk\model\delete\deleteModel_test.go:94: 
            Error Trace:    deleteModel_test.go:94
            Error:          Not equal: 
                            expected: "2018-09-04 10:36:18.3627338 -0400 EDT m=+0.014000801"
                            actual  : "2018-09-04 10:36:18.3627338 -0400 EDT"

                            Diff:
                            --- Expected
                            +++ Actual
                            @@ -1 +1 @@
                            -2018-09-04 10:36:18.3627338 -0400 EDT m=+0.014000801
                            +2018-09-04 10:36:18.3627338 -0400 EDT
            Test:           TestFromJSON
FAIL
FAIL    ezsoft/apiserver_sdk/model/delete   1.336s
Error: Tests failed.

Примечание

Я замечаю, что при проверке выходных данных каким-то образом m=+[blah] добавляется к ожидаемому / фактическому.

Я не знаю почему, однако, и скимминг RFC 3339 не дает мне никаких намеков, почему.

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

time.String() не является надежным способом проверки значения времени (если вы не заботитесь и о монотонном значении часов). С документы (выделение добавлено):

func (Time) String

func (t Time) String() string

String возвращает время, отформатированное с использованием строки формата

"2006-01-02 15:04:05.999999999 -0700 MST"

Если время имеет монотонное чтение часов, возвращаемая строка содержит конечное поле «m = ±», где значение - это монотонное чтение часов, отформатированное в виде десятичного числа секунд.

Возвращаемая строка предназначена для отладки; для стабильного сериализованного представления используйте t.MarshalText, t.MarshalBinary или t.Format с явной строкой формата.

Для вашего случая использования было бы лучше использовать вывод time.MarshalText() вместо time.String():

expected, _ := now.MarshalText()
actual, _ := obj.MarshalText()

if !assert.Equal(string(expected), string(actual)) ...
0 голосов
/ 04 сентября 2018

Per документация , значение m - это монотонное значение тактового сигнала, которое можно удалить с помощью Truncate для сравнений, а не с целью синхронизации. Поле m не совпадает, так как оно опущено в JSON, оно генерируется только time.Now().

Попробуй так:

// values
now := time.Now().Truncate(0)  // Truncate to remove monotonic clock portion
timeToJSON, _ := json.Marshal(now)
var obj time.Time
json.Unmarshal(timeToJSON, &obj)

Было добавлено монотонное смещение часов, чтобы обеспечить точную синхронизацию длительностей, которые охватывают изменение настенных часов (например, обновление NTP, изменение летнего времени или високосная секунда / мазок).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...