Golang如何根据给定日期精确计算年龄?
Golang如何根据给定日期精确计算年龄? 如何创建一个函数,能够根据给定的出生日期精确计算到今天的年龄?我创建了以下函数,但该函数返回的年龄是错误的。例如:如果我提供 dateOfBirth := 08/15/1990 并尝试计算截至今天的年龄,它会返回 30 而不是 29。有人能帮我解决这个问题吗?
Age = math.Floor(Today.Now().Sub(*dateOfBirth).Hours() / 24 / 365)
如果我的生日是明天:(20200909-19820910)/10。
更多关于Golang如何根据给定日期精确计算年龄?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
1990年8月15日是出生日期,今天是2020年9月10日。
9月紧随8月之后,而2020减去1990等于30,30看起来确实是正确的结果。我不确定你为什么期望是29。
除此之外,一天并不总是24小时。它也可能是23或25小时(夏令时),甚至24小时加减1秒(闰秒)。同样,一年也不是365天,大约是365.23天。这就是为什么我们每4年在二月多出一天(每25次跳过,但第4次跳过不跳)……
如何根据给定日期计算截至今天的准确年龄?
我提供了出生日期
dateOfBirth := 08/15/1990,并尝试计算截至今天[09/09/2020]的年龄。
Age = math.Floor(Today.Now().Sub(*dateOfBirth).Hours() / 24 / 365)
存在闰年、时区,可能还有夏令时。你的年龄计算公式不正确。
这里是一个正确的年龄计算方法。
package main
import (
"fmt"
"time"
)
func age(birthdate, today time.Time) int {
today = today.In(birthdate.Location())
ty, tm, td := today.Date()
today = time.Date(ty, tm, td, 0, 0, 0, 0, time.UTC)
by, bm, bd := birthdate.Date()
birthdate = time.Date(by, bm, bd, 0, 0, 0, 0, time.UTC)
if today.Before(birthdate) {
return 0
}
age := ty - by
anniversary := birthdate.AddDate(age, 0, 0)
if anniversary.After(today) {
age--
}
return age
}
func main() {
layout := "01/02/2006"
birthdate, _ := time.Parse(layout, "08/15/1990")
for _, today := range []string{"09/09/2020", "08/15/2020", "08/14/2020", "08/15/1991", "08/14/1991"} {
today, _ := time.Parse(layout, today)
fmt.Println(age(birthdate, today), birthdate.Format(layout), today.Format(layout))
}
}
30 08/15/1990 09/09/2020
30 08/15/1990 08/15/2020
29 08/15/1990 08/14/2020
1 08/15/1990 08/15/1991
0 08/15/1990 08/14/1991
对于出生日期 08/15/1990,第一个生日在 08/15/1991,第十个生日在 08/15/2000,第三十个生日在 08/15/2020。在 09/09/2020 时,age 为 30。
根据你提供的代码,问题在于直接使用 Hours()/24/365 进行年龄计算,这种方法没有考虑闰年和月份天数差异,导致精度不足。以下是修正后的解决方案:
package main
import (
"fmt"
"time"
)
func CalculateAge(birthDate time.Time) int {
now := time.Now()
// 计算年份差异
years := now.Year() - birthDate.Year()
// 如果今年的生日还没到,年龄减1
if now.YearDay() < birthDate.YearDay() {
years--
}
return years
}
func main() {
// 示例:1990年8月15日出生
birthDate := time.Date(1990, 8, 15, 0, 0, 0, 0, time.UTC)
age := CalculateAge(birthDate)
fmt.Printf("精确年龄: %d岁\n", age)
}
如果需要更精确的年龄(包含月份和天数),可以使用以下扩展版本:
func CalculateExactAge(birthDate time.Time) (years, months, days int) {
now := time.Now()
// 计算年份
years = now.Year() - birthDate.Year()
// 计算月份
months = int(now.Month()) - int(birthDate.Month())
// 计算天数
days = now.Day() - birthDate.Day()
// 调整负数情况
if days < 0 {
// 获取上个月的天数
lastMonth := now.AddDate(0, -1, 0)
days += time.Date(lastMonth.Year(), lastMonth.Month()+1, 0, 0, 0, 0, 0, time.UTC).Day()
months--
}
if months < 0 {
months += 12
years--
}
return years, months, days
}
func main() {
birthDate := time.Date(1990, 8, 15, 0, 0, 0, 0, time.UTC)
years, months, days := CalculateExactAge(birthDate)
fmt.Printf("精确年龄: %d岁 %d个月 %d天\n", years, months, days)
}
对于你提到的 08/15/1990 格式的字符串输入,可以使用以下解析方式:
func ParseAndCalculateAge(dateStr string) (int, error) {
birthDate, err := time.Parse("01/02/2006", dateStr)
if err != nil {
return 0, err
}
return CalculateAge(birthDate), nil
}
func main() {
age, err := ParseAndCalculateAge("08/15/1990")
if err != nil {
fmt.Println("日期解析错误:", err)
return
}
fmt.Printf("年龄: %d岁\n", age)
}
这个解决方案正确处理了闰年和月份天数差异,能够返回精确的年龄计算结果。


