2021-02-18 14:32:31 +08:00
|
|
|
|
package carbon
|
|
|
|
|
|
2021-07-31 13:27:17 +08:00
|
|
|
|
import (
|
2022-10-27 00:37:43 +08:00
|
|
|
|
"math"
|
2021-07-31 13:27:17 +08:00
|
|
|
|
"strings"
|
2024-02-20 11:08:21 +08:00
|
|
|
|
"time"
|
2021-07-31 13:27:17 +08:00
|
|
|
|
)
|
2021-02-18 14:32:31 +08:00
|
|
|
|
|
2024-03-08 15:10:56 +08:00
|
|
|
|
const (
|
|
|
|
|
minDuration time.Duration = -1 << 63
|
|
|
|
|
maxDuration time.Duration = 1<<63 - 1
|
|
|
|
|
)
|
|
|
|
|
|
2021-08-10 10:57:22 +08:00
|
|
|
|
// DiffInYears gets the difference in years.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少年
|
2021-07-23 10:57:18 +08:00
|
|
|
|
func (c Carbon) DiffInYears(carbon ...Carbon) int64 {
|
2022-10-27 00:37:43 +08:00
|
|
|
|
start, end := c, c.Now()
|
2023-12-27 11:14:52 +08:00
|
|
|
|
if c.IsSetTestNow() {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
2021-07-31 13:27:17 +08:00
|
|
|
|
if len(carbon) > 0 {
|
2023-11-30 15:06:56 +08:00
|
|
|
|
end = carbon[0]
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
2023-09-06 23:10:35 +08:00
|
|
|
|
dy, dm, dd := end.Year()-start.Year(), end.Month()-start.Month(), end.Day()-start.Day()
|
2023-10-09 09:47:53 +08:00
|
|
|
|
if dm < 0 || (dm == 0 && dd < 0) {
|
2023-09-06 23:10:35 +08:00
|
|
|
|
dy--
|
|
|
|
|
}
|
|
|
|
|
if dy < 0 && (dd != 0 || dm != 0) {
|
|
|
|
|
dy++
|
|
|
|
|
}
|
|
|
|
|
return int64(dy)
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-17 19:52:02 +08:00
|
|
|
|
// DiffAbsInYears gets the difference in years with absolute value.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少年(绝对值)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
func (c Carbon) DiffAbsInYears(carbon ...Carbon) int64 {
|
2022-10-27 00:37:43 +08:00
|
|
|
|
return getAbsValue(c.DiffInYears(carbon...))
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-10 10:57:22 +08:00
|
|
|
|
// DiffInMonths gets the difference in months.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少月
|
2021-07-23 10:57:18 +08:00
|
|
|
|
func (c Carbon) DiffInMonths(carbon ...Carbon) int64 {
|
2024-11-25 03:50:39 +08:00
|
|
|
|
start, end := c, c.Now()
|
2024-11-24 23:48:04 +08:00
|
|
|
|
if start.IsSetTestNow() {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
2021-07-31 13:27:17 +08:00
|
|
|
|
if len(carbon) > 0 {
|
2023-11-30 15:06:56 +08:00
|
|
|
|
end = carbon[0]
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
2024-11-25 03:43:30 +08:00
|
|
|
|
if start.Month() == end.Month() && start.Year() == end.Year() {
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
dd := start.DiffInDays(end)
|
2024-11-25 03:48:27 +08:00
|
|
|
|
sign := 1
|
2024-11-25 03:43:30 +08:00
|
|
|
|
if dd <= 0 {
|
|
|
|
|
start, end = end, start
|
2024-11-25 03:48:27 +08:00
|
|
|
|
sign = -1
|
2024-11-25 03:43:30 +08:00
|
|
|
|
}
|
|
|
|
|
months := getDiffInMonths(start, end, 0)
|
2024-11-25 03:48:27 +08:00
|
|
|
|
return months * int64(sign)
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-17 19:52:02 +08:00
|
|
|
|
// DiffAbsInMonths gets the difference in months with absolute value.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少月(绝对值)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
func (c Carbon) DiffAbsInMonths(carbon ...Carbon) int64 {
|
2022-10-27 00:37:43 +08:00
|
|
|
|
return getAbsValue(c.DiffInMonths(carbon...))
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-10 10:57:22 +08:00
|
|
|
|
// DiffInWeeks gets the difference in weeks.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少周
|
2021-07-23 10:57:18 +08:00
|
|
|
|
func (c Carbon) DiffInWeeks(carbon ...Carbon) int64 {
|
2022-10-27 00:37:43 +08:00
|
|
|
|
start, end := c, c.Now()
|
2023-12-27 11:14:52 +08:00
|
|
|
|
if c.IsSetTestNow() {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
2021-07-31 13:27:17 +08:00
|
|
|
|
if len(carbon) > 0 {
|
2023-11-30 15:06:56 +08:00
|
|
|
|
end = carbon[0]
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
2022-10-27 00:37:43 +08:00
|
|
|
|
return int64(math.Floor(float64((end.Timestamp() - start.Timestamp()) / (7 * 24 * 3600))))
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-17 19:52:02 +08:00
|
|
|
|
// DiffAbsInWeeks gets the difference in weeks with absolute value.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少周(绝对值)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
func (c Carbon) DiffAbsInWeeks(carbon ...Carbon) int64 {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
return getAbsValue(c.DiffInWeeks(carbon...))
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-10 10:57:22 +08:00
|
|
|
|
// DiffInDays gets the difference in days.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少天
|
2021-07-23 10:57:18 +08:00
|
|
|
|
func (c Carbon) DiffInDays(carbon ...Carbon) int64 {
|
2022-10-27 00:37:43 +08:00
|
|
|
|
start, end := c, c.Now()
|
2023-12-27 11:14:52 +08:00
|
|
|
|
if c.IsSetTestNow() {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
2021-07-31 13:27:17 +08:00
|
|
|
|
if len(carbon) > 0 {
|
2023-11-30 15:06:56 +08:00
|
|
|
|
end = carbon[0]
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
2022-10-27 00:37:43 +08:00
|
|
|
|
return int64(math.Floor(float64((end.Timestamp() - start.Timestamp()) / (24 * 3600))))
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-17 19:52:02 +08:00
|
|
|
|
// DiffAbsInDays gets the difference in days with absolute value.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少天(绝对值)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
func (c Carbon) DiffAbsInDays(carbon ...Carbon) int64 {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
return getAbsValue(c.DiffInDays(carbon...))
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-10 10:57:22 +08:00
|
|
|
|
// DiffInHours gets the difference in hours.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少小时
|
2021-07-23 10:57:18 +08:00
|
|
|
|
func (c Carbon) DiffInHours(carbon ...Carbon) int64 {
|
2021-02-18 14:32:31 +08:00
|
|
|
|
end := c.Now()
|
2023-12-27 11:14:52 +08:00
|
|
|
|
if c.IsSetTestNow() {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
2021-07-31 13:27:17 +08:00
|
|
|
|
if len(carbon) > 0 {
|
2023-11-30 15:06:56 +08:00
|
|
|
|
end = carbon[0]
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
return c.DiffInSeconds(end) / SecondsPerHour
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-17 19:52:02 +08:00
|
|
|
|
// DiffAbsInHours gets the difference in hours with absolute value.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少小时(绝对值)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
func (c Carbon) DiffAbsInHours(carbon ...Carbon) int64 {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
return getAbsValue(c.DiffInHours(carbon...))
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-10 10:57:22 +08:00
|
|
|
|
// DiffInMinutes gets the difference in minutes.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少分钟
|
2021-07-23 10:57:18 +08:00
|
|
|
|
func (c Carbon) DiffInMinutes(carbon ...Carbon) int64 {
|
2021-02-18 14:32:31 +08:00
|
|
|
|
end := c.Now()
|
2023-12-27 11:14:52 +08:00
|
|
|
|
if c.IsSetTestNow() {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
2021-07-31 13:27:17 +08:00
|
|
|
|
if len(carbon) > 0 {
|
2023-11-30 15:06:56 +08:00
|
|
|
|
end = carbon[0]
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
return c.DiffInSeconds(end) / SecondsPerMinute
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-17 19:52:02 +08:00
|
|
|
|
// DiffAbsInMinutes gets the difference in minutes with absolute value.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少分钟(绝对值)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
func (c Carbon) DiffAbsInMinutes(carbon ...Carbon) int64 {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
return getAbsValue(c.DiffInMinutes(carbon...))
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-10 10:57:22 +08:00
|
|
|
|
// DiffInSeconds gets the difference in seconds.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少秒
|
2021-07-23 10:57:18 +08:00
|
|
|
|
func (c Carbon) DiffInSeconds(carbon ...Carbon) int64 {
|
2021-02-18 14:32:31 +08:00
|
|
|
|
end := c.Now()
|
2023-12-27 11:14:52 +08:00
|
|
|
|
if c.IsSetTestNow() {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
2021-07-31 13:27:17 +08:00
|
|
|
|
if len(carbon) > 0 {
|
2023-11-30 15:06:56 +08:00
|
|
|
|
end = carbon[0]
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
2021-09-06 11:07:45 +08:00
|
|
|
|
return end.Timestamp() - c.Timestamp()
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-04-17 19:52:02 +08:00
|
|
|
|
// DiffAbsInSeconds gets the difference in seconds with absolute value.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 相差多少秒(绝对值)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
func (c Carbon) DiffAbsInSeconds(carbon ...Carbon) int64 {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
return getAbsValue(c.DiffInSeconds(carbon...))
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-09-06 11:07:45 +08:00
|
|
|
|
// DiffInString gets the difference in string, i18n is supported.
|
|
|
|
|
// 相差字符串,支持i18n
|
|
|
|
|
func (c Carbon) DiffInString(carbon ...Carbon) string {
|
|
|
|
|
end := c.Now()
|
2023-12-27 11:14:52 +08:00
|
|
|
|
if c.IsSetTestNow() {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
2021-09-06 11:07:45 +08:00
|
|
|
|
if len(carbon) > 0 {
|
2023-11-30 15:06:56 +08:00
|
|
|
|
end = carbon[0]
|
2021-09-06 11:07:45 +08:00
|
|
|
|
}
|
|
|
|
|
if c.Error != nil || end.Error != nil {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
unit, value := c.diff(end)
|
|
|
|
|
return c.lang.translate(unit, value)
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-17 19:52:02 +08:00
|
|
|
|
// DiffAbsInString gets the difference in string with absolute value, i18n is supported.
|
2021-09-15 21:05:21 +08:00
|
|
|
|
// 相差字符串,支持i18n(绝对值)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
func (c Carbon) DiffAbsInString(carbon ...Carbon) string {
|
2021-09-06 11:07:45 +08:00
|
|
|
|
end := c.Now()
|
2023-12-27 11:14:52 +08:00
|
|
|
|
if c.IsSetTestNow() {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
2021-09-06 11:07:45 +08:00
|
|
|
|
if len(carbon) > 0 {
|
2023-11-30 15:06:56 +08:00
|
|
|
|
end = carbon[0]
|
2021-09-06 11:07:45 +08:00
|
|
|
|
}
|
|
|
|
|
if c.Error != nil || end.Error != nil {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
unit, value := c.diff(end)
|
|
|
|
|
return c.lang.translate(unit, getAbsValue(value))
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 11:08:21 +08:00
|
|
|
|
// DiffInDuration gets the difference in duration.
|
|
|
|
|
// 相差时长
|
|
|
|
|
func (c Carbon) DiffInDuration(carbon ...Carbon) time.Duration {
|
|
|
|
|
end := c.Now()
|
|
|
|
|
if c.IsSetTestNow() {
|
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
|
|
|
|
if len(carbon) > 0 {
|
|
|
|
|
end = carbon[0]
|
|
|
|
|
}
|
|
|
|
|
return end.StdTime().Sub(c.StdTime())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DiffAbsInDuration gets the difference in duration with absolute value.
|
|
|
|
|
// 相差时长(绝对值)
|
|
|
|
|
func (c Carbon) DiffAbsInDuration(carbon ...Carbon) time.Duration {
|
2024-03-08 15:10:56 +08:00
|
|
|
|
d := c.DiffInDuration(carbon...)
|
|
|
|
|
if d >= 0 {
|
|
|
|
|
return d
|
2024-02-20 11:08:21 +08:00
|
|
|
|
}
|
2024-03-08 15:10:56 +08:00
|
|
|
|
return -d
|
2024-02-20 11:08:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-09-16 09:52:35 +08:00
|
|
|
|
// DiffForHumans gets the difference in a human-readable format, i18n is supported.
|
2021-07-28 15:18:05 +08:00
|
|
|
|
// 获取对人类友好的可读格式时间差,支持i18n
|
2021-07-23 10:57:18 +08:00
|
|
|
|
func (c Carbon) DiffForHumans(carbon ...Carbon) string {
|
2021-02-18 14:32:31 +08:00
|
|
|
|
end := c.Now()
|
2023-12-27 11:14:52 +08:00
|
|
|
|
if c.IsSetTestNow() {
|
2023-10-16 14:06:45 +08:00
|
|
|
|
end = CreateFromTimestampNano(c.testNow, c.Location())
|
|
|
|
|
}
|
2021-07-31 13:27:17 +08:00
|
|
|
|
if len(carbon) > 0 {
|
2023-11-30 15:06:56 +08:00
|
|
|
|
end = carbon[0]
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
2021-09-06 11:07:45 +08:00
|
|
|
|
if c.Error != nil || end.Error != nil {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
unit, value := c.diff(end)
|
|
|
|
|
translation := c.lang.translate(unit, getAbsValue(value))
|
|
|
|
|
if unit == "now" {
|
|
|
|
|
return translation
|
|
|
|
|
}
|
|
|
|
|
if c.Lt(end) && len(carbon) == 0 {
|
|
|
|
|
return strings.Replace(c.lang.resources["ago"], "%s", translation, 1)
|
|
|
|
|
}
|
|
|
|
|
if c.Lt(end) && len(carbon) > 0 {
|
|
|
|
|
return strings.Replace(c.lang.resources["before"], "%s", translation, 1)
|
|
|
|
|
}
|
|
|
|
|
if c.Gt(end) && len(carbon) == 0 {
|
|
|
|
|
return strings.Replace(c.lang.resources["from_now"], "%s", translation, 1)
|
|
|
|
|
}
|
|
|
|
|
return strings.Replace(c.lang.resources["after"], "%s", translation, 1)
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-24 07:03:55 +08:00
|
|
|
|
// gets the difference for unit and value.
|
2021-09-06 11:07:45 +08:00
|
|
|
|
// 获取相差单位和差值
|
|
|
|
|
func (c Carbon) diff(end Carbon) (unit string, value int64) {
|
2021-02-18 14:32:31 +08:00
|
|
|
|
switch true {
|
2022-04-17 19:52:02 +08:00
|
|
|
|
case c.DiffAbsInYears(end) > 0:
|
2021-02-18 14:32:31 +08:00
|
|
|
|
unit = "year"
|
2021-09-06 11:07:45 +08:00
|
|
|
|
value = c.DiffInYears(end)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
case c.DiffAbsInMonths(end) > 0:
|
2021-02-18 14:32:31 +08:00
|
|
|
|
unit = "month"
|
2021-09-06 11:07:45 +08:00
|
|
|
|
value = c.DiffInMonths(end)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
case c.DiffAbsInWeeks(end) > 0:
|
2021-02-18 14:32:31 +08:00
|
|
|
|
unit = "week"
|
2021-09-06 11:07:45 +08:00
|
|
|
|
value = c.DiffInWeeks(end)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
case c.DiffAbsInDays(end) > 0:
|
2021-02-18 14:32:31 +08:00
|
|
|
|
unit = "day"
|
2021-09-06 11:07:45 +08:00
|
|
|
|
value = c.DiffInDays(end)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
case c.DiffAbsInHours(end) > 0:
|
2021-02-18 14:32:31 +08:00
|
|
|
|
unit = "hour"
|
2021-09-06 11:07:45 +08:00
|
|
|
|
value = c.DiffInHours(end)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
case c.DiffAbsInMinutes(end) > 0:
|
2021-02-18 14:32:31 +08:00
|
|
|
|
unit = "minute"
|
2021-09-06 11:07:45 +08:00
|
|
|
|
value = c.DiffInMinutes(end)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
case c.DiffAbsInSeconds(end) > 0:
|
2021-02-18 14:32:31 +08:00
|
|
|
|
unit = "second"
|
2021-09-06 11:07:45 +08:00
|
|
|
|
value = c.DiffInSeconds(end)
|
2022-04-17 19:52:02 +08:00
|
|
|
|
case c.DiffAbsInSeconds(end) == 0:
|
2021-02-18 14:32:31 +08:00
|
|
|
|
unit = "now"
|
2021-09-06 11:07:45 +08:00
|
|
|
|
value = 0
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
2021-09-06 11:07:45 +08:00
|
|
|
|
return
|
2021-02-18 14:32:31 +08:00
|
|
|
|
}
|
2024-11-24 23:48:04 +08:00
|
|
|
|
|
2024-11-25 03:43:30 +08:00
|
|
|
|
func getDiffInMonths(start, end Carbon, months int64) int64 {
|
|
|
|
|
next := start.AddDays(start.DaysInMonth())
|
|
|
|
|
days := next.DiffInDays(end)
|
|
|
|
|
seconds := next.DiffInSeconds(end)
|
2024-11-25 03:55:14 +08:00
|
|
|
|
if days < 0 || (days == 0 && seconds < 0) {
|
2024-11-24 23:48:04 +08:00
|
|
|
|
return months
|
|
|
|
|
}
|
|
|
|
|
months += 1
|
2024-11-25 03:43:30 +08:00
|
|
|
|
return getDiffInMonths(next, end, months)
|
2024-11-24 23:48:04 +08:00
|
|
|
|
}
|