Skip to content

Commit

Permalink
Optimize DiffInMonths method (#273)
Browse files Browse the repository at this point in the history
The original implementation for `DiffInMonths` method used a recursive
approach to calculate, which required a time complexity of O(n). By
switching to a mathematical calculation, the time complexity is reduced
to O(1).
  • Loading branch information
gouguoyin authored Dec 25, 2024
2 parents 882b656 + 5c7d6ee commit 9edc4c1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 10 deletions.
23 changes: 13 additions & 10 deletions difference.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down Expand Up @@ -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)
}
12 changes: 12 additions & 0 deletions difference_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 9edc4c1

Please sign in to comment.