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)
			}
		}
	}
}

结果

go计算”三天打鱼两天晒网“_第1张图片

进阶篇

难点解决

基本方法中计算总天数的方式理解简单,但是过于冗长。进阶中利用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))
			}
		}
	}
}

结果

go计算”三天打鱼两天晒网“_第2张图片

你可能感兴趣的:(go编程)