Go语言Fscanf解析短日期串未报错问题及正确解析方案咨询
问题解答
关于fmt.Fscanf的校验能力
fmt.Fscanf的%04d格式符仅用于指定输出时补零至4位,不会校验输入数字的位数。它会将输入的"24"当作十进制整数读取,再格式化为4位(前置补零),因此不会触发错误——这是它的设计特性,无法直接让它实现你想要的位数校验。
正确的解析方案
要严格校验日期字符串格式(年份必须4位、月份必须2位,中间以短横线分隔),可采用以下几种方法:
方法1:正则表达式校验
先通过正则匹配确认字符串符合^\d{4}-\d{2}$格式,再进行解析:
package main import ( "fmt" "regexp" "strconv" ) func main() { s := "24-02" pattern := `^\d{4}-\d{2}$` match, _ := regexp.MatchString(pattern, s) if !match { fmt.Println("日期格式错误:年份需为4位") return } yearStr, monthStr := s[:4], s[5:] year, _ := strconv.Atoi(yearStr) month, _ := strconv.Atoi(monthStr) fmt.Printf("%04d-%02d\n", year, month) }
方法2:使用time包解析
Go的time包支持严格格式匹配,用time.Parse指定"2006-01"(Go的参考时间格式),它会严格校验输入位数:
package main import ( "fmt" "time" ) func main() { s := "24-02" format := "2006-01" t, err := time.Parse(format, s) if err != nil { fmt.Println("日期格式错误:", err) return } fmt.Println(t.Format(format)) }
运行后会直接返回错误:parsing time "24-02" as "2006-01": cannot parse "24-02" as "2006",完全符合你的预期校验需求。
方法3:手动字符串长度检查
先判断字符串总长度是否为7("YYYY-MM"的标准长度),再拆分年份、月份部分检查各自长度:
package main import ( "fmt" "strconv" ) func main() { s := "24-02" if len(s) != 7 || s[4] != '-' { fmt.Println("日期格式错误:需为YYYY-MM格式") return } yearStr := s[:4] monthStr := s[5:] if len(yearStr) != 4 || len(monthStr) != 2 { fmt.Println("日期格式错误:年份需4位,月份需2位") return } year, err1 := strconv.Atoi(yearStr) month, err2 := strconv.Atoi(monthStr) if err1 != nil || err2 != nil || month < 1 || month > 12 { fmt.Println("日期数值错误") return } fmt.Printf("%04d-%02d\n", year, month) }
内容的提问来源于stack exchange,提问作者Anton Lahti
相关产品推荐
相关产品推荐

