go計算”三天打魚兩天曬網“

題目

”GO王國“在1990年1月1日發佈了”三天打魚兩天曬網“計劃,那麼請編寫一段代碼,輸入年月日,計算輸入日期是“打魚日”還是“曬網日”。

基本方法

解決思路

1.計算輸入時間到1990年1月1日共過了多少天(難點)
2.”三天打魚兩天曬網“,則是5天爲1個週期,那麼將總天數5取餘,1、2、3爲”打魚日“,其他爲”曬網日“

難點解決

  1. 計算從輸入的年份到1990年過了多少年,平年365,閏年366,一直累加到前一年。
  2. 計算從輸入的月份到1月過了多少月,平年2月28,閏年2月29,一直累加到前一個月。
  3. 將輸入的天數加上,則得出的爲到1990年1月1日的總天數

代碼

package main
import (
	"fmt"
)
//從1990年1月1日起開始發佈“三天打魚兩天曬網”,那麼輸入年月日,計算當前時間是”打魚日“還是”曬網日“
//判斷是否是閏年,並且返回相應年的總天數
func isYear(year int) int {
	if (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 {
		return 366
	}
	return 365
}
//計算輸入的日期到1990年1月1日共多少天
func subDay(year, month, day int) int {
	count := 0
	//計算年份差多少天
	for i := 1990; i < year; i++ {
		 count += isYear(year)
	}
	//計算月份差多少天
	for i := 1; i < month; i++ {
		switch month {
			case 1, 3, 5, 7, 8, 10, 12:
				count += 31
			case 2:
				if (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 {
					if day > 29 {
						fmt.Println("天數輸入錯誤!")
						return -1
					}
					count += 29
				}else {
					if day > 28 {
						fmt.Println("天數輸入錯誤!")
						return -1
					}
					count += 28
				}
			default: 
				if day > 30 {
					fmt.Println("天數輸入錯誤!")
					return -1
				}
				count += 30
		}
	}
	count += day
	return count
}
func main() {
	var year, month, day int
	for {
		fmt.Printf("請輸入年份: ")
		fmt.Scanln(&year)
		if year < 1990 {
			fmt.Printf("年份輸入錯誤!%v年還沒有發佈此計劃\n", year)
			continue
		}
		fmt.Printf("請輸入月份: ")
		fmt.Scanln(&month)
		if month < 1 || month > 12 {
			fmt.Println("月份輸入錯誤!")
			continue
		}
		fmt.Printf("請輸入天數: ")
		fmt.Scanln(&day)
		if day < 1 || day > 31 {
			fmt.Println("天數輸入錯誤!")
			continue
		}
		days := subDay(year, month, day)
		if days == -1 {
			continue
		}
		switch days % 5 {
			case 1, 2, 3:
				fmt.Printf("%v年%v月%v日是打魚日\n", year, month, day)
			default: {
				fmt.Printf("%v年%v月%v日是曬網日\n", year, month, day)
			}
		}
	}
}

結果

在這裏插入圖片描述

進階篇

難點解決

基本方法中計算總天數的方式理解簡單,但是過於冗長。進階中利用time包中相關函數方法直接將輸入時間和計劃發出時間(1990-01-01)進行運算,得出總天數

相關函數

  1. func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time
    輸入相關參數,年月日時分秒納秒時區。結果返回time.Time類型時間。注意:month需要輸入time.Month格式,即英文月份,如果要輸入數字可以通過轉換,如:time.Month(1)。
  2. time.Sub().Hours()
    time.Sub()計算兩個時間差,將結果再利用time.Hours轉換成小時單位
  3. time.Format()
    時間格式轉換,需要將模版傳入其中。模版爲:2006 01 02 15 04 05 數字值不能改變,但是格式隨意。例如:希望輸出結果爲年月日,則模版爲2006年01月02日

代碼

package main
import (
	"fmt"
	"time"
)
func main() {
	var year, month, day int
	//定義時間格式化模版,2006 01 02 15 04 05 是go誕生時間,數字不能變		     
	//經過Format格式化後的時間就是以模版以基礎的時間格式
	tempPlite := "2006年01月02日"
	for {
		fmt.Printf("請輸入年份: ")
		fmt.Scanln(&year)
		if year < 1990 {
			fmt.Printf("年份輸入錯誤!%v年還沒有發佈此計劃\n", year)
			continue
		}
		fmt.Printf("請輸入月份: ")
		fmt.Scanln(&month)
		//不允許輸入負數和0,即使能代入正確運算。防止出現1990年以前的日期
		if month < 1 {
			fmt.Printf("月份輸入錯誤\n")
			continue
		}
		fmt.Printf("請輸入天數: ")
		fmt.Scanln(&day)
		//輸入的日期轉換成time.Time格式
		//time.Date()默認會將輸入的“不正確的”日期轉換成正確日期,例如:輸入1990-13-1
		//實際返回結果是1991-1-1
		curDay := time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.Local)
		//計劃發佈時間1990-01-01轉換成time.Time格式
		tempDay := time.Date(1990, 1, 1, 0, 0, 0, 0, time.Local)
		//利用time.Sub().Hours()計算兩個時間差轉成小時,float64類型。計算總天數。
		//+1是將當天算上。例如1990-01-01距離1990-01-01總天數是1天,而不能算是0天
		days := int(((curDay.Sub(tempDay)).Hours()) / 24+ 1)
		switch days % 5 {
			case 1, 2, 3:
			//time.Format()函數依據傳入的模版格式,輸出時間格式。現在時間格式爲*年*月*日
				fmt.Printf("%v是打魚日\n", curDay.Format(tempPlite))
			default: {
				fmt.Printf("%v是曬網日\n", curDay.Format(tempPlite))
			}
		}
	}
}

結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章