Skip to content

Commit

Permalink
[RFC][UN-13487] Fix diff in months (#43)
Browse files Browse the repository at this point in the history
* Fix diff in months counting months twice

* Add carbon php tests

* Fix logic all test suite passes

* Add negative date tests

* Refactor diff in months
  • Loading branch information
asantos00 authored and Hugo Correia committed Jun 25, 2018
1 parent ed4169d commit ac8e45a
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 31 deletions.
70 changes: 39 additions & 31 deletions carbon.go
Original file line number Diff line number Diff line change
Expand Up @@ -1181,46 +1181,54 @@ func (c *Carbon) DiffInMonths(carb *Carbon, abs bool) int64 {
return 0
}

diffHr := c.DiffInHours(carb, abs)
hrLastMonth := int64(c.DaysInMonth() * hoursPerDay)

if (diffHr - hrLastMonth) >= 0 {
var m int64
if c.Year() < carb.Year() {
m = (int64(monthsPerYear) - int64(c.In(time.UTC).Month())) + (int64(carb.In(time.UTC).Month()) - 1)
totalHr := int64(c.DaysInMonth() * hoursPerDay)
cHr := c.StartOfMonth().DiffInHours(c, abs)
remainHr := totalHr - cHr
spentInHr := carb.StartOfMonth().DiffInHours(carb, abs)
if (remainHr + spentInHr) >= totalHr {
m = m + 1
}
} else if c.Year() > carb.Year() {
m = (int64(monthsPerYear) - int64(carb.In(time.UTC).Month())) + (int64(c.In(time.UTC).Month()) - 1)
totalHr := int64(carb.DaysInMonth() * hoursPerDay)
carbHr := carb.StartOfMonth().DiffInHours(carb, abs)
remainHr := totalHr - carbHr
spentInHr := c.StartOfMonth().DiffInHours(c, abs)
if (remainHr + spentInHr) >= totalHr {
m = m + 1
}
} else {
m = int64(carb.In(time.UTC).Month() - c.In(time.UTC).Month())
if c.Month() != carb.Month() && c.Year() == carb.Year() {
diffInMonths := int64(carb.In(time.UTC).Month() - c.In(time.UTC).Month())
remainingTime := int(carb.DiffInHours(c, true))

if remainingTime < c.DaysInMonth()*hoursPerDay {
return 0
}

diffYr := c.Year() - carb.Year()
if math.Abs(float64(diffYr)) > 1 {
diff := c.DiffInYears(carb, abs)*monthsPerYear + m
return absValue(abs, diffInMonths)
}

m := monthsPerYear - c.In(time.UTC).Month() + carb.In(time.UTC).Month() - 1
if c.Year() < carb.Year() && c.hasRemainingHours(carb) {
m = m + 1
}

if c.Year() > carb.Year() {
m = monthsPerYear - carb.In(time.UTC).Month() + c.In(time.UTC).Month() - 1

return absValue(abs, diff)
if carb.hasRemainingHours(c) {
m = m + 1
}
}

diff := m
diffYr := c.Year() - carb.Year()
if math.Abs(float64(diffYr)) > 1 {
dateWithoutMonths := c.AddMonths(int(m))
diff := dateWithoutMonths.DiffInYears(carb, abs)*monthsPerYear + int64(m)

return absValue(abs, diff)
}

return 0
diff := int64(m)

if c.GreaterThan(carb) {
diff = -diff
}

return absValue(abs, diff)
}

func (c *Carbon) hasRemainingHours(carb *Carbon) bool {
totalHr := int64(c.DaysInMonth() * hoursPerDay)
cHr := c.StartOfMonth().DiffInHours(c, false)
remainHr := totalHr - cHr
spentInHr := carb.StartOfMonth().DiffInHours(carb, false)

return remainHr+spentInHr >= totalHr
}

// DiffDurationInString returns the duration difference in string format
Expand Down
70 changes: 70 additions & 0 deletions carbon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1993,6 +1993,76 @@ func TestDiffInMonthsSameMonth(t *testing.T) {
assert.EqualValues(t, 0, t1.DiffInMonths(t2, true))
}

func TestDiffInMonthsDifferentYears(t *testing.T) {
t1, _ := Create(2018, time.May, 1, 0, 0, 0, 0, "UTC")
t2, _ := Create(2020, time.June, 1, 0, 0, 0, 0, "UTC")

assert.EqualValues(t, 25, t1.DiffInMonths(t2, true))
}

func TestDiffInMonthsPositive(t *testing.T) {
t1, _ := Create(2018, time.January, 1, 0, 0, 0, 0, "UTC")
t2, _ := Create(2019, time.February, 1, 0, 0, 0, 0, "UTC")

assert.EqualValues(t, 13, t1.DiffInMonths(t2, true))
}

func TestDiffInMonthsNegativeWithSign(t *testing.T) {
t1, _ := Create(2018, time.January, 1, 0, 0, 0, 0, "UTC")
t2, _ := Create(2017, time.February, 1, 0, 0, 0, 0, "UTC")

assert.EqualValues(t, -11, t1.DiffInMonths(t2, false))
}

func TestDiffInMonthsNegativeWithSignOneHourLess(t *testing.T) {
t1, _ := Create(2018, time.January, 1, 0, 0, 0, 0, "UTC")
t2, _ := Create(2017, time.January, 1, 1, 0, 0, 0, "UTC")

assert.EqualValues(t, -11, t1.DiffInMonths(t2, false))
}

func TestDiffInMonthsNegativeWithSignWithMonthsLess(t *testing.T) {
t1, _ := Create(2018, time.January, 1, 0, 0, 0, 0, "UTC")
t2, _ := Create(2017, time.July, 1, 0, 0, 0, 0, "UTC")

assert.EqualValues(t, -6, t1.DiffInMonths(t2, false))
}

func TestDiffInMonthsNegativeWithSignWithOneMonthLess(t *testing.T) {
t1, _ := Create(2018, time.January, 1, 0, 0, 0, 0, "UTC")
t2, _ := Create(2017, time.December, 1, 0, 0, 0, 0, "UTC")

assert.EqualValues(t, -1, t1.DiffInMonths(t2, false))
}

func TestDiffInMonthsNegativeWithSignWithOneMonthAndOneHourLess(t *testing.T) {
t1, _ := Create(2018, time.January, 1, 0, 0, 0, 0, "UTC")
t2, _ := Create(2017, time.December, 1, 1, 0, 0, 0, "UTC")

assert.EqualValues(t, 0, t1.DiffInMonths(t2, false))
}

func TestDiffInMonthsNegativeWithFewDaysLeft(t *testing.T) {
t1, _ := Create(2018, time.January, 1, 0, 0, 0, 0, "UTC")
t2, _ := Create(2017, time.December, 20, 0, 0, 0, 0, "UTC")

assert.EqualValues(t, 0, t1.DiffInMonths(t2, false))
}

func TestDiffInMonthsNegativeNoSign(t *testing.T) {
t1, _ := Create(2018, time.January, 1, 0, 0, 0, 0, "UTC")
t2, _ := Create(2017, time.February, 1, 0, 0, 0, 0, "UTC")

assert.EqualValues(t, 11, t1.DiffInMonths(t2, true))
}

func TestDiffInMonthsEnsureIsTruncated(t *testing.T) {
t1, _ := Create(2018, time.January, 1, 0, 0, 0, 0, "UTC")
t2, _ := Create(2018, time.February, 17, 0, 0, 0, 0, "UTC")

assert.EqualValues(t, 1, t1.DiffInMonths(t2, true))
}

func TestDiffInString(t *testing.T) {
t1, _ := Create(2016, time.August, 10, 10, 0, 0, 0, "UTC")
t2, _ := Create(2016, time.August, 1, 23, 0, 0, 0, "UTC")
Expand Down

0 comments on commit ac8e45a

Please sign in to comment.