你们好,我叫谢伟,是一名程序员。git
以前梳理了一些内置库的学习,收到了一些评论,绝大多数评论都在直指一个问题:为何梳理这些无关痛痒的内置库?程序员
好吧,看上去确实都是些简单的内置库的梳理。主要缘由是为了:《后端工程师的攻略》这个系列,从零起步,教程到这个地步,看上去是须要提升难度了。后续加以改善。另一个缘由,实际上是想告诉初学者,内置库的不少代码组织方式,代码的编写方式指的学习、借鉴、参考。github
这期是我以前准备的,趁着这期仍是放送出来吧。json
核心很简单:懂 Go 的基本语法,会使用内置库的 time, 基本能搞到这些。后端
大纲:bash
前段日子项目中须要使用的国家规定的节假日,因此须要获取这些数据。其实获取这些数据的方式也不少:app
因而本着简洁的方式,编写这么一个节假日的库。工具
要求:学习
数据源须要可靠,因此须要寻找官方的通知来源。网站
通常的方式呢,就是网页数据抓取,解析出获得的数据。
这是第一步,获取数据;固然,不少网站均可以找到这些信息,这里仅仅举例。
关于节假日,咱们最须要知道的是什么信息?
基于此,能够这么设计结构体:
type OneCollection struct {
Start string `json:"start"`
End string `json:"end"`
ChName string `json:"ch_name"`
EnName string `json:"en_name"`
}
复制代码
包括:
关于节假日名称呢,国家法定的节日是这么几个:元旦、春节、清明、端午、劳动、中秋、国庆
借鉴许多内置库的处理方式:这种固定的数据的处理,可使用枚举类型:
const (
NewYearDay = iota
SpringFestivalDay
TombSweepingDay
LaborDay
DragonBoatFestivalDay
NationalDay
MidAutumnFestivalDay
)
var ChHolidays = [...]string{
"元旦",
"春节",
"清明节",
"劳动节",
"端午节",
"中秋节",
"国庆节",
}
var EnHolidays = [...]string{
"New Year\\'s Day",
"Spring Festival",
"Tomb-sweeping Day",
"Labour Day",
"Dragon Boat Festival",
"Mid-autumn Festival",
"National Day",
}
复制代码
中英文,获取指定偏移量上的数据便可,这种处理方式在内置库很常见:好比时间类型的时间基本单位月:一月、二月、三月等
基于上文的分析,要构建这个简单的库,要组织历史节假日,这边选取 2010年到 2019 年的数据。
// 一年
type YearCollection struct {
Data []OneCollection `json:"data"`
}
// n 年
type CollectionYearHistory struct {
Data [][]OneCollection `json:"data"`
}
// 2010 年到 2019年历史数据
func FetchCollectionYearHistory() CollectionYearHistory {
return CollectionYearHistory{
Data: [][]OneCollection{
holiday2019,
holiday2018,
holiday2017,
holiday2016,
holiday2015,
holiday2014,
holiday2013,
holiday2012,
holiday2011,
holiday2010,
},
}
}
复制代码
- FetchAll
- FetchByChName(year int, name string)
- FetchByEnName(year int, name string)
- FetchByMonth(year int, month int)
- FetchByYear(year int)
- FetchMonthHolidayCount(year int, month int)
- FetchYearHolidayCount(year int)
- IsHoliday
- IsWeekDay
- IsWorkDay
复制代码
之因此这样设计, 是由于项目中常常会是这样的操做:
基于这些需求,构建了上文的API
以几个API 为例,详细的操做如何实现?
// FetchByYear get holidays by year in china
func FetchByYear(year int) []history.OneCollection {
var index int
nowYear, _, _ := time.Now().Date()
if year > nowYear+1 {
return nil
}
index = nowYear + 1 - year
return history.FetchCollectionYearHistory().Data[index]
}
复制代码
func FetchByMonth(year int, month int) []history.OneCollection {
if month < 1 || month > 12 {
return nil
}
collections := FetchByYear(year)
var data []history.OneCollection
for _, collection := range collections {
collectionTime, _ := time.Parse("2006/01/02", collection.End)
if int(collectionTime.Month()) == month {
data = append(data, collection)
}
}
return data
}
复制代码
func IsHoliday(value string) bool {
collectionTime, err := time.Parse("2006/01/02", value)
if err != nil {
return false
}
nowYear, _, _ := time.Now().Date()
if collectionTime.Year() > nowYear+1 {
return false
}
collections := FetchByYear(collectionTime.Year())
for _, collection := range collections {
startDate, _ := getDate(collection.Start)
endDate, _ := getDate(collection.End)
if collectionTime.Unix() >= startDate.Unix() && collectionTime.Unix() <= endDate.Unix() {
return true
}
}
return false
}
复制代码
// IsWeekDay: judge date is week day or not
func IsWeekDay(value string) bool {
return !IsWorkDay(value) && !IsHoliday(value)
}
复制代码
<后记>
基于上文的理念,其实能够写不少小工具:
好比:
<完>