go语言学习实例---生成指定年份和月份的日历

go语言学习实例—生成指定年份和月份的日历

go语言学习实例---生成指定年份和月份的日历_第1张图片

这是用Go语言编写的与之前文章Java代码功能相同的日历程序。

package main
//这是Go语言程序的起始语句,是一个特殊的包声明,指定了程序所属的包。每个程序通常都属于一个包,用于组织相关的代码和功能。表示这个文件是一个可执行程序而不是一个库。
import (
	"fmt"
)
//这是导入fmt包,提供了格式化输入输出的功能,用于在控制台上输出文本和数据。
func main() { //定义了一个名为main的函数,这是Go程序的入口函数。程序从这里开始执行。
	var year, month int   //声明了两个变量year和month,它们的类型都是整数int。这些变量将用于存储年份和月份的值。
	fmt.Println("请输入年份:") //输出提示信息,请求用户输入年份。
	fmt.Scanln(&year) //使用fmt.Scanln函数从用户输入中读取年份的值,并将其存储到变量year中。Scanln函数会等待用户输入一个整数,并将其解析并存储到指定的变量中。
	fmt.Println("请输入月份:") //输出提示信息,请求用户输入月份。
	fmt.Scanln(&month)//使用fmt.Scanln函数从用户输入中读取月份的值,并将其存储到变量month中。Scanln函数会等待用户输入一个整数,并将其解析并存储到指定的变量中。
	if year < 1 || month < 1 || month > 12 {
		fmt.Println("无效的年份或月份")
		return
	}
	printCalendar(year, month)//调用名为printCalendar的函数,传递年份和月份作为参数。这个函数将用于打印日历。
}
//这是程序的主函数,它首先声明了两个整型变量year和month,
//然后使用fmt包中的Println函数向用户提示输入年份和月份,
//并使用fmt包中的Scanln函数读取用户的输入。
//最后,调用printCalendar函数打印日历。
func printCalendar(year, month int) {//定义了一个名为printCalendar的函数,它接受两个整数参数,分别表示年份和月份。
	days := make([]int, 42)// 创建一个长度为42的整数切片days。切片是Go语言中的动态数组,可以用于存储一系列整数。
	day := 1 //初始化一个变量day,将其赋值为 1。`day`将用于迭代日期。 
	dayOfWeek := getDayOfWeek(year, month, 1)  //调用名为getDayOfWeek的函数,传递年份、月份和日期(初始化为 1)作为参数。这个函数将返回对应的星期几的值。
	maxDay := getMaxDayOfMonth(year, month) //调用名为getMaxDayOfMonth的函数,传递年份和月份作为参数。这个函数将返回该月的最大天数。
	for i := 0; i < maxDay; i++ {  //使用一个循环,从0开始迭代到`maxDay`减 1 的范围。循环体将执行多次,每次迭代对应一天。
		days[i+dayOfWeek] = day // 在循环体内,将当前日期`day`存储到切片`days`的指定索引位置。索引是通过计算星期几和循环迭代次数得到的。
		day++ //在每次循环迭代后,将日期变量`day`加 1,以便在下一次迭代中处理下一天的日期。
	}
	fmt.Println("      Sun Mon Tue Wed Thu Fri Sat") //输出一周七天的头部标题,用于对齐日期。
	fmt.Println("      === === === === === === ===") //输出一条分隔线,用于分隔不同星期的日期。
	index := 0  // 初始化一个变量index,将其赋值为 0。index将用于迭代切片中的日期。
	for i := 1; i <= 6; i++ {   //使用另一个循环,从1开始迭代到6的范围。循环体将执行多次,每次迭代对应一周中的一天。
		fmt.Print(i, "   ") //- `fmt.Print(i, "   ")`:在循环体内,输出当前迭代的索引(表示星期几),并在后面添加三个空格。
		for j := 0; j < 7; j++ { // 使用嵌套的循环,从0开始迭代到6的范围。循环体将执行多次,每次迭代对应一周中的一个位置。
			if index < len(days) && days[index] != 0 { //在循环体内,检查当前索引是否小于切片的长度,并且对应的日期值不为0。这是为了确保在输出日期时不越界。
				fmt.Printf("%4d", days[index]) //如果条件满足,输出当前日期的值,使用格式化字符串`%4d`来指定输出格式为四位数的日期。
			} else {  
				fmt.Print("    ")
			}
			index++   //在每次循环迭代后,将索引变量`index`加 1,以便在下一次迭代中处理下一个日期。
		}
		fmt.Println()  //循环结束后,输出一个换行符,以便将不同星期的日期分隔开。
	}
}
//这是一个打印日历的函数。
//它首先创建了一个长度为42的整型切片days,用于存储每个月份中的日期。
//然后,使用getDayOfWeek函数获取给定年份和月份的第一天是星期几,
//并使用getMaxDayOfMonth函数获取给定年份和月份的最大天数。
//接下来,使用两个循环填充days切片。
//第一个循环从1到最大天数,将日期依次放入正确的位置。第二个循环打印日历的表头以及日期。
func getDayOfWeek(year, month, day int) int {  //定义了一个名为getDayOfWeek的函数,它接受三个整数参数,分别表示年份、月份和日期。
	if month < 3 {  //检查月份是否小于 3。这是为了处理月份在 1 月或 2 月的情况。
		month += 12  //如果月份小于 3,将其加上 12,以便将日期转换为对应的星座月份。
		year--  //同时,将年份减 1,以调整到正确的年份。
	}
	century := year / 100  //计算年份的世纪部分,即将年份除以 100。
	year %= 100 //将年份的余数保留下来,用于后续计算。
	week := (day + 2*month + 3*(month+1)/5 + year + year/4 - year/100 + year/400 + century/4 - 2*century) % 7  //用于确定给定日期对应的星期几。它考虑了月份、日期、年份和世纪的各种组合和调整。
	return (week + 6) % 7  //最后,将计算得到的星期几加上6,然后再对7取余数,以将结果调整为0到6的范围,对应星期日到星期六。
}
//这是一个计算给定日期是星期几的函数。它使用了蔡勒公式(Zeller's Congruence)来计算星期几。该公式根据年份、月份和日期计算出一个数字,表示星期几(0代表星期日,1代表星期一,以此类推)。
func getMaxDayOfMonth(year, month int) int {   //定义了一个名为`getMaxDayOfMonth`的函数,它接受两个整数参数,分别表示年份和月份。
	if month == 2 {  //检查月份是否为 2。
		if (year%4 == 0 && year%100 != 0) || year%400 == 0 {   //条件判断,用于确定是否为闰年。如果年份能被4整除但不能被100整除,或者能被400整除,那么就是闰年。
			return 29   //在闰年的情况下,2月份的最大天数为29。
		} else {  //否则,如果不是闰年。
			return 28   //2月份的最大天数为28。
		}
	} else if month == 4 || month == 6 || month == 9 || month == 11 {   //检查其他月份是否为4、6、9 或11。
		return 30   //这些月份的最大天数为30。
	} else {  //否则,如果不是上述月份。
		return 31  //其他月份的最大天数为31。
	}
}

你可能感兴趣的:(golang,学习,go)