Golang中如何验证日期
Golang中如何验证日期
我获取到一个字符串格式的出生日期(“12345678”),并通过使用 time.Parse 将该字符串转换为日期。我的函数在这一部分之前工作正常,但如果有人输入了错误的出生日期,它不会给我返回错误。例如:如果我输入 “00000000”,我将不会收到任何错误。请问你能帮我解决这个问题吗?
func (p *Package1) checkBirthdate {
if len(p.Birthdate) != 0 {
_, err := time.Parse("2006-01-02", p.Birthdate[0:4]+"-"+p.Birthdate[4:6]+"-"+p.Birthdate[6:8])
if err != nil {
fmt. Printf("Error occured %s", p.Birthdate)
}
}
更多关于Golang中如何验证日期的实战教程也可以访问 https://www.itying.com/category-94-b0.html
Yo_94:
12345678
这个值代表什么日期?你是指像 19700228 这样代表 1970 年 2 月 28 日的形式吗?
更多关于Golang中如何验证日期的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
是的,这应该是其表示形式。 所以,就像如果我输入“00000000”,那么我应该得到一个错误,提示这不是一个有效的日期;或者如果我输入“20200230”,那么我也应该得到一个错误,但我的函数并没有返回这个错误。
我无法复现您描述的行为。请参考以下代码:
package main
import (
"fmt"
"time"
)
func parse(s string) (time.Time, error) {
d, err := time.Parse("2006-01-02", s)
if err != nil {
return d, err
}
return d, nil
}
func main() {
d, err := parse("1970-02-28")
if err != nil {
panic(err)
}
fmt.Println(d)
d, err = parse("0000-00-00")
if err != nil {
panic(err)
}
fmt.Println(d)
}
第一次调用 parse 函数返回一个有效日期,而第二次调用则返回一个错误。这一切都符合预期。
参见 https://play.golang.org/p/k8hW04pz6yM
输出:
1970-02-28 00:00:00 +0000 UTC
panic: parsing time "0000-00-00": month out of range
在Go中验证日期时,time.Parse 只会检查日期格式是否有效,但不会验证日期的合理性。例如,"0000-00-00" 在格式上符合 "2006-01-02",因此不会返回错误。要解决这个问题,你需要在解析后添加额外的验证逻辑。以下是一个改进的示例代码:
func (p *Package1) checkBirthdate() error {
if len(p.Birthdate) == 0 {
return nil // 或者返回一个错误,取决于你的需求
}
// 确保字符串长度至少为8位
if len(p.Birthdate) < 8 {
return fmt.Errorf("invalid birthdate length: %s", p.Birthdate)
}
// 解析日期
birthdateStr := p.Birthdate[0:4] + "-" + p.Birthdate[4:6] + "-" + p.Birthdate[6:8]
t, err := time.Parse("2006-01-02", birthdateStr)
if err != nil {
return fmt.Errorf("failed to parse birthdate %s: %v", p.Birthdate, err)
}
// 验证日期合理性:年份、月份和日期应在有效范围内
year := t.Year()
month := t.Month()
day := t.Day()
// 检查年份是否合理(例如,出生日期通常在1900年之后)
if year < 1900 || year > time.Now().Year() {
return fmt.Errorf("invalid year in birthdate: %s", p.Birthdate)
}
// 检查月份是否在1到12之间
if month < 1 || month > 12 {
return fmt.Errorf("invalid month in birthdate: %s", p.Birthdate)
}
// 检查日期是否在1到31之间(更精确的检查可以考虑月份和闰年)
if day < 1 || day > 31 {
return fmt.Errorf("invalid day in birthdate: %s", p.Birthdate)
}
// 可选:进一步验证日期是否实际存在(例如,2月30日无效)
// 这里使用解析后的时间重新格式化为字符串,并与原始输入比较
formatted := t.Format("2006-01-02")
expected := fmt.Sprintf("%04d-%02d-%02d", year, month, day)
if formatted != expected {
return fmt.Errorf("birthdate does not exist: %s", p.Birthdate)
}
return nil
}
这段代码首先解析日期,然后检查年份、月份和日期的基本范围。最后,通过比较格式化后的日期与预期字符串,可以捕获像 "0000-00-00" 或 "2023-02-30" 这样的无效日期。调用此函数时,如果返回错误,则表示日期无效。

