golang 通过获取国务院的放假信息,解析法定节假日和法定补休日
func main() {
fjDays, sbDays, err :=GetDays()
fmt.Println(fjDays, sbDays, err)
}
// GetDays 获取国务院的放假通知消息,解析出对应的法定节假日和调休日
// fjDays 法定节假日,全部列表
// sbDays 法定补休日,全部列表
func GetDays() (fjDays, sbDays []string, errerror) {
var pUrl ="http://sousuo.gov.cn/s.htm?t=paper&advance=false&q=%E9%83%A8%E5%88%86%E8%8A%82%E5%81%87%E6%97%A5%E5%AE%89%E6%8E%92%E7%9A%84%E9%80%9A%E7%9F%A5"
bytes, err :=Get(pUrl, nil)
if err !=nil {
return nil, nil, err
}
result, err :=GetRegexpList(string(bytes), `<li class="res-list">(.*?)</li>`)
if err !=nil {
return nil, nil, err
}
if len(result) >0 {
// 拿第一个即可
var data =strings.TrimSpace(result[0][1])
if len(data) <=0 {
return nil, nil, errors.New("data result")
}
linkUrl, err :=GetRegexpItem(data, `a href="(.*?)"`)
if err !=nil {
fmt.Println("linkUrl=err==", err)
return nil, nil, err
}
bytes, err =Get(linkUrl, nil)
if err !=nil {
fmt.Println("bytes=err==", err)
return nil, nil, err
}
year, err :=GetRegexpItem(string(bytes), `国务院办公厅关于(.*?)年`)
if err !=nil {
fmt.Println("year=err==", err)
return nil, nil, err
}
content, err :=GetRegexpItem(string(bytes), `<div class="b12c pages_content".*?>(.*?)</div>`)
if err !=nil {
fmt.Println("content=err==", err)
return nil, nil, err
}
ll, err :=GetRegexpList(content, `</span>(.*?)</p>`)
if err !=nil {
return nil, nil, err
}
for _, c :=range ll {
if len(c[1]) >0 && !strings.Contains(c[1], "<") {
if strings.Contains(c[1], "。") {
var s =strings.Split(c[1], "。")
for _, str :=range s {
if len(str) >0 {
if strings.Contains(str, "放假") {
var t =strings.Split(str, "放假")[0]
if strings.Contains(t, "至") {
var st =strings.Split(t, "至")[0]
var et =strings.Split(t, "至")[1]
var y, m, d =GetDateTime(GetTimeFormat(year, "", st))
var ey, em, ed =GetDateTime(GetTimeFormat(year, m, et))
var times =GetDateRange(fmt.Sprintf("%s-%s-%s", y, m, d), fmt.Sprintf("%s-%s-%s", ey, em, ed))
fjDays =append(fjDays, times...)
}else {
var y, m, d =GetDateTime(GetTimeFormat(year, "", t))
fjDays =append(fjDays, fmt.Sprintf("%s-%s-%s", y, m, d))
}
}
if strings.Contains(str, "上班") {
if strings.Contains(str, "、") {
var ts =strings.Split(str, "、")
for _, t :=range ts {
if strings.Contains(t, "日") {
var ymd =strings.Split(t, "日")
var y, m, d =GetDateTime(GetTimeFormat(year, "", ymd[0]+"日"))
sbDays =append(sbDays, fmt.Sprintf("%s-%s-%s", y, m, d))
}
}
}
}
}
}
}
}
}
fmt.Println("fjDays===", fjDays)
fmt.Println("sbDays===", sbDays)
}
return
}
// GetTimeFormat 格式话时间
func GetTimeFormat(year, month, tstring)string {
if strings.Contains(t, "月") {
if !strings.Contains(t, "年") {
t =fmt.Sprintf("%s年%s", year, t)
}
}else {
t =fmt.Sprintf("%s月%s", month, t)
if !strings.Contains(t, "年") {
t =fmt.Sprintf("%s年%s", year, t)
}
}
return t
}
// GetDateTime 获取年月日
func GetDateTime(tstring) (year, month, daystring) {
// 2022年12月31日
var ymd =strings.Split(t, "年")
var y = ymd[0]//2022
var md = ymd[1]//12月31日
var m =strings.Split(md, "月")[0]
var d =strings.Split(strings.Split(md, "月")[1], "日")[0]
if len(m) ==1 {
m =fmt.Sprintf("0%s", m)
}
if len(d) ==1 {
d =fmt.Sprintf("0%s", d)
}
return y, m, d
}
// GetRegexpItem 匹配符合正则的1个结果
func GetRegexpItem(contentstring, regexpStrstring) (sstring, errerror) {
if len(regexpStr) <=0 {
return "", nil
}
// 处理回车换行
content =strings.Replace(content, "\r", "", len(content))
content =strings.Replace(content, "\n", "", len(content))
regexpStr =fmt.Sprintf("(?i)%s", regexpStr)
reg :=regexp.MustCompile(regexpStr)
cs := reg.FindStringSubmatch(content)
if len(cs) >1 {
// 去掉内容的前后空格
return strings.TrimSpace(cs[1]), nil
}
return "", errors.New(fmt.Sprintf("%s匹配错误,请检查网页", regexpStr))
}
// GetRegexpList 匹配符合正则的多个结果
func GetRegexpList(contentstring, regexpStrstring) (s [][]string, errerror) {
// 处理回车换行
content =strings.Replace(content, "\r", "", len(content))
content =strings.Replace(content, "\n", "", len(content))
regexpStr =fmt.Sprintf("(?i)%s", regexpStr)
reg :=regexp.MustCompile(regexpStr)
result := reg.FindAllStringSubmatch(content, -1)
if len(result) <=0 {
return nil, errors.New(fmt.Sprintf("%s匹配错误,请检查网页", regexpStr))
}
return result, nil
}
// Get 发起一个GET请求
func Get(urlstring, headersmap[string]string) (response []byte, errerror) {
client :=http.Client{Timeout:30 *time.Second}
req, err :=http.NewRequest("GET", url, nil)
if err !=nil {
return nil, err
}
if len(headers) >0 {
for key, val :=range headers {
req.Header.Set(key, val)
}
}
resp, err := client.Do(req)
if err !=nil {
return nil, err
}
defer resp.Body.Close()
var iint
TRY:
body, err :=io.ReadAll(resp.Body)
if err !=nil {
i++
if i <3 {
time.Sleep(time.Second)
goto TRY
}
return nil, err
}
return body, nil
}
// Post 发起一个Post请求
func Post(urlstring, datainterface{}, contentTypestring) (content []byte, errerror) {
jsonStr, _ :=json.Marshal(data)
req, err :=http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
if err !=nil {
return nil, err
}
req.Header.Add("content-type", contentType)
defer req.Body.Close()
client := &http.Client{Timeout:5 *time.Second}
resp, err := client.Do(req)
if err !=nil {
return nil, err
}
defer resp.Body.Close()
result, err :=io.ReadAll(resp.Body)
if err !=nil {
return nil, err
}
return result, nil
}
// IsWorkday 判断是否是工作日
// holiday 法定节假日日期列表["2023-04-29","2023-04-30","2023-05-01"...]
// workdays 法定补休日日期列表["2023-05-06"...]
func IsWorkday(holidays []string, workdays []string)bool {
var day =time.Now().Format("2006-01-02")
for _, s :=range workdays {
if s == day {
return true
}
}
for _, s :=range holidays {
if s == day {
return false
}
}
// 如果不在指定日期表中,则判断是否是周末
weekday :=time.Now().Weekday()
if weekday !=time.Saturday && weekday !=time.Sunday {
return true
}
return false
}
// GetDateRange 获取时间范围
func GetDateRange(start, endstring) []string {
startTime, _ :=time.Parse("2006-01-02", start)
endTime, _ :=time.Parse("2006-01-02", end)
var dates []string
for i :=0; i <=int(endTime.Sub(startTime).Hours()/24); i++ {
currentTime := startTime.AddDate(0, 0, i)
date := currentTime.Format("2006-01-02")
dates =append(dates, date)
}
return dates
}
以上发放即可获取2023年的,如果需要获取下一年的可以采用定时任务,或者手动在12月底,国务院放假通知出来后进行获取
fjDays=== [2022-12-31 2023-01-01 2023-01-02 2023-01-21 2023-01-22 2023-01-23 2023-01-24 2023-01-25 2023-01-26 2023-01-27 2023-04-05 2023-04-29 2023-04-30 2023-05-01 2023-05-02 2023-05-03 2023-06-22 2023-06-23 2023-06-24 2023-09-29 2023-09-30 2023-10-01 2023-10-02 2023-10-03 2023-10-04 2023-10-05 2023-10-06]
sbDays=== [2023-01-28 2023-01-29 2023-04-23 2023-05-06 2023-10-07 2023-10-08]