『本身構建節假日API』

RickAndMorty.png

你們好,我叫謝偉,是一名程序員。git

以前梳理了一些內置庫的學習,收到了一些評論,絕大多數評論都在直指一個問題:爲何梳理這些無關痛癢的內置庫?程序員

好吧,看上去確實都是些簡單的內置庫的梳理。主要緣由是爲了:《後端工程師的攻略》這個系列,從零起步,教程到這個地步,看上去是須要提升難度了。後續加以改善。另一個緣由,實際上是想告訴初學者,內置庫的不少代碼組織方式,代碼的編寫方式指的學習、借鑑、參考。github

這期是我以前準備的,趁着這期仍是放送出來吧。json

核心很簡單:懂 Go 的基本語法,會使用內置庫的 time, 基本能搞到這些。後端

大綱:bash

前段日子項目中須要使用的國家規定的節假日,因此須要獲取這些數據。其實獲取這些數據的方式也不少:app

  • 好比比較笨的方式:搜索引擎,手動整理
  • 使用一些免費開放的第三方節假日 API: 不穩定,雖然這些數據也不須要頻繁的使用
  • 使用一些付費的第三方節假日 API:付費

因而本着簡潔的方式,編寫這麼一個節假日的庫。工具

要求:學習

  • 簡單的功能
  • 簡單的API

1. 數據獲取

數據源須要可靠,因此須要尋找官方的通知來源。網站

好比:國務院辦公廳關於2018年部分節假日安排的通知

通常的方式呢,就是網頁數據抓取,解析出獲得的數據。

這是第一步,獲取數據;固然,不少網站均可以找到這些信息,這裏僅僅舉例。

2. 定義結構體

關於節假日,咱們最須要知道的是什麼信息?

  • 名稱
  • 時間安排

基於此,能夠這麼設計結構體:

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",
}
複製代碼

中英文,獲取指定偏移量上的數據便可,這種處理方式在內置庫很常見:好比時間類型的時間基本單位月:一月、二月、三月等

3. 歷史數據

基於上文的分析,要構建這個簡單的庫,要組織歷史節假日,這邊選取 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,
		},
	}
}

複製代碼

4. 構建API

  • 選擇好的命名方式
  • 選擇好的數據返回格式
- 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(year int): 從歷史數據中獲取
// 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]

}
複製代碼
  • FetchByMonth: 從某年的歷史數據中獲取
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
}
複製代碼
  • IsHoliday: 歷史數據中是否能擊中目標
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: 不是節假日、也不是工做日的
// IsWeekDay: judge date is week day or not
func IsWeekDay(value string) bool {
	return !IsWorkDay(value) && !IsHoliday(value)
}
複製代碼

<後記>

基於上文的理念,其實能夠寫不少小工具:

好比:

  • 獲取古詩詞
  • 給定一個日期,判斷星座
  • 給定一個身份證,判斷是否有效,屬於哪一個地區等
  • 給定一個ip, 給出地理位置
  • 給定一箇中文,給出英文或者拼音
  • 給定文字,解釋其中文含義 ...

<完>

相關文章
相關標籤/搜索