You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:18:14