From 5c7d6eee07f30ec7c035b7656f2f8001f06ce462 Mon Sep 17 00:00:00 2001 From: ritbrz Date: Wed, 25 Dec 2024 20:35:24 +0800 Subject: [PATCH] Optimize DiffInMonths method --- difference.go | 23 +++++++++++++---------- difference_unit_test.go | 12 ++++++++++++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/difference.go b/difference.go index 2247fabc..609ccb76 100755 --- a/difference.go +++ b/difference.go @@ -56,7 +56,7 @@ func (c Carbon) DiffInMonths(carbon ...Carbon) int64 { start, end = end, start sign = -1 } - months := getDiffInMonths(start, end, 0) + months := getDiffInMonths(start, end) return months * int64(sign) } @@ -280,13 +280,16 @@ func (c Carbon) diff(end Carbon) (unit string, value int64) { return } -func getDiffInMonths(start, end Carbon, months int64) int64 { - next := start.AddDays(start.DaysInMonth()) - days := next.DiffInDays(end) - seconds := next.DiffInSeconds(end) - if days < 0 || (days == 0 && seconds < 0) { - return months - } - months++ - return getDiffInMonths(next, end, months) +func getDiffInMonths(start, end Carbon) int64 { + y, m, d, h, i, s, ns := start.DateTimeNano() + endYear, endMonth, _ := end.Date() + + yearDiff := endYear - y + monthDiff := endMonth - m + totalMonths := yearDiff*12 + monthDiff + + if time.Date(y, time.Month(m+totalMonths), d, h, i, s, ns, start.StdTime().Location()).After(end.StdTime()) { + return int64(totalMonths - 1) + } + return int64(totalMonths) } diff --git a/difference_unit_test.go b/difference_unit_test.go index e624e76e..477c2d5e 100755 --- a/difference_unit_test.go +++ b/difference_unit_test.go @@ -1116,6 +1116,18 @@ func TestCarbon_Issue255(t *testing.T) { end: Parse("2020-08-05 13:14:15"), want: 23, }, + { + name: "case11", + start: Parse("1024-12-25 13:14:20"), + end: Parse("2024-12-25 13:14:20"), + want: 12000, + }, + { + name: "case12", + start: Parse("1024-12-25 13:14:20"), + end: Parse("2024-12-25 13:14:19"), + want: 11999, + }, } for _, tt := range tests {