1
0
mirror of https://github.com/duke-git/lancet.git synced 2026-03-01 00:35:28 +08:00

feat: add AddDaySafe, AddMonthSafe, AddYearSafe

This commit is contained in:
dudaodong
2025-02-18 15:37:56 +08:00
parent a09f5623d6
commit 4181c42805
5 changed files with 293 additions and 61 deletions
+49 -49
View File
@@ -1,51 +1,51 @@
-----BEGIN rsa private key----- -----BEGIN rsa private key-----
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
-----END rsa private key----- -----END rsa private key-----
+12 -12
View File
@@ -1,14 +1,14 @@
-----BEGIN rsa public key----- -----BEGIN rsa public key-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5bsUtFZmae/9D6ncFO62 MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAydCMlSbzx3yb6o3T/CUp
EaaGxoc0+/ZXqi2OtHZYpaDV0/bLV0gegTIQ5+kUJr0VQ/9GMEnALdGNBT9bJ0Mv fxRHSl45LjyqhEQiMHkGPcL9d81NlxVHvvy/V/mY5wtarYRlifsk2OOVJ2LyfagX
7VWZijYoyUOQ4fB4k8vaytFcug/kMYkvE+pvXg6JMbp9rZXXiz5djabAKv9ZrClU KM5k16LEEq2PsPcKVM4Vp6gLCIB2aX88hfJkYfTRGW2RX9aVCJaK1Ak2nXInuNEG
ugnK8KPtn+6SnCC4oKVhMRj2G+5LAxYhiidSrnK8xkgts4OwLTzqWw9N2QMvdkXj 9T/ykelH57gHjH2k9NuDBifcIm3fIKNKYqK4WvDQMob8KyKJdiKPsKll4Z5ZKGt/
wwaIG5UeDqeal0/hna402j6/QbANq/brR2eXHfxVrX9eMKBdA6OmVPeFUVb+JR/p gqpMt0gWx1fZ/njUnGATUoXMH7/JXdPQH+VVYt5HFq8JqffkiiIW0zzdNmA0dSGx
2TvNEEXRM/DmPP70HXg08L1XIjvaZm7MNbcqS+6AUciwWNshm8o4vFkyjN1E3U5s c96i8dCNdIB79iQAJ/X0c5fk5/8b/fkLUHY/BvBMhFtLp7/TCnbzn5Rmp8IJtWKe
yYptCEtDYA/+GPFzbzCzSyaTxBpdxSI6wB9Vt+Hk/DzS3RBoxj4xYk2LmPDX6i86 xaQ00AqzRNGnd4LoJAiPWAipfsUeYXW517lBllKz9wiKo7AmkB0h8fig5ZEK5btS
skBTQ9X3sUdWUoelyAko8JW+sXlXMQP05yNyBY+fayzhHfYYsi+4jpV4uLMY7bXe BqNRgdnMjBxrm/QFgWdqsxmzcjrXD3iV+ZNOE8s47jkdhjoPRpqqyMSUawmJs1uy
ySffROdiEQ9xXCf3trq2isKReHhYhmu7mnjIn+CcJZ909XzMJmN6zEeSTeXZMDqP SrVpgaldIJrBzNOATReHFQ+mSlHi7D1BcrOegCHasIqaQKv+w9ttR1P6bFcVezO/
K1dv3Yom6n/oRpR+rfx8JYCKTFR/+QYPGR1kc+LUyqgFcWwTexf3CfL3ck0H0iG7 OQaTbdQviB+pHqYv7Ww9kVPko1c+X5SMUUXy0MwwjLRl2TcEA0BzUf3Qdq5TA7x2
ivGV6wm9xvpOxbQb+4/79jQLtoBC8goU9KXuxYEs2aE4/LM8zY4QpHDIZYLoHnz2 Q4Eak2oBsuuEZrCPSTDRXjwUxd+Cz82SZMKg6fDe409dPR0S8w1xp4gdknvoQIyN
xSgm+rlh6E4p0t5mik3wOAUCAwEAAQ== pNrY6I6/UyDieOAImOLSrMECAwEAAQ==
-----END rsa public key----- -----END rsa public key-----
+55
View File
@@ -100,6 +100,61 @@ func AddYear(t time.Time, year int64) time.Time {
return t.AddDate(int(year), 0, 0) return t.AddDate(int(year), 0, 0)
} }
// AddDaySafe add or sub days to the time and ensure that the returned date does not exceed the valid date of the target year and month.
// Play: todo
func AddDaySafe(t time.Time, days int) time.Time {
t = t.AddDate(0, 0, days)
year, month, day := t.Date()
lastDayOfMonth := time.Date(year, month+1, 0, 0, 0, 0, 0, t.Location()).Day()
if day > lastDayOfMonth {
t = time.Date(year, month, lastDayOfMonth, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location())
}
return t
}
// AddMonthSafe add or sub months to the time and ensure that the returned date does not exceed the valid date of the target year and month.
// Play: todo
func AddMonthSafe(t time.Time, months int) time.Time {
year := t.Year()
month := int(t.Month()) + months
for month > 12 {
month -= 12
year++
}
for month < 1 {
month += 12
year--
}
daysInMonth := time.Date(year, time.Month(month+1), 0, 0, 0, 0, 0, time.UTC).Day()
day := t.Day()
if day > daysInMonth {
day = daysInMonth
}
return time.Date(year, time.Month(month), day, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location())
}
// AddYearSafe add or sub years to the time and ensure that the returned date does not exceed the valid date of the target year and month.
// Play: todo
func AddYearSafe(t time.Time, years int) time.Time {
year, month, day := t.Date()
year += years
if month == time.February && day == 29 {
if !IsLeapYear(year) {
day = 28
}
}
return time.Date(year, month, day, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location())
}
// GetNowDate return format yyyy-mm-dd of current date. // GetNowDate return format yyyy-mm-dd of current date.
// Play: https://go.dev/play/p/PvfkPpcpBBf // Play: https://go.dev/play/p/PvfkPpcpBBf
func GetNowDate() string { func GetNowDate() string {
+54
View File
@@ -90,6 +90,60 @@ func ExampleAddYear() {
// 2019-01-01 // 2019-01-01
} }
func ExampleAddDaySafe() {
leapYearDate1, _ := time.Parse("2006-01-02", "2024-02-29")
result1 := AddDaySafe(leapYearDate1, 1)
leapYearDate2, _ := time.Parse("2006-01-02", "2024-03-01")
result2 := AddDaySafe(leapYearDate2, -1)
nonLeapYearDate1, _ := time.Parse("2006-01-02", "2025-02-28")
result3 := AddDaySafe(nonLeapYearDate1, 1)
nonLeaYearDate2, _ := time.Parse("2006-01-02", "2025-03-01")
result4 := AddDaySafe(nonLeaYearDate2, -1)
fmt.Println(result1.Format("2006-01-02"))
fmt.Println(result2.Format("2006-01-02"))
fmt.Println(result3.Format("2006-01-02"))
fmt.Println(result4.Format("2006-01-02"))
// Output:
// 2024-03-01
// 2024-02-29
// 2025-03-01
// 2025-02-28
}
func ExampleAddMonthSafe() {
date1, _ := time.Parse("2006-01-02", "2025-01-31")
result1 := AddMonthSafe(date1, 1)
date2, _ := time.Parse("2006-01-02", "2024-02-29")
result2 := AddMonthSafe(date2, -1)
fmt.Println(result1.Format("2006-01-02"))
fmt.Println(result2.Format("2006-01-02"))
// Output:
// 2025-02-28
// 2024-01-29
}
func ExampleAddYearSafe() {
date, _ := time.Parse("2006-01-02", "2020-02-29")
result1 := AddYearSafe(date, 1)
result2 := AddYearSafe(date, -1)
fmt.Println(result1.Format("2006-01-02"))
fmt.Println(result2.Format("2006-01-02"))
// Output:
// 2021-02-28
// 2019-02-28
}
func ExampleGetNowDate() { func ExampleGetNowDate() {
result := GetNowDate() result := GetNowDate()
+123
View File
@@ -309,6 +309,129 @@ func TestAddMonth(t *testing.T) {
} }
func TestAddDaySafe(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestAddDaySafe")
tests := []struct {
inputDate string
days int
expected string
}{
{"2025-01-31", 10, "2025-02-10"},
{"2025-01-01", 30, "2025-01-31"},
{"2025-01-31", 1, "2025-02-01"},
{"2025-02-28", 1, "2025-03-01"},
{"2024-02-29", 1, "2024-03-01"},
{"2024-02-29", 365, "2025-02-28"},
{"2025-01-31", -10, "2025-01-21"},
{"2025-01-01", -30, "2024-12-02"},
{"2025-02-01", -1, "2025-01-31"},
{"2025-03-01", -1, "2025-02-28"},
{"2024-03-01", -1, "2024-02-29"},
{"2025-01-31", -31, "2024-12-31"},
{"2025-12-31", 1, "2026-01-01"},
}
for _, tt := range tests {
date, _ := time.Parse("2006-01-02", tt.inputDate)
result := AddDaySafe(date, tt.days)
assert.Equal(tt.expected, result.Format("2006-01-02"))
}
}
func TestAddMonthSafe(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestAddMonthSafe")
tests := []struct {
inputDate string
months int
expected string
}{
{
inputDate: "2025-01-31",
months: 1,
expected: "2025-02-28",
},
{
inputDate: "2025-01-31",
months: -1,
expected: "2024-12-31",
},
{
inputDate: "2025-12-31",
months: 1,
expected: "2026-01-31",
},
{
inputDate: "2025-01-31",
months: -1,
expected: "2024-12-31",
},
{
inputDate: "2024-02-29",
months: 1,
expected: "2024-03-29",
},
{
inputDate: "2024-02-29",
months: -1,
expected: "2024-01-29",
},
}
for _, tt := range tests {
date, _ := time.Parse("2006-01-02", tt.inputDate)
result := AddMonthSafe(date, tt.months)
assert.Equal(tt.expected, result.Format("2006-01-02"))
}
}
func TestAddYearSafe(t *testing.T) {
t.Parallel()
assert := internal.NewAssert(t, "TestAddYearSafe")
tests := []struct {
inputDate string
years int
expected string
}{
{
inputDate: "2020-02-29",
years: 1,
expected: "2021-02-28",
},
{
inputDate: "2020-02-29",
years: 2,
expected: "2022-02-28",
},
{
inputDate: "2020-02-29",
years: -1,
expected: "2019-02-28",
},
{
inputDate: "2020-02-29",
years: -2,
expected: "2018-02-28",
},
}
for _, tt := range tests {
date, _ := time.Parse("2006-01-02", tt.inputDate)
result := AddYearSafe(date, tt.years)
assert.Equal(tt.expected, result.Format("2006-01-02"))
}
}
func TestGetNowDate(t *testing.T) { func TestGetNowDate(t *testing.T) {
t.Parallel() t.Parallel()