go-playground / validator

:100:Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving
MIT License
16.53k stars 1.31k forks source link

bug: unable to translate time.Duration validation error #1069

Open wijayaerick opened 1 year ago

wijayaerick commented 1 year ago

Package version eg. v9, v10:

v10

Issue, Question or Enhancement:

The package docs mentioned that time.Duration are supported for some validations e.g. min, max, eq, etc. However the translations code (at least the EN one) fails when time.Duration validation error occurs. It happens because the translation assumes the value to be convertible to number (float), as seen in code below: https://github.com/go-playground/validator/blob/3201fe42fe04a0f4ff45a1e8911c9e84daa5fb93/translations/en/en.go#L167

Code sample, to showcase or reproduce:

https://go.dev/play/p/E2e5iYMb2BC

package main

import (
    "fmt"
    "time"

    "github.com/go-playground/locales/en"
    ut "github.com/go-playground/universal-translator"
    "github.com/go-playground/validator/v10"
    entranslations "github.com/go-playground/validator/v10/translations/en"
)

type Test struct {
    T1 time.Duration `validate:"min=1h30m,max=2h"`
    T2 time.Duration `validate:"min=1h30m,max=2h"`
    T3 time.Duration `validate:"min=1h30m,max=2h"`
}

func main() {
    validate := validator.New()
    enLocale := en.New()
    uniTranslator := ut.New(enLocale, enLocale)
    translator, _ := uniTranslator.GetTranslator("en")
    if err := entranslations.RegisterDefaultTranslations(validate, translator); err != nil {
        panic(err)
    }

    err := validate.Struct(Test{T1: 1 * time.Hour, T2: 2*time.Hour + 10*time.Minute, T3: 1*time.Hour + 40*time.Minute})
    for _, verr := range err.(validator.ValidationErrors) {
        fmt.Printf("  %s (value was '%v')\n", verr.Translate(translator), verr.Value())
    }
    // Expected T1 & T2 to have translated error:
    // - T1 must be 1h30m or more
    // - T2 must be 2h or less
}
vuon9 commented 1 year ago

Looks like the translation's logic hasn't handled for time.Duration value yet.