diff --git a/README.en.md b/README.en.md index 3f81f48..0b678ff 100755 --- a/README.en.md +++ b/README.en.md @@ -1,7 +1,7 @@ # Carbon English | [Chinese](./README.md) -#### Description +#### Introduction A simple,semantic and developer-friendly golang package for datetime If you think it is helpful, please give me a star @@ -47,7 +47,7 @@ carbon.Now().ToTimestampWithMillisecond() // 1596604455000 carbon.Now().ToTimestampWithMicrosecond() // 1596604455000000 // Timestamp with nanosecond of today carbon.Now().ToTimestampWithNanosecond() // 1596604455000000000 -// Datetime of today in other timezone +// Datetime of today in specific timezone carbon.SetTimezone(Carbon.NewYork).Now().ToDateTimeString() // 2020-08-05 01:14:15 // Datetime of yesterday @@ -65,9 +65,9 @@ carbon.Yesterday().ToTimestampWithMillisecond() // 1596518055000 carbon.Yesterday().ToTimestampWithMicrosecond() // 1596518055000000 // Timestamp with nanosecond of yesterday carbon.Yesterday().ToTimestampWithNanosecond() // 1596518055000000000 -// Datetime of yesterday in other timezone +// Datetime of yesterday in specific timezone carbon.SetTimezone(Carbon.NewYork).Yesterday().ToDateTimeString() // 2020-08-04 01:14:15 -// Datetime of yesterday in other day +// Datetime of yesterday in specific day carbon.Parse("2021-01-28 13:14:15").Yesterday().ToDateTimeString() // 2021-01-27 13:14:15 // Datetime of tomorrow @@ -85,9 +85,9 @@ carbon.Tomorrow().ToTimestampWithMillisecond() // 1596690855000 carbon.Tomorrow().ToTimestampWithMicrosecond() // 1596690855000000 // Timestamp with nanosecond of tomorrow carbon.Tomorrow().ToTimestampWithNanosecond() // 1596690855000000000 -// Datetime of tomorrow in other timezone +// Datetime of tomorrow in specific timezone carbon.SetTimezone(Carbon.NewYork).Tomorrow().ToDateTimeString() // 2020-08-06 01:14:15 -// Datetime of tomorrow in other day +// Datetime of tomorrow in specific day carbon.Parse("2021-01-28 13:14:15").Tomorrow().ToDateTimeString() // 2021-01-29 13:14:15 ``` @@ -110,7 +110,7 @@ carbon.CreateFromDate(2020, 8, 5).ToDateTimeString() // 2020-08-05 13:14:15 carbon.CreateFromTime(13, 14, 15).ToDateTimeString() // 2020-08-05 13:14:15 ``` -##### Parse standard time format string +##### Parse standard string ```go carbon.Parse("").ToDateTimeString() // empty string carbon.Parse("0000-00-00 00:00:00").ToDateTimeString() // empty string @@ -144,43 +144,6 @@ carbon.Time2Carbon(time.Now()) carbon.Now().Carbon2Time() or carbon.Now().Time ``` -##### Time setter -```go -// Set timezone -carbon.SetTimezone(carbon.PRC).Now().ToDateTimeString() // 2020-08-05 13:14:15 -carbon.SetTimezone(carbon.Tokyo).Now().ToDateTimeString() // 2020-08-05 14:14:15 -carbon.SetTimezone(carbon.Tokyo).SetTimezone(carbon.PRC).Now().ToDateTimeString() // 2020-08-05 13:14:15 - -// Set locale -carbon.Parse("2020-07-05 13:14:15").SetLocale("en").DiffForHumans()) // 1 month before -carbon.Parse("2020-07-05 13:14:15").SetLocale("zh-CN").DiffForHumans()) // 1 月前 - -// Set year -carbon.Parse("2019-08-05").SetYear(2020).ToDateString() // 2020-08-05 -carbon.Parse("2020-02-29").SetYear(2019).ToDateString() // 2019-03-01 - -// Set month -carbon.Parse("2020-01-31").SetMonth(2).ToDateString() // 2020-03-02 -carbon.Parse("2020-08-05").SetMonth(2).ToDateString() // 2020-02-05 - -// Set day -carbon.Parse("2019-08-05").SetDay(31).ToDateString() // 2020-08-31 -carbon.Parse("2020-02-01").SetDay(31).ToDateString() // 2020-03-02 - -// Set hour -carbon.Parse("2020-08-05 13:14:15").SetHour(10).ToDateTimeString() // 2020-08-05 10:14:15 -carbon.Parse("2020-08-05 13:14:15").SetHour(24).ToDateTimeString() // 2020-08-06 00:14:15 - -// Set minute -carbon.Parse("2020-08-05 13:14:15").SetMinute(10).ToDateTimeString() // 2020-08-05 13:10:15 -carbon.Parse("2020-08-05 13:14:15").SetMinute(60).ToDateTimeString() // 2020-08-05 14:00:15 - -// Set second -carbon.Parse("2020-08-05 13:14:15").SetSecond(10).ToDateTimeString() // 2020-08-05 13:14:10 -carbon.Parse("2020-08-05 13:14:15").SetSecond(60).ToDateTimeString() // 2020-08-05 13:15:00 -``` -> For more timezone constants, please see the [constant.go](./constant.go) file - ##### Start and end ```go // Start of the year @@ -212,9 +175,14 @@ carbon.Parse("2020-08-05 13:14:15").EndOfHour().ToDateTimeString() // 2020-08-05 carbon.Parse("2020-08-05 13:14:15").StartOfMinute().ToDateTimeString() // 2020-08-05 13:14:00 // End of the minute carbon.Parse("2020-08-05 13:14:15").EndOfMinute().ToDateTimeString() // 2020-08-05 13:14:59 + +// Start of the second +carbon.Parse("2020-08-05 13:14:15").StartOfSecond().Format("Y-m-d H:i:s.u") // 2020-08-05 13:14:15.0 +// End of the second +carbon.Parse("2020-08-05 13:14:15").EndOfSecond().Format("Y-m-d H:i:s.u") // 2020-08-05 13:14:15.999 ``` -##### Time travel +##### Addition and Subtraction ```go // Add three centuries carbon.Parse("2020-02-29 13:14:15").AddCenturies(3).ToDateTimeString() // 2320-02-29 13:14:15 @@ -362,7 +330,7 @@ carbon.Parse("2020-08-05 13:14:15").SubDuration("2.5s").ToDateTimeString() // 20 carbon.Parse("2020-08-05 13:14:15").SubSecond().ToDateTimeString() // 2020-08-05 13:14:14 ``` -##### Difference in time +##### Difference ```go // Difference in weeks carbon.Parse("2020-08-05 13:14:15").DiffInWeeks(carbon.Parse("2020-07-28 13:14:15")) // -1 @@ -389,75 +357,20 @@ carbon.Parse("2020-08-05 13:14:15").DiffInSeconds(carbon.Parse("2020-08-05 13:14 // Difference in seconds with absolute value carbon.Parse("2020-08-05 13:14:15").DiffInSecondsWithAbs(carbon.Parse("2020-08-05 13:14:14")) // 1 -// Difference for humans in English -carbon.Now().DiffForHumans()) // just now -carbon.Now().SubYears(1).DiffForHumans() // 1 years ago -carbon.Now().SubYears(2).DiffForHumans() // 2 year ago -carbon.Now().AddYears(1).DiffForHumans() // in 1 year -carbon.Now().AddYears(2).DiffForHumans() // in 2 years -// Difference for humans in Chinese -carbon.Now().SetLocale("zh-CN").DiffForHumans() // 刚刚 -carbon.Now().SubMonths(1).SetLocale("zh-CN").DiffForHumans() // 1 月前 -carbon.Now().AddMonths(2).SetLocale("zh-CN").DiffForHumans() // 2 月后 +// Difference for humans +carbon.Parse("2020-08-05 13:14:15").DiffForHumans()) // just now +carbon.Parse("2019-08-05 13:14:15").DiffForHumans() // 1 year ago +carbon.Parse("2018-08-05 13:14:15").DiffForHumans() // 2 years ago +carbon.Parse("2021-08-05 13:14:15").DiffForHumans() // 1 year from now +carbon.Parse("2022-08-05 13:14:15").DiffForHumans() // 2 years from now + +carbon.Parse("2020-08-05 13:14:15").DiffForHumans(carbon.Now()) // 1 year before +carbon.Parse("2019-08-05 13:14:15").DiffForHumans(carbon.Now()) // 2 years before +carbon.Parse("2018-08-05 13:14:15").DiffForHumans(carbon.Now()) // 1 year after +carbon.Parse("2022-08-05 13:14:15").DiffForHumans(carbon.Now()) // 2 years after ``` -##### Time compare -```go -// greater than -carbon.Parse("2020-08-05 13:14:15").Gt(carbon.Parse("2020-08-04 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Gt(carbon.Parse("2020-08-05 13:14:15")) // false -carbon.Parse("2020-08-05 13:14:15").Compare(">", carbon.Parse("2020-08-04 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare(">", carbon.Parse("2020-08-05 13:14:15")) // false - -// less than -carbon.Parse("2020-08-05 13:14:15").Lt(carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Lt(carbon.Parse("2020-08-05 13:14:15")) // false -carbon.Parse("2020-08-05 13:14:15").Compare("<", carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare("<", carbon.Parse("2020-08-05 13:14:15")) // false - -// equal -carbon.Parse("2020-08-05 13:14:15").Eq(carbon.Parse("2020-08-05 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Eq(carbon.Parse("2020-08-05 13:14:00")) // false -carbon.Parse("2020-08-05 13:14:15").Compare("=", carbon.Parse("2020-08-05 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare("=", carbon.Parse("2020-08-05 13:14:00")) // false - -// not equal -carbon.Parse("2020-08-05 13:14:15").Ne(carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Ne(carbon.Parse("2020-08-05 13:14:15")) // false -carbon.Parse("2020-08-05 13:14:15").Compare("!=", carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare("<>", carbon.Parse("2020-08-05 13:14:15")) // false - -// greater than or equal -carbon.Parse("2020-08-05 13:14:15").Gte(carbon.Parse("2020-08-04 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Gte(carbon.Parse("2020-08-05 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare(">=", carbon.Parse("2020-08-04 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare(">=", carbon.Parse("2020-08-05 13:14:15")) // true - -// less than or equal -carbon.Parse("2020-08-05 13:14:15").Lte(carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Lte(carbon.Parse("2020-08-05 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare("<=", carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare("<=", carbon.Parse("2020-08-05 13:14:15")) // true - -// between -carbon.Parse("2020-08-05 13:14:15").Between(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // false -carbon.Parse("2020-08-05 13:14:15").Between(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true - -// Between included start time -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedStartTime(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedStartTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true - -// Between included end time -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedEndTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-05 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedEndTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true - -// Between included both -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedBoth(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedBoth(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-05 13:14:15")) // true - -``` - -##### Time judgment +##### Comparison ```go // Is zero time carbon.Parse("").IsZero() // true @@ -536,9 +449,61 @@ carbon.Parse("2020-08-05").IsToday() // true carbon.Parse("2020-08-06 13:14:15").IsTomorrow() // true carbon.Parse("2020-08-06 00:00:00").IsTomorrow() // true carbon.Parse("2020-08-06").IsTomorrow() // true + +// Greater than +carbon.Parse("2020-08-05 13:14:15").Gt(carbon.Parse("2020-08-04 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Gt(carbon.Parse("2020-08-05 13:14:15")) // false +carbon.Parse("2020-08-05 13:14:15").Compare(">", carbon.Parse("2020-08-04 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare(">", carbon.Parse("2020-08-05 13:14:15")) // false + +// Less than +carbon.Parse("2020-08-05 13:14:15").Lt(carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Lt(carbon.Parse("2020-08-05 13:14:15")) // false +carbon.Parse("2020-08-05 13:14:15").Compare("<", carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare("<", carbon.Parse("2020-08-05 13:14:15")) // false + +// Equal +carbon.Parse("2020-08-05 13:14:15").Eq(carbon.Parse("2020-08-05 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Eq(carbon.Parse("2020-08-05 13:14:00")) // false +carbon.Parse("2020-08-05 13:14:15").Compare("=", carbon.Parse("2020-08-05 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare("=", carbon.Parse("2020-08-05 13:14:00")) // false + +// Not equal +carbon.Parse("2020-08-05 13:14:15").Ne(carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Ne(carbon.Parse("2020-08-05 13:14:15")) // false +carbon.Parse("2020-08-05 13:14:15").Compare("!=", carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare("<>", carbon.Parse("2020-08-05 13:14:15")) // false + +// Greater than or equal +carbon.Parse("2020-08-05 13:14:15").Gte(carbon.Parse("2020-08-04 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Gte(carbon.Parse("2020-08-05 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare(">=", carbon.Parse("2020-08-04 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare(">=", carbon.Parse("2020-08-05 13:14:15")) // true + +// Less than or equal +carbon.Parse("2020-08-05 13:14:15").Lte(carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Lte(carbon.Parse("2020-08-05 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare("<=", carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare("<=", carbon.Parse("2020-08-05 13:14:15")) // true + +// Between +carbon.Parse("2020-08-05 13:14:15").Between(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // false +carbon.Parse("2020-08-05 13:14:15").Between(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true + +// Between included start time +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedStartTime(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedStartTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true + +// Between included end time +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedEndTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-05 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedEndTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true + +// Between included both +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedBoth(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedBoth(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-05 13:14:15")) // true ``` -##### Time output +##### Output ```go // To timestamp with second carbon.Parse("2020-08-05 13:14:15").ToTimestamp() // 1596604455 @@ -595,7 +560,7 @@ carbon.Parse("2020-08-05 13:14:15").ToRfc7231String() // Wed, 05 Aug 2020 05:14: // To string carbon.Parse("2020-08-05 13:14:15").Time.String() // 2020-08-05 13:14:15 +0800 CST -// To string of layout format,ToFormatString() abbreviated as Format() +// To string of layout format,Format() is short of ToFormatString() carbon.Parse("2020-08-05 13:14:15").ToFormatString("YmdHis") // 20200805131415 carbon.Parse("2020-08-05 13:14:15").ToFormatString("Y年m月d H时i分s秒") // 2020年08月05日 13时14分15秒 carbon.Parse("2020-08-05 13:14:15").Format("YmdHis") // 20200805131415 @@ -603,7 +568,43 @@ carbon.Parse("2020-08-05 13:14:15").Format("l jS \\o\\f F Y h:i:s A") // Wednesd ``` > For more format signs, please see the Format sign table -##### Time getter +##### Setter +```go +// Set timezone +carbon.SetTimezone(carbon.PRC).Now().ToDateTimeString() // 2020-08-05 13:14:15 +carbon.SetTimezone(carbon.Tokyo).Now().ToDateTimeString() // 2020-08-05 14:14:15 +carbon.SetTimezone(carbon.Tokyo).SetTimezone(carbon.PRC).Now().ToDateTimeString() // 2020-08-05 13:14:15 + +// Set locale +carbon.Parse("2020-07-05 13:14:15").SetLocale("en").DiffForHumans()) // 1 month before +carbon.Parse("2020-07-05 13:14:15").SetLocale("zh-CN").DiffForHumans()) // 1 月前 + +// Set year +carbon.Parse("2019-08-05").SetYear(2020).ToDateString() // 2020-08-05 +carbon.Parse("2020-02-29").SetYear(2019).ToDateString() // 2019-03-01 + +// Set month +carbon.Parse("2020-01-31").SetMonth(2).ToDateString() // 2020-03-02 +carbon.Parse("2020-08-05").SetMonth(2).ToDateString() // 2020-02-05 + +// Set day +carbon.Parse("2019-08-05").SetDay(31).ToDateString() // 2020-08-31 +carbon.Parse("2020-02-01").SetDay(31).ToDateString() // 2020-03-02 + +// Set hour +carbon.Parse("2020-08-05 13:14:15").SetHour(10).ToDateTimeString() // 2020-08-05 10:14:15 +carbon.Parse("2020-08-05 13:14:15").SetHour(24).ToDateTimeString() // 2020-08-06 00:14:15 + +// Set minute +carbon.Parse("2020-08-05 13:14:15").SetMinute(10).ToDateTimeString() // 2020-08-05 13:10:15 +carbon.Parse("2020-08-05 13:14:15").SetMinute(60).ToDateTimeString() // 2020-08-05 14:00:15 + +// Set second +carbon.Parse("2020-08-05 13:14:15").SetSecond(10).ToDateTimeString() // 2020-08-05 13:14:10 +carbon.Parse("2020-08-05 13:14:15").SetSecond(60).ToDateTimeString() // 2020-08-05 13:15:00 +``` + +##### Getter ```go // Get total days of the year carbon.Parse("2019-08-05 13:14:15").DaysInYear() // 365 @@ -658,6 +659,77 @@ carbon.Parse("2002-01-01 13:14:15").Age() // 17 carbon.Parse("2002-12-31 13:14:15").Age() // 18 ``` +##### I18n +###### Set locale +```go +// Way one(recommend) +c := carbon.Now().AddHours(1).SetLocale("zh-CN") +if c.Error != nil { + // Error handle... + fmt.Println(c.Error) +} +c.DiffForHumans() // 1 小时后 + +// Way two +lang := NewLanguage() +if err := lang.SetLocale("zh-CN");err != nil { + // Error handle... + fmt.Println(err) +} +carbon.Now().AddHours(1).SetLanguage(lang).DiffForHumans() // 1 小时后 +``` + +###### Set dir +```go +lang := NewLanguage() +if err := lang.SetDir("lang");err != nil { + // Error handle... + fmt.Println(err) +} +carbon.Now().AddHours(1).SetLanguage(lang).DiffForHumans() // 1 小时后 +``` + +###### Set some resources(the rest still translate from the specific locale) +```go +lang := NewLanguage() + +if err := lang.SetLocale("en");err != nil { + // 错误处理 + fmt.Println(err) +} + +resources := map[string]string{ + "hour":"%dh", +} +lang.SetResources(resources) + +carbon.Now().AddYears(1).SetLanguage(lang).DiffForHumans() // 1 year from now +carbon.Now().AddHours(1).SetLanguage(lang).DiffForHumans() // 1h from now +``` + +###### Set all resources +```go +lang := NewLanguage() +resources := map[string]string{ +"year":"1 yr|%d yrs", +"month":"1 mo|%d mos", +"week":"%dw", +"day":"%dd", +"hour":"%dh", +"minute":"%dm", +"second":"%ds", +"now": "just now", +"ago":"%s ago", +"from_now":"in %s", +"before":"%s before", +"after":"%s after", +} +lang.SetResources(resources) + +carbon.Now().AddYears(1).SetLanguage(lang).DiffForHumans() // in 1 yr +carbon.Now().AddHours(1).SetLanguage(lang).DiffForHumans() // in 1h +``` + ##### Calendar ```go // To year of the animal diff --git a/README.md b/README.md index daed9bc..a0fca32 100755 --- a/README.md +++ b/README.md @@ -143,43 +143,6 @@ carbon.Time2Carbon(time.Now()) carbon.Now().Carbon2Time() 或 carbon.Now().Time ``` -##### 时间设置 -```go -// 设置时区 -carbon.SetTimezone(carbon.PRC).Now().ToDateTimeString() // 2020-08-05 13:14:15 -carbon.SetTimezone(carbon.Tokyo).Now().ToDateTimeString() // 2020-08-05 14:14:15 -carbon.SetTimezone(carbon.Tokyo).SetTimezone(carbon.PRC).Now().ToDateTimeString() // 2020-08-05 13:14:15 - -// 设置语言 -carbon.Parse("2020-07-05 13:14:15").SetLocale("en").DiffForHumans()) // 1 month before -carbon.Parse("2020-07-05 13:14:15").SetLocale("zh-CN").DiffForHumans()) // 1 月前 - -// 设置年 -carbon.Parse("2019-08-05").SetYear(2020).ToDateString() // 2020-08-05 -carbon.Parse("2020-02-29").SetYear(2019).ToDateString() // 2019-03-01 - -// 设置月 -carbon.Parse("2020-01-31").SetMonth(2).ToDateString() // 2020-03-02 -carbon.Parse("2020-08-05").SetMonth(2).ToDateString() // 2020-02-05 - -// 设置日 -carbon.Parse("2019-08-05").SetDay(31).ToDateString() // 2020-08-31 -carbon.Parse("2020-02-01").SetDay(31).ToDateString() // 2020-03-02 - -// 设置时 -carbon.Parse("2020-08-05 13:14:15").SetHour(10).ToDateTimeString() // 2020-08-05 10:14:15 -carbon.Parse("2020-08-05 13:14:15").SetHour(24).ToDateTimeString() // 2020-08-06 00:14:15 - -// 设置分 -carbon.Parse("2020-08-05 13:14:15").SetMinute(10).ToDateTimeString() // 2020-08-05 13:10:15 -carbon.Parse("2020-08-05 13:14:15").SetMinute(60).ToDateTimeString() // 2020-08-05 14:00:15 - -// 设置秒 -carbon.Parse("2020-08-05 13:14:15").SetSecond(10).ToDateTimeString() // 2020-08-05 13:14:10 -carbon.Parse("2020-08-05 13:14:15").SetSecond(60).ToDateTimeString() // 2020-08-05 13:15:00 -``` ->更多时区常量请查看[constant.go](./constant.go)文件 - ##### 开始时间、结束时间 ```go // 本年开始时间 @@ -211,6 +174,11 @@ carbon.Parse("2020-08-05 13:14:15").EndOfHour().ToDateTimeString() // 2020-08-05 carbon.Parse("2020-08-05 13:14:15").StartOfMinute().ToDateTimeString() // 2020-08-05 13:14:00 // 本分钟结束时间 carbon.Parse("2020-08-05 13:14:15").EndOfMinute().ToDateTimeString() // 2020-08-05 13:14:59 + +// 本秒开始时间 +carbon.Parse("2020-08-05 13:14:15").StartOfSecond().Format("Y-m-d H:i:s.u") // 2020-08-05 13:14:15.0 +// 本秒结束时间 +carbon.Parse("2020-08-05 13:14:15").EndOfSecond().Format("Y-m-d H:i:s.u") // 2020-08-05 13:14:15.999 ``` ##### 时间旅行 @@ -389,73 +357,17 @@ carbon.Parse("2020-08-05 13:14:15").DiffInSeconds(carbon.Parse("2020-08-05 13:14 // 相差多少秒(绝对值) carbon.Parse("2020-08-05 13:14:15").DiffInSecondsWithAbs(carbon.Parse("2020-08-05 13:14:14")) // 1 -// 对人类友好的可读格式时间差(默认英文) -carbon.Now().DiffForHumans()) // just now -carbon.Now().SubYears(1).DiffForHumans() // 1 years ago -carbon.Now().SubYears(2).DiffForHumans() // 2 year ago -carbon.Now().AddYears(1).DiffForHumans() // in 1 year -carbon.Now().AddYears(2).DiffForHumans() // in 2 years -// 对人类友好的可读格式时间差(指定语言) -carbon.Now().SetLocale("zh-CN").DiffForHumans() // 刚刚 -carbon.Now().SubMonths(1).SetLocale("zh-CN").DiffForHumans() // 1 月前 -carbon.Now().AddMonths(2).SetLocale("zh-CN").DiffForHumans() // 2 月后 - -``` - -##### 时间比较 -```go -// 是否大于 -carbon.Parse("2020-08-05 13:14:15").Gt(carbon.Parse("2020-08-04 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Gt(carbon.Parse("2020-08-05 13:14:15")) // false -carbon.Parse("2020-08-05 13:14:15").Compare(">", carbon.Parse("2020-08-04 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare(">", carbon.Parse("2020-08-05 13:14:15")) // false - -// 是否小于 -carbon.Parse("2020-08-05 13:14:15").Lt(carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Lt(carbon.Parse("2020-08-05 13:14:15")) // false -carbon.Parse("2020-08-05 13:14:15").Compare("<", carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare("<", carbon.Parse("2020-08-05 13:14:15")) // false - -// 是否等于 -carbon.Parse("2020-08-05 13:14:15").Eq(carbon.Parse("2020-08-05 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Eq(carbon.Parse("2020-08-05 13:14:00")) // false -carbon.Parse("2020-08-05 13:14:15").Compare("=", carbon.Parse("2020-08-05 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare("=", carbon.Parse("2020-08-05 13:14:00")) // false - -// 是否不等于 -carbon.Parse("2020-08-05 13:14:15").Ne(carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Ne(carbon.Parse("2020-08-05 13:14:15")) // false -carbon.Parse("2020-08-05 13:14:15").Compare("!=", carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare("<>", carbon.Parse("2020-08-05 13:14:15")) // false - -// 是否大于等于 -carbon.Parse("2020-08-05 13:14:15").Gte(carbon.Parse("2020-08-04 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Gte(carbon.Parse("2020-08-05 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare(">=", carbon.Parse("2020-08-04 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare(">=", carbon.Parse("2020-08-05 13:14:15")) // true - -// 是否小于等于 -carbon.Parse("2020-08-05 13:14:15").Lte(carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Lte(carbon.Parse("2020-08-05 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare("<=", carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").Compare("<=", carbon.Parse("2020-08-05 13:14:15")) // true - -// 是否在两个时间之间(不包括这两个时间) -carbon.Parse("2020-08-05 13:14:15").Between(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // false -carbon.Parse("2020-08-05 13:14:15").Between(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true - -// 是否在两个时间之间(包括开始时间) -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedStartTime(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedStartTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true - -// 是否在两个时间之间(包括结束时间) -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedEndTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-05 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedEndTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true - -// 是否在两个时间之间(包括这两个时间) -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedBoth(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true -carbon.Parse("2020-08-05 13:14:15").BetweenIncludedBoth(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-05 13:14:15")) // true +// 对人类友好的可读格式时间差 +carbon.Parse("2020-08-05 13:14:15").DiffForHumans()) // just now +carbon.Parse("2019-08-05 13:14:15").DiffForHumans() // 1 year ago +carbon.Parse("2018-08-05 13:14:15").DiffForHumans() // 2 years ago +carbon.Parse("2021-08-05 13:14:15").DiffForHumans() // 1 year from now +carbon.Parse("2022-08-05 13:14:15").DiffForHumans() // 2 years from now +carbon.Parse("2020-08-05 13:14:15").DiffForHumans(carbon.Now()) // 1 year before +carbon.Parse("2019-08-05 13:14:15").DiffForHumans(carbon.Now()) // 2 years before +carbon.Parse("2018-08-05 13:14:15").DiffForHumans(carbon.Now()) // 1 year after +carbon.Parse("2022-08-05 13:14:15").DiffForHumans(carbon.Now()) // 2 years after ``` ##### 时间判断 @@ -538,6 +450,59 @@ carbon.Parse("2020-08-05").IsToday() // true carbon.Parse("2020-08-06 13:14:15").IsTomorrow() // true carbon.Parse("2020-08-06 00:00:00").IsTomorrow() // true carbon.Parse("2020-08-06").IsTomorrow() // true + +// 是否大于 +carbon.Parse("2020-08-05 13:14:15").Gt(carbon.Parse("2020-08-04 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Gt(carbon.Parse("2020-08-05 13:14:15")) // false +carbon.Parse("2020-08-05 13:14:15").Compare(">", carbon.Parse("2020-08-04 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare(">", carbon.Parse("2020-08-05 13:14:15")) // false + +// 是否小于 +carbon.Parse("2020-08-05 13:14:15").Lt(carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Lt(carbon.Parse("2020-08-05 13:14:15")) // false +carbon.Parse("2020-08-05 13:14:15").Compare("<", carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare("<", carbon.Parse("2020-08-05 13:14:15")) // false + +// 是否等于 +carbon.Parse("2020-08-05 13:14:15").Eq(carbon.Parse("2020-08-05 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Eq(carbon.Parse("2020-08-05 13:14:00")) // false +carbon.Parse("2020-08-05 13:14:15").Compare("=", carbon.Parse("2020-08-05 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare("=", carbon.Parse("2020-08-05 13:14:00")) // false + +// 是否不等于 +carbon.Parse("2020-08-05 13:14:15").Ne(carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Ne(carbon.Parse("2020-08-05 13:14:15")) // false +carbon.Parse("2020-08-05 13:14:15").Compare("!=", carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare("<>", carbon.Parse("2020-08-05 13:14:15")) // false + +// 是否大于等于 +carbon.Parse("2020-08-05 13:14:15").Gte(carbon.Parse("2020-08-04 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Gte(carbon.Parse("2020-08-05 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare(">=", carbon.Parse("2020-08-04 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare(">=", carbon.Parse("2020-08-05 13:14:15")) // true + +// 是否小于等于 +carbon.Parse("2020-08-05 13:14:15").Lte(carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Lte(carbon.Parse("2020-08-05 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare("<=", carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").Compare("<=", carbon.Parse("2020-08-05 13:14:15")) // true + +// 是否在两个时间之间(不包括这两个时间) +carbon.Parse("2020-08-05 13:14:15").Between(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // false +carbon.Parse("2020-08-05 13:14:15").Between(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true + +// 是否在两个时间之间(包括开始时间) +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedStartTime(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedStartTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true + +// 是否在两个时间之间(包括结束时间) +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedEndTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-05 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedEndTime(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true + +// 是否在两个时间之间(包括这两个时间) +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedBoth(carbon.Parse("2020-08-05 13:14:15"), carbon.Parse("2020-08-06 13:14:15")) // true +carbon.Parse("2020-08-05 13:14:15").BetweenIncludedBoth(carbon.Parse("2020-08-04 13:14:15"), carbon.Parse("2020-08-05 13:14:15")) // true + ``` ##### 时间输出 @@ -606,6 +571,42 @@ carbon.Parse("2020-08-05 13:14:15").Format("l jS \\o\\f F Y h:i:s A") // Wednesd ``` >更多格式化输出符号请查看附录 格式化符号表 +##### 时间设置 +```go +// 设置时区 +carbon.SetTimezone(carbon.PRC).Now().ToDateTimeString() // 2020-08-05 13:14:15 +carbon.SetTimezone(carbon.Tokyo).Now().ToDateTimeString() // 2020-08-05 14:14:15 +carbon.SetTimezone(carbon.Tokyo).SetTimezone(carbon.PRC).Now().ToDateTimeString() // 2020-08-05 13:14:15 + +// 设置语言 +carbon.Parse("2020-07-05 13:14:15").SetLocale("en").DiffForHumans()) // 1 month ago +carbon.Parse("2020-07-05 13:14:15").SetLocale("zh-CN").DiffForHumans()) // 1 月前 + +// 设置年 +carbon.Parse("2019-08-05").SetYear(2020).ToDateString() // 2020-08-05 +carbon.Parse("2020-02-29").SetYear(2019).ToDateString() // 2019-03-01 + +// 设置月 +carbon.Parse("2020-01-31").SetMonth(2).ToDateString() // 2020-03-02 +carbon.Parse("2020-08-05").SetMonth(2).ToDateString() // 2020-02-05 + +// 设置日 +carbon.Parse("2019-08-05").SetDay(31).ToDateString() // 2020-08-31 +carbon.Parse("2020-02-01").SetDay(31).ToDateString() // 2020-03-02 + +// 设置时 +carbon.Parse("2020-08-05 13:14:15").SetHour(10).ToDateTimeString() // 2020-08-05 10:14:15 +carbon.Parse("2020-08-05 13:14:15").SetHour(24).ToDateTimeString() // 2020-08-06 00:14:15 + +// 设置分 +carbon.Parse("2020-08-05 13:14:15").SetMinute(10).ToDateTimeString() // 2020-08-05 13:10:15 +carbon.Parse("2020-08-05 13:14:15").SetMinute(60).ToDateTimeString() // 2020-08-05 14:00:15 + +// 设置秒 +carbon.Parse("2020-08-05 13:14:15").SetSecond(10).ToDateTimeString() // 2020-08-05 13:14:10 +carbon.Parse("2020-08-05 13:14:15").SetSecond(60).ToDateTimeString() // 2020-08-05 13:15:00 +``` + ##### 时间获取 ```go // 获取本年总天数 @@ -665,6 +666,76 @@ carbon.Parse("2002-12-31 13:14:15").Age() // 18 ``` > 关于第几周的计算如有疑惑请查看 [ISO8601标准](https://baike.baidu.com/item/ISO%208601/3910715) +##### 多语言支持 +###### 设置区域 +```go +// 方式一(推荐) +c := carbon.Now().AddHours(1).SetLocale("zh-CN") +if c.Error != nil { + // 错误处理 + fmt.Println(c.Error) +} +c.DiffForHumans() // 1 小时后 + +// 方式二 +lang := NewLanguage() +if err := lang.SetLocale("zh-CN");err != nil { + // 错误处理 + fmt.Println(err) +} +carbon.Now().AddHours(1).SetLanguage(lang).DiffForHumans() // 1 小时后 +``` +###### 设置目录 +```go +lang := NewLanguage() +if err := lang.SetDir("lang");err != nil { + // 错误处理 + fmt.Println(err) +} +carbon.Now().AddHours(1).SetLanguage(lang).DiffForHumans() // 1 小时后 +``` + +###### 部分自定义翻译(其余仍然按照指定的locale翻译) +```go +lang := NewLanguage() + +if err := lang.SetLocale("en");err != nil { + // 错误处理 + fmt.Println(err) +} + +resources := map[string]string{ + "hour":"%dh", +} +lang.SetResources(resources) + +carbon.Now().AddYears(1).SetLanguage(lang).DiffForHumans() // 1 year from now +carbon.Now().AddHours(1).SetLanguage(lang).DiffForHumans() // 1h from now +``` + +###### 完全自定义翻译 +```go +lang := NewLanguage() +resources := map[string]string{ +"year":"1 yr|%d yrs", +"month":"1 mo|%d mos", +"week":"%dw", +"day":"%dd", +"hour":"%dh", +"minute":"%dm", +"second":"%ds", +"now": "just now", +"ago":"%s ago", +"from_now":"in %s", +"before":"%s before", +"after":"%s after", +} +lang.SetResources(resources) + +carbon.Now().AddYears(1).SetLanguage(lang).DiffForHumans() // in 1 yr +carbon.Now().AddHours(1).SetLanguage(lang).DiffForHumans() // in 1h +``` + ##### 农历支持 ```go // 获取生肖年 @@ -833,7 +904,7 @@ fmt.Println(c.ToDateTimeString()) // 输出 invalid timezone "XXXX", please see the $GOROOT/lib/time/zoneinfo.zip file for all valid timezone ``` -> 建议使用SetTimezone()、Parse()、ParseByFormat()、AddDuration()、SubDuration()等方法时先进行错误处理判断,除非你能确保传入参数无误 +> 建议使用SetTimezone()、Parse()、ParseByFormat()、AddDuration()、SubDuration()、SetLocale()等方法时先进行错误处理判断,除非你能确保传入参数无误 #### 附录 ##### 格式化符号表 | 符号 | 描述 | 长度 | 范围 | 示例 | diff --git a/carbon.go b/carbon.go index f7e02ee..3e5a4aa 100755 --- a/carbon.go +++ b/carbon.go @@ -1,12 +1,133 @@ +// @Title carbon +// @Description A simple,semantic and developer-friendly golang package for datetime +// @Page github.com/golang-module/carbon +// @Version v1.3.2 +// @Author gouguoyin +// @Email mail@gouguoyin.cn package carbon -import "C" -import ( - "strconv" - "strings" - "time" +import "time" + +// 时区常量 +const ( + Local = "Local" + CET = "CET" + EET = "EET" + EST = "EST" + GMT = "GMT" + UTC = "UTC" + UCT = "UCT" + MST = "MST" + + Cuba = "Cuba" + Egypt = "Egypt" + Eire = "Eire" + Greenwich = "Greenwich" + Iceland = "Iceland" + Iran = "Iran" + Israel = "Israel" + Jamaica = "Jamaica" + Japan = "Japan" + Libya = "Libya" + Poland = "Poland" + Portugal = "Portugal" + PRC = "PRC" + Singapore = "Singapore" + Turkey = "Turkey" + Zulu = "Zulu" + + Shanghai = "Asia/Shanghai" + Chongqing = "Asia/Chongqing" + HongKong = "Asia/Hong_Kong" + Macao = "Asia/Macao" + Taipei = "Asia/Taipei" + Tokyo = "Asia/Tokyo" + London = "Europe/London" + NewYork = "America/New_York" + LosAngeles = "America/Los_Angeles" ) +// 月份常量 +const ( + January = "January" // 一月 + February = "February" // 二月 + March = "March" // 三月 + April = "April" // 四月 + May = "May" // 五月 + June = "June" // 六月 + July = "July" // 七月 + August = "August" // 八月 + September = "September" // 九月 + October = "October" // 十月 + November = "November" // 十一月 + December = "December" // 十二月 +) + +// 星期常量 +const ( + Monday = "Monday" // 周一 + Tuesday = "Tuesday" // 周二 + Wednesday = "Wednesday" // 周三 + Thursday = "Thursday" // 周四 + Friday = "Friday" // 周五 + Saturday = "Saturday" // 周六 + Sunday = "Sunday" // 周日 +) + +// 数字常量 +const ( + YearsPerMillennium = 1000 // 每千年1000年 + YearsPerCentury = 100 // 每世纪100年 + YearsPerDecade = 10 // 每十年10年 + QuartersPerYear = 4 // 每年4季度 + MonthsPerYear = 12 // 每年12月 + MonthsPerQuarter = 3 // 每季度3月 + WeeksPerNormalYear = 52 // 每常规年52周 + weeksPerLongYear = 53 // 每长年53周 + WeeksPerMonth = 4 // 每月4周 + DaysPerLeapYear = 366 // 每闰年366天 + DaysPerNormalYear = 365 // 每常规年365天 + DaysPerWeek = 7 // 每周7天 + HoursPerWeek = 168 // 每周168小时 + HoursPerDay = 24 // 每天24小时 + MinutesPerDay = 1440 // 每天1440分钟 + MinutesPerHour = 60 // 每小时60分钟 + SecondsPerWeek = 604800 // 每周604800秒 + SecondsPerDay = 86400 // 每天86400秒 + SecondsPerHour = 3600 // 每小时3600秒 + SecondsPerMinute = 60 // 每分钟60秒 + MillisecondsPerSecond = 1000 // 每秒1000毫秒 + MicrosecondsPerMillisecond = 1000 // 每毫秒1000微秒 + MicrosecondsPerSecond = 1000000 // 每秒1000000微秒 +) + +// 时间格式化常量 +const ( + AnsicFormat = time.ANSIC + UnixDateFormat = time.UnixDate + RubyDateFormat = time.RubyDate + RFC822Format = time.RFC822 + RFC822ZFormat = time.RFC822Z + RFC850Format = time.RFC850 + RFC1123Format = time.RFC1123 + RFC1123ZFormat = time.RFC1123Z + RssFormat = time.RFC1123Z + RFC2822Format = time.RFC1123Z + RFC3339Format = time.RFC3339 + KitchenFormat = time.Kitchen + CookieFormat = "Monday, 02-Jan-2006 15:04:05 MST" + RFC1036Format = "Mon, 02 Jan 06 15:04:05 -0700" + RFC7231Format = "Mon, 02 Jan 2006 15:04:05 GMT" + DayDateTimeFormat = "Mon, Aug 2, 2006 3:04 PM" + DateTimeFormat = "2006-01-02 15:04:05" + DateFormat = "2006-01-02" + TimeFormat = "15:04:05" + ShortDateTimeFormat = "20060102150405" + ShortDateFormat = "20060102" + ShortTimeFormat = "150405" +) + +// Carbon 定义 Carbon 结构体 type Carbon struct { Time time.Time Loc *time.Location @@ -54,611 +175,3 @@ func (c Carbon) Yesterday() Carbon { func Yesterday() Carbon { return SetTimezone(Local).Yesterday() } - -// CreateFromTimestamp 从时间戳创建Carbon实例 -func (c Carbon) CreateFromTimestamp(timestamp int64) Carbon { - ts := timestamp - switch len(strconv.FormatInt(timestamp, 10)) { - case 10: - ts = timestamp - case 13: - ts = timestamp / 1e3 - case 16: - ts = timestamp / 1e6 - case 19: - ts = timestamp / 1e9 - default: - ts = 0 - } - c.Time = time.Unix(ts, 0) - return c -} - -// CreateFromTimestamp 从时间戳创建Carbon实例(默认时区) -func CreateFromTimestamp(timestamp int64) Carbon { - return SetTimezone(Local).CreateFromTimestamp(timestamp) -} - -// CreateFromDateTime 从年月日时分秒创建Carbon实例 -func (c Carbon) CreateFromDateTime(year int, month int, day int, hour int, minute int, second int) Carbon { - c.Time = time.Date(year, time.Month(month), day, hour, minute, second, 0, c.Loc) - return c -} - -// CreateFromDateTime 从年月日时分秒创建Carbon实例(默认时区) -func CreateFromDateTime(year int, month int, day int, hour int, minute int, second int) Carbon { - return SetTimezone(Local).CreateFromDateTime(year, month, day, hour, minute, second) -} - -// CreateFromDate 从年月日创建Carbon实例 -func (c Carbon) CreateFromDate(year int, month int, day int) Carbon { - hour, minute, second := time.Now().Clock() - c.Time = time.Date(year, time.Month(month), day, hour, minute, second, 0, c.Loc) - return c -} - -// CreateFromDate 从年月日创建Carbon实例(默认时区) -func CreateFromDate(year int, month int, day int) Carbon { - return SetTimezone(Local).CreateFromDate(year, month, day) -} - -// CreateFromTime 从时分秒创建Carbon实例 -func (c Carbon) CreateFromTime(hour int, minute int, second int) Carbon { - year, month, day := time.Now().Date() - c.Time = time.Date(year, month, day, hour, minute, second, 0, c.Loc) - return c -} - -// CreateFromTime 从时分秒创建Carbon实例(默认时区) -func CreateFromTime(hour int, minute int, second int) Carbon { - return SetTimezone(Local).CreateFromTime(hour, minute, second) -} - -// Parse 将标准格式时间字符串解析成 Carbon 实例 -func (c Carbon) Parse(value string) Carbon { - if c.Error != nil { - return c - } - - layout := DateTimeFormat - - if value == "" || value == "0" || value == "0000-00-00 00:00:00" || value == "0000-00-00" || value == "00:00:00" { - return c - } - - if len(value) == 10 && strings.Count(value, "-") == 2 { - layout = DateFormat - } - - if strings.Index(value, "T") == 10 { - layout = RFC3339Format - } - - if _, err := strconv.ParseInt(value, 10, 64); err == nil { - switch len(value) { - case 8: - layout = ShortDateFormat - case 14: - layout = ShortDateTimeFormat - } - } - - tt, err := parseByLayout(value, layout) - c.Time = tt - c.Error = err - return c -} - -// Parse 将标准格式时间字符串解析成 Carbon 实例(默认时区) -func Parse(value string) Carbon { - return SetTimezone(Local).Parse(value) -} - -// ParseByFormat 将特殊格式时间字符串解析成 Carbon 实例 -func (c Carbon) ParseByFormat(value string, format string) Carbon { - if c.Error != nil { - return c - } - layout := format2layout(format) - return c.ParseByLayout(value, layout) -} - -// ParseByFormat 将特殊格式时间字符串解析成 Carbon 实例(默认时区) -func ParseByFormat(value string, format string) Carbon { - return SetTimezone(Local).ParseByFormat(value, format) -} - -// ParseByLayout 将布局时间字符串解析成 Carbon 实例 -func (c Carbon) ParseByLayout(value string, layout string) Carbon { - if c.Error != nil { - return c - } - tt, err := parseByLayout(value, layout) - c.Time = tt - c.Error = err - return c -} - -// ParseByLayout 将布局时间字符串解析成 Carbon 实例(默认时区) -func ParseByLayout(value string, layout string) Carbon { - return SetTimezone(Local).ParseByLayout(value, layout) -} - -// Time2Carbon 将 time.Time 转换成 Carbon -func Time2Carbon(tt time.Time) Carbon { - loc, _ := time.LoadLocation(Local) - return Carbon{Time: tt, Loc: loc} -} - -// Carbon2Time 将 Carbon 转换成 time.Time -func (c Carbon) Carbon2Time() time.Time { - return c.Time -} - -// AddDurations 按照持续时间字符串增加时间 -// 支持整数/浮点数和符号ns(纳秒)、us(微妙)、ms(毫秒)、s(秒)、m(分钟)、h(小时)的组合 -func (c Carbon) AddDuration(duration string) Carbon { - if c.Error != nil { - return c - } - td, err := parseByDuration(duration) - c.Time = c.Time.Add(td) - c.Error = err - return c -} - -// SubDurations 按照持续时间字符串减少时间 -// 支持整数/浮点数和符号ns(纳秒)、us(微妙)、ms(毫秒)、s(秒)、m(分钟)、h(小时)的组合 -func (c Carbon) SubDuration(duration string) Carbon { - if c.Error != nil { - return c - } - td, err := parseByDuration("-" + duration) - c.Time = c.Time.Add(td) - c.Error = err - return c -} - -// AddCenturies N世纪后 -func (c Carbon) AddCenturies(centuries int) Carbon { - return c.AddYears(YearsPerCentury * centuries) -} - -// AddCenturiesNoOverflow N世纪后(月份不溢出) -func (c Carbon) AddCenturiesNoOverflow(centuries int) Carbon { - return c.AddYearsNoOverflow(centuries * YearsPerCentury) -} - -// AddCentury 1世纪后 -func (c Carbon) AddCentury() Carbon { - return c.AddCenturies(1) -} - -// AddCenturyNoOverflow 1世纪后(月份不溢出) -func (c Carbon) AddCenturyNoOverflow() Carbon { - return c.AddCenturiesNoOverflow(1) -} - -// SubCenturies N世纪前 -func (c Carbon) SubCenturies(centuries int) Carbon { - return c.SubYears(YearsPerCentury * centuries) -} - -// SubCenturiesNoOverflow N世纪前(月份不溢出) -func (c Carbon) SubCenturiesNoOverflow(centuries int) Carbon { - return c.SubYearsNoOverflow(centuries * YearsPerCentury) -} - -// SubCentury 1世纪前 -func (c Carbon) SubCentury() Carbon { - return c.SubCenturies(1) -} - -// SubCenturyNoOverflow 1世纪前(月份不溢出) -func (c Carbon) SubCenturyNoOverflow() Carbon { - return c.SubCenturiesNoOverflow(1) -} - -// AddYears N年后 -func (c Carbon) AddYears(years int) Carbon { - c.Time = c.Time.AddDate(years, 0, 0) - return c -} - -// AddYearsNoOverflow N年后(月份不溢出) -func (c Carbon) AddYearsNoOverflow(years int) Carbon { - year := c.Time.Year() + years - month := c.Time.Month() - day := c.Time.Day() - - // 获取N年后本月的最后一天 - last := time.Date(year, month, 1, c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc).AddDate(0, 1, -1) - - if day > last.Day() { - day = last.Day() - } - - c.Time = time.Date(last.Year(), last.Month(), day, c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) - return c -} - -// AddYear 1年后 -func (c Carbon) AddYear() Carbon { - return c.AddYears(1) -} - -// AddYearNoOverflow 1年后(月份不溢出) -func (c Carbon) AddYearNoOverflow() Carbon { - return c.AddYearsNoOverflow(1) -} - -// SubYears N年前 -func (c Carbon) SubYears(years int) Carbon { - c.Time = c.Time.AddDate(-years, 0, 0) - return c -} - -// SubYearsWithOverflow N年前(月份不溢出) -func (c Carbon) SubYearsNoOverflow(years int) Carbon { - return c.AddYearsNoOverflow(-years) -} - -// SubYear 1年前 -func (c Carbon) SubYear() Carbon { - return c.SubYears(1) -} - -// SubYearWithOverflow 1年前(月份不溢出) -func (c Carbon) SubYearNoOverflow() Carbon { - return c.SubYearsNoOverflow(1) -} - -// AddQuarters N季度后 -func (c Carbon) AddQuarters(quarters int) Carbon { - return c.AddMonths(quarters * MonthsPerQuarter) -} - -// AddQuartersNoOverflow N季度后(月份不溢出) -func (c Carbon) AddQuartersNoOverflow(quarters int) Carbon { - return c.AddMonthsNoOverflow(quarters * MonthsPerQuarter) -} - -// AddQuarter 1季度后 -func (c Carbon) AddQuarter() Carbon { - return c.AddQuarters(1) -} - -// NextQuarters 1季度后(月份不溢出) -func (c Carbon) AddQuarterNoOverflow() Carbon { - return c.AddQuartersNoOverflow(1) -} - -// SubQuarters N季度前 -func (c Carbon) SubQuarters(quarters int) Carbon { - return c.SubMonths(quarters * MonthsPerQuarter) -} - -// SubQuartersNoOverflow N季度前(月份不溢出) -func (c Carbon) SubQuartersNoOverflow(quarters int) Carbon { - return c.AddMonthsNoOverflow(-quarters * MonthsPerQuarter) -} - -// SubQuarter 1季度前 -func (c Carbon) SubQuarter() Carbon { - return c.SubQuarters(1) -} - -// SubQuarterNoOverflow 1季度前(月份不溢出) -func (c Carbon) SubQuarterNoOverflow() Carbon { - return c.SubQuartersNoOverflow(1) -} - -// AddMonths N月后 -func (c Carbon) AddMonths(months int) Carbon { - c.Time = c.Time.AddDate(0, months, 0) - return c -} - -// AddMonthsNoOverflow N月后(月份不溢出) -func (c Carbon) AddMonthsNoOverflow(months int) Carbon { - year := c.Time.Year() - month := c.Time.Month() + time.Month(months) - day := c.Time.Day() - - // 获取N月后的最后一天 - last := time.Date(year, month, 1, c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc).AddDate(0, 1, -1) - - if day > last.Day() { - day = last.Day() - } - - c.Time = time.Date(last.Year(), last.Month(), day, c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) - return c -} - -// AddMonth 1月后 -func (c Carbon) AddMonth() Carbon { - return c.AddMonths(1) -} - -// AddMonthNoOverflow 1月后(月份不溢出) -func (c Carbon) AddMonthNoOverflow() Carbon { - return c.AddMonthsNoOverflow(1) -} - -// SubMonths N月前 -func (c Carbon) SubMonths(months int) Carbon { - c.Time = c.Time.AddDate(0, -months, 0) - return c -} - -// SubMonthsNoOverflow N月前(月份不溢出) -func (c Carbon) SubMonthsNoOverflow(months int) Carbon { - return c.AddMonthsNoOverflow(-months) -} - -// SubMonth 1月前 -func (c Carbon) SubMonth() Carbon { - return c.SubMonths(1) -} - -// SubMonthNoOverflow 1月前(月份不溢出) -func (c Carbon) SubMonthNoOverflow() Carbon { - return c.SubMonthsNoOverflow(1) -} - -// AddWeeks N周后 -func (c Carbon) AddWeeks(weeks int) Carbon { - return c.AddDays(weeks * DaysPerWeek) -} - -// AddWeek 1天后 -func (c Carbon) AddWeek() Carbon { - return c.AddWeeks(1) -} - -// SubWeeks N周后 -func (c Carbon) SubWeeks(weeks int) Carbon { - return c.SubDays(weeks * DaysPerWeek) -} - -// SubWeek 1天后 -func (c Carbon) SubWeek() Carbon { - return c.SubWeeks(1) -} - -// AddDays N天后 -func (c Carbon) AddDays(days int) Carbon { - c.Time = c.Time.AddDate(0, 0, days) - return c -} - -// AddDay 1天后 -func (c Carbon) AddDay() Carbon { - return c.AddDays(1) -} - -// SubDays N天前 -func (c Carbon) SubDays(days int) Carbon { - c.Time = c.Time.AddDate(0, 0, -days) - return c -} - -// SubDay 1天前 -func (c Carbon) SubDay() Carbon { - return c.SubDays(1) -} - -// AddHours N小时后 -func (c Carbon) AddHours(hours int) Carbon { - td := time.Duration(hours) * time.Hour - c.Time = c.Time.Add(td) - return c -} - -// AddHour 1小时后 -func (c Carbon) AddHour() Carbon { - return c.AddHours(1) -} - -// SubHours N小时前 -func (c Carbon) SubHours(hours int) Carbon { - td := time.Duration(hours) * -time.Hour - c.Time = c.Time.Add(td) - return c -} - -// SubHour 1小时前 -func (c Carbon) SubHour() Carbon { - return c.SubHours(1) -} - -// AddMinutes N分钟后 -func (c Carbon) AddMinutes(minutes int) Carbon { - td := time.Duration(minutes) * time.Minute - c.Time = c.Time.Add(td) - return c -} - -// AddMinute 1分钟后 -func (c Carbon) AddMinute() Carbon { - return c.AddMinutes(1) -} - -// SubMinutes N分钟前 -func (c Carbon) SubMinutes(minutes int) Carbon { - td := time.Duration(minutes) * -time.Minute - c.Time = c.Time.Add(td) - return c -} - -// SubMinute 1分钟前 -func (c Carbon) SubMinute() Carbon { - return c.SubMinutes(1) -} - -// AddSeconds N秒钟后 -func (c Carbon) AddSeconds(seconds int) Carbon { - td := time.Duration(seconds) * time.Second - c.Time = c.Time.Add(td) - return c -} - -// AddSecond 1秒钟后 -func (c Carbon) AddSecond() Carbon { - return c.AddSeconds(1) -} - -// SubSeconds N秒钟前 -func (c Carbon) SubSeconds(seconds int) Carbon { - td := time.Duration(seconds) * -time.Second - c.Time = c.Time.Add(td) - return c -} - -// SubSecond 1秒钟前 -func (c Carbon) SubSecond() Carbon { - return c.SubSeconds(1) -} - -// StartOfYear 本年开始时间 -func (c Carbon) StartOfYear() Carbon { - c.Time = time.Date(c.Time.Year(), 1, 1, 0, 0, 0, 0, c.Loc) - return c -} - -// EndOfYear 本年结束时间 -func (c Carbon) EndOfYear() Carbon { - c.Time = time.Date(c.Time.Year(), 12, 31, 23, 59, 59, 0, c.Loc) - return c -} - -// StartOfMonth 本月开始时间 -func (c Carbon) StartOfMonth() Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), 1, 0, 0, 0, 0, c.Loc) - return c -} - -// EndOfMonth 本月结束时间 -func (c Carbon) EndOfMonth() Carbon { - t := time.Date(c.Time.Year(), c.Time.Month(), 1, 23, 59, 59, 0, c.Loc) - c.Time = t.AddDate(0, 1, -1) - return c -} - -// StartOfWeek 本周开始时间 -func (c Carbon) StartOfWeek() Carbon { - days := c.Time.Weekday() - if days == 0 { - days = DaysPerWeek - } - t := time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), 0, 0, 0, 0, c.Loc) - c.Time = t.AddDate(0, 0, int(1-days)) - return c -} - -// EndOfWeek 本周结束时间 -func (c Carbon) EndOfWeek() Carbon { - days := c.Time.Weekday() - if days == 0 { - days = DaysPerWeek - } - t := time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), 23, 59, 59, 0, c.Loc) - c.Time = t.AddDate(0, 0, int(DaysPerWeek-days)) - return c -} - -// StartOfDay 本日开始时间 -func (c Carbon) StartOfDay() Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), 0, 0, 0, 0, c.Loc) - return c -} - -// EndOfDay 本日结束时间 -func (c Carbon) EndOfDay() Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), 23, 59, 59, 0, c.Loc) - return c -} - -// StartOfHour 小时开始时间 -func (c Carbon) StartOfHour() Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), 0, 0, 0, c.Loc) - return c -} - -// EndOfHour 小时结束时间 -func (c Carbon) EndOfHour() Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), 59, 59, 0, c.Loc) - return c -} - -// StartOfMinute 分钟开始时间 -func (c Carbon) StartOfMinute() Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), 0, 0, c.Loc) - return c -} - -// EndOfMinute 分钟结束时间 -func (c Carbon) EndOfMinute() Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), 59, 0, c.Loc) - return c -} - -// Timezone 设置时区 -func SetTimezone(name string) Carbon { - loc, err := getLocationByTimezone(name) - return Carbon{Loc: loc, Error: err} -} - -// Timezone 设置时区 -func (c Carbon) SetTimezone(name string) Carbon { - loc, err := getLocationByTimezone(name) - c.Loc = loc - c.Error = err - return c -} - -// SetYear 设置年 -func (c Carbon) SetYear(year int) Carbon { - c.Time = time.Date(year, c.Time.Month(), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) - return c -} - -// SetMonth 设置月 -func (c Carbon) SetMonth(month int) Carbon { - c.Time = time.Date(c.Time.Year(), time.Month(month), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) - return c -} - -// SetDay 设置日 -func (c Carbon) SetDay(day int) Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), day, c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) - return c -} - -// SetHour 设置时 -func (c Carbon) SetHour(hour int) Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), hour, c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) - return c -} - -// SetMinute 设置分 -func (c Carbon) SetMinute(minute int) Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), minute, c.Time.Second(), c.Time.Nanosecond(), c.Loc) - return c -} - -// SetSecond 设置秒 -func (c Carbon) SetSecond(second int) Carbon { - c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), second, c.Time.Nanosecond(), c.Loc) - return c -} - -// SetLocale 设置语言区域 -func (c Carbon) SetLocale(locale string) Carbon { - lang := NewLanguage() - err := lang.SetLocale(locale) - c.Lang = lang - c.Error = err - return c -} diff --git a/carbon_test.go b/carbon_test.go index 0052ff3..7f7bd13 100755 --- a/carbon_test.go +++ b/carbon_test.go @@ -1,172 +1,10 @@ package carbon import ( - "fmt" "testing" "time" ) -var TimezoneTests = []struct { - input string // 输入值 - timezone string // 输入参数 - output string // 期望输出值 -}{ - {"2020-08-05 13:14:15", PRC, "2020-08-05 13:14:15"}, - {"2020-08-05", Tokyo, "2020-08-05 01:00:00"}, - {"2020-08-05", "Hangzhou", "panic"}, // 异常情况 -} - -func TestCarbon_SetTimezone1(t *testing.T) { - for _, v := range TimezoneTests { - output := SetTimezone(v.timezone).Parse(v.input) - - if output.Error != nil { - fmt.Println("catch an exception in SetTimezone():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output.ToDateTimeString()) - } - } -} - -func TestCarbon_SetTimezone2(t *testing.T) { - for _, v := range TimezoneTests { - output := SetTimezone(PRC).SetTimezone(v.timezone).Parse(v.input) - - if output.Error != nil { - fmt.Println("catch an exception in SetTimezone():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output.ToDateTimeString()) - } - } -} - -func TestCarbon_SetYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - year int // 输入参数 - output string // 期望输出值 - }{ - {"2020-01-01", 2019, "2019-01-01"}, - {"2020-01-31", 2019, "2019-01-31"}, - {"2020-02-01", 2019, "2019-02-01"}, - {"2020-02-28", 2019, "2019-02-28"}, - {"2020-02-29", 2019, "2019-03-01"}, - } - - for _, v := range Tests { - output := Parse(v.input).SetYear(v.year).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_SetMonth(t *testing.T) { - Tests := []struct { - input string // 输入值 - month int // 输入参数 - output string // 期望输出值 - }{ - {"2020-01-01", 2, "2020-02-01"}, - {"2020-01-30", 2, "2020-03-01"}, - {"2020-01-31", 2, "2020-03-02"}, - {"2020-08-05", 2, "2020-02-05"}, - } - - for _, v := range Tests { - output := Parse(v.input).SetMonth(v.month).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_SetDay(t *testing.T) { - Tests := []struct { - input string // 输入值 - day int // 输入参数 - output string // 期望输出值 - }{ - {"2020-01-01", 31, "2020-01-31"}, - {"2020-02-01", 31, "2020-03-02"}, - {"2020-02-28", 31, "2020-03-02"}, - {"2020-02-29", 31, "2020-03-02"}, - } - - for _, v := range Tests { - output := Parse(v.input).SetDay(v.day).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_SetHour(t *testing.T) { - Tests := []struct { - input string // 输入值 - hour int // 输入参数 - output string // 期望输出值 - }{ - {"2020-08-05 13:14:15", 10, "2020-08-05 10:14:15"}, - {"2020-08-05 13:14:15", 24, "2020-08-06 00:14:15"}, - } - - for _, v := range Tests { - output := Parse(v.input).SetHour(v.hour).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_SetMinute(t *testing.T) { - Tests := []struct { - input string // 输入值 - minute int // 输入参数 - output string // 期望输出值 - }{ - {"2020-08-05 13:14:15", 10, "2020-08-05 13:10:15"}, - {"2020-08-05 13:14:15", 60, "2020-08-05 14:00:15"}, - } - - for _, v := range Tests { - output := Parse(v.input).SetMinute(v.minute).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_SetSecond(t *testing.T) { - Tests := []struct { - input string // 输入值 - second int // 输入参数 - output string // 期望输出值 - }{ - {"2020-08-05 13:14:15", 10, "2020-08-05 13:14:10"}, - {"2020-08-05 13:14:15", 60, "2020-08-05 13:15:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).SetSecond(v.second).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - func TestCarbon_Now(t *testing.T) { expected := time.Now().Format(DateTimeFormat) @@ -206,2168 +44,12 @@ func TestCarbon_Tomorrow(t *testing.T) { output := Tomorrow().Time.Format(DateTimeFormat) if expected != output { - t.Fatalf("Expected %s, but got %s", expected, output) + t.Errorf("Expected %s, but got %s", expected, output) } output = SetTimezone(PRC).Parse("2020-08-05").Tomorrow().Time.Format(DateFormat) if "2020-08-06" != output { - t.Fatalf("Expected %s, but got %s", expected, output) - } -} - -func TestCarbon_StartOfYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-01-01 00:00:00"}, - {"2020-01-31 23:59:59", "2020-01-01 00:00:00"}, - {"2020-02-01 13:14:15", "2020-01-01 00:00:00"}, - {"2020-02-28", "2020-01-01 00:00:00"}, - {"2020-02-29", "2020-01-01 00:00:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).StartOfYear().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_EndOfYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-12-31 23:59:59"}, - {"2020-01-31 23:59:59", "2020-12-31 23:59:59"}, - {"2020-02-01 13:14:15", "2020-12-31 23:59:59"}, - {"2020-02-28", "2020-12-31 23:59:59"}, - {"2020-02-29", "2020-12-31 23:59:59"}, - } - - for _, v := range Tests { - output := Parse(v.input).EndOfYear().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_StartOfMonth(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-01-01 00:00:00"}, - {"2020-01-31 23:59:59", "2020-01-01 00:00:00"}, - {"2020-02-01 13:14:15", "2020-02-01 00:00:00"}, - {"2020-02-28", "2020-02-01 00:00:00"}, - {"2020-02-29", "2020-02-01 00:00:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).StartOfMonth().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_EndOfMonth(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-01-31 23:59:59"}, - {"2020-01-31 23:59:59", "2020-01-31 23:59:59"}, - {"2020-02-01 13:14:15", "2020-02-29 23:59:59"}, - {"2020-02-28", "2020-02-29 23:59:59"}, - {"2020-02-29", "2020-02-29 23:59:59"}, - } - - for _, v := range Tests { - output := Parse(v.input).EndOfMonth().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_StartOfWeek(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2019-12-30 00:00:00"}, - {"2020-01-31 23:59:59", "2020-01-27 00:00:00"}, - {"2020-02-01 13:14:15", "2020-01-27 00:00:00"}, - {"2020-02-28", "2020-02-24 00:00:00"}, - {"2020-02-29", "2020-02-24 00:00:00"}, - {"2020-10-04", "2020-09-28 00:00:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).StartOfWeek().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_EndOfWeek(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-01-05 23:59:59"}, - {"2020-01-31 23:59:59", "2020-02-02 23:59:59"}, - {"2020-02-01 13:14:15", "2020-02-02 23:59:59"}, - {"2020-02-28", "2020-03-01 23:59:59"}, - {"2020-02-29", "2020-03-01 23:59:59"}, - {"2020-10-04", "2020-10-04 23:59:59"}, - } - - for _, v := range Tests { - output := Parse(v.input).EndOfWeek().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_StartOfDay(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-01-01 00:00:00"}, - {"2020-01-31 23:59:59", "2020-01-31 00:00:00"}, - {"2020-02-01 13:14:15", "2020-02-01 00:00:00"}, - {"2020-02-28", "2020-02-28 00:00:00"}, - {"2020-02-29", "2020-02-29 00:00:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).StartOfDay().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_EndOfDay(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-01-01 23:59:59"}, - {"2020-01-31 23:59:59", "2020-01-31 23:59:59"}, - {"2020-02-01 13:14:15", "2020-02-01 23:59:59"}, - {"2020-02-28", "2020-02-28 23:59:59"}, - {"2020-02-29", "2020-02-29 23:59:59"}, - } - - for _, v := range Tests { - output := Parse(v.input).EndOfDay().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_StartOfHour(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-01-01 00:00:00"}, - {"2020-01-31 23:59:59", "2020-01-31 23:00:00"}, - {"2020-02-01 13:14:15", "2020-02-01 13:00:00"}, - {"2020-02-28", "2020-02-28 00:00:00"}, - {"2020-02-29", "2020-02-29 00:00:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).StartOfHour().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_EndOfHour(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-01-01 00:59:59"}, - {"2020-01-31 23:59:59", "2020-01-31 23:59:59"}, - {"2020-02-01 13:14:15", "2020-02-01 13:59:59"}, - {"2020-02-28", "2020-02-28 00:59:59"}, - {"2020-02-29", "2020-02-29 00:59:59"}, - } - - for _, v := range Tests { - output := Parse(v.input).EndOfHour().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_StartOfMinute(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-01-01 00:00:00"}, - {"2020-01-31 23:59:59", "2020-01-31 23:59:00"}, - {"2020-02-01 13:14:15", "2020-02-01 13:14:00"}, - {"2020-02-28", "2020-02-28 00:00:00"}, - {"2020-02-29", "2020-02-29 00:00:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).StartOfMinute().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_EndOfMinute(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 00:00:00", "2020-01-01 00:00:59"}, - {"2020-01-31 23:59:59", "2020-01-31 23:59:59"}, - {"2020-02-01 13:14:15", "2020-02-01 13:14:59"}, - {"2020-02-28", "2020-02-28 00:00:59"}, - {"2020-02-29", "2020-02-29 00:00:59"}, - } - - for _, v := range Tests { - output := Parse(v.input).EndOfMinute().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_CreateFromTimestamp(t *testing.T) { - Tests := []struct { - timestamp int64 // 输入参数 - output string // 期望输出值 - }{ - {123456, "1970-01-01 08:00:00"}, - {1577855655, "2020-01-01 13:14:15"}, - {1604074084682, "2020-10-31 00:08:04"}, - {1604074196366540, "2020-10-31 00:09:56"}, - {1604074298500312000, "2020-10-31 00:11:38"}, - } - - for _, v := range Tests { - output := CreateFromTimestamp(v.timestamp).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %d, expected %s, but got %s", v.timestamp, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).CreateFromTimestamp(v.timestamp).ToDateTimeString() - - if output != v.output { - t.Fatalf("Expected %s, but got %s", v.output, output) - } - } -} - -func TestCarbon_CreateFromDateTime(t *testing.T) { - Tests := []struct { - year, month, day, hour, minute, second int // 输入参数 - output string // 期望输出值 - }{ - {2020, 01, 01, 13, 14, 15, "2020-01-01 13:14:15"}, - {2020, 1, 31, 13, 14, 15, "2020-01-31 13:14:15"}, - {2020, 2, 1, 13, 14, 15, "2020-02-01 13:14:15"}, - {2020, 2, 28, 13, 14, 15, "2020-02-28 13:14:15"}, - {2020, 2, 29, 13, 14, 15, "2020-02-29 13:14:15"}, - } - - for _, v := range Tests { - output := CreateFromDateTime(v.year, v.month, v.day, v.hour, v.minute, v.second).ToDateTimeString() - - if output != v.output { - t.Fatalf("Expected %s, but got %s", v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).CreateFromDateTime(v.year, v.month, v.day, v.hour, v.minute, v.second).ToDateTimeString() - - if output != v.output { - t.Fatalf("Expected %s, but got %s", v.output, output) - } - } -} - -func TestCarbon_CreateFromDate(t *testing.T) { - clock := Now().ToTimeString() - - Tests := []struct { - year, month, day int // 输入参数 - output string // 期望输出值 - }{ - {2020, 01, 01, "2020-01-01 " + clock}, - {2020, 1, 31, "2020-01-31 " + clock}, - {2020, 2, 1, "2020-02-01 " + clock}, - {2020, 2, 28, "2020-02-28 " + clock}, - {2020, 2, 29, "2020-02-29 " + clock}, - } - - for _, v := range Tests { - output := CreateFromDate(v.year, v.month, v.day).ToDateTimeString() - - if output != v.output { - t.Fatalf("Expected %s, but got %s", v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).CreateFromDate(v.year, v.month, v.day).ToDateTimeString() - - if output != v.output { - t.Fatalf("Expected %s, but got %s", v.output, output) - } - } -} - -func TestCarbon_CreateFromTime(t *testing.T) { - date := Now().ToDateString() - - Tests := []struct { - hour, minute, second int // 输入参数 - output string // 期望输出值 - }{ - {0, 0, 0, date + " 00:00:00"}, - {00, 00, 15, date + " 00:00:15"}, - {00, 14, 15, date + " 00:14:15"}, - {13, 14, 15, date + " 13:14:15"}, - } - - for _, v := range Tests { - output := CreateFromTime(v.hour, v.minute, v.second).ToDateTimeString() - - if output != v.output { - t.Fatalf("Expected %s, but got %s", v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).CreateFromTime(v.hour, v.minute, v.second).ToDateTimeString() - - if output != v.output { - t.Fatalf("Expected %s, but got %s", v.output, output) - } - } -} - -func TestCarbon_Time2Carbon(t *testing.T) { - Tests := []struct { - time time.Time // // 输入参数 - output string // 期望输出值 - }{ - {time.Now(), time.Now().Format(DateTimeFormat)}, - } - - for _, v := range Tests { - output := Time2Carbon(v.time).ToDateTimeString() - - if output != v.output { - t.Fatalf("Expected %s, but got %s", v.output, output) - } - } -} - -func TestCarbon_Parse(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"", ""}, - {"0", ""}, - {"0000-00-00", ""}, - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:15"}, - {"20200805131415", "2020-08-05 13:14:15"}, - {"20200805", "2020-08-05 00:00:00"}, - {"2020-08-05", "2020-08-05 00:00:00"}, - {"2020-08-05T13:14:15+08:00", "2020-08-05 13:14:15"}, - {"12345678", ""}, // 异常情况 - } - - for _, v := range Tests { - output := Parse(v.input) - - if output.Error != nil { - fmt.Println("catch an exception in Parse():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input) - - if output.Error != nil { - fmt.Println("catch an exception in Parse():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) - } - } -} - -var ParseByFormatTests = []struct { - input string // 输入值 - format string // 输入参数 - output string // 期望输出值 -}{ - {"2020|08|05 13:14:15", "Y|m|d H:i:s", "2020-08-05 13:14:15"}, - {"It is 2020|08|05 13:14:15", "It is Y|m|d H:i:s", "2020-08-05 13:14:15"}, - {"今天是 2020年08月05日13时14分15秒", "今天是 Y年m月d日H时i分s秒", "2020-08-05 13:14:15"}, - {"12345678", "XXXX", ""}, // 异常情况 -} - -func TestCarbon_ParseByFormat1(t *testing.T) { - for _, v := range ParseByFormatTests { - output := ParseByFormat(v.input, v.format) - - if output.Error != nil { - fmt.Println("catch an exception in ParseByFormat():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) - } - } -} - -func TestCarbon_ParseByFormat2(t *testing.T) { - for _, v := range ParseByFormatTests { - output := SetTimezone("XXXX").ParseByFormat(v.input, v.format) - - if output.Error != nil { - fmt.Println("catch an exception in ParseByFormat():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) - } - } -} - -var ParseByLayoutTests = []struct { - input string // 输入值 - format string // 输入参数 - output string // 期望输出值 -}{ - {"2020|08|05 13:14:15", "2006|01|02 15:04:05", "2020-08-05 13:14:15"}, - {"It is 2020|08|05 13:14:15", "It is 2006|01|02 15:04:05", "2020-08-05 13:14:15"}, - {"今天是 2020年08月05日13时14分15秒", "今天是 2006年01月02日15时04分05秒", "2020-08-05 13:14:15"}, - {"12345678", "XXXX", ""}, // 异常情况 -} - -func TestCarbon_ParseByLayout1(t *testing.T) { - for _, v := range ParseByLayoutTests { - output := ParseByLayout(v.input, v.format) - - if output.Error != nil { - fmt.Println("catch an exception in ParseByLayout():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) - } - } -} - -func TestCarbon_ParseByLayout2(t *testing.T) { - for _, v := range ParseByLayoutTests { - output := SetTimezone("XXXX").ParseByLayout(v.input, v.format) - - if output.Error != nil { - fmt.Println("catch an exception in ParseByLayout():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) - } - } -} - -func TestCarbon_AddDuration(t *testing.T) { - Tests := []struct { - input string // 输入值 - duration string // 输入参数 - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", "10h", "2020-01-01 23:14:15"}, - {"2020-01-01 13:14:15", "10.5h", "2020-01-01 23:44:15"}, - - {"2020-01-01 13:14:15", "10m", "2020-01-01 13:24:15"}, - {"2020-01-01 13:14:15", "10.5m", "2020-01-01 13:24:45"}, - - {"2020-01-01 13:14:15", "10s", "2020-01-01 13:14:25"}, - {"2020-01-01 13:14:15", "10.5s", "2020-01-01 13:14:25"}, - - {"2020-01-01 13:14:15", "XXXX", ""}, // 异常情况 - } - - for _, v := range Tests { - output := Parse(v.input).AddDuration(v.duration) - - if output.Error != nil { - fmt.Println("catch an exception in AddDuration():", output.Error) - } else { - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) - } - } - } - - for _, v := range Tests { - output := SetTimezone("XXXX").Parse(v.input).AddDuration(v.duration) - - if output.Error != nil { - fmt.Println("catch an exception in AddDuration():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) - } - } -} - -func TestCarbon_SubDuration(t *testing.T) { - Tests := []struct { - input string // 输入值 - duration string // 输入参数 - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", "10h", "2020-01-01 03:14:15"}, - {"2020-01-01 13:14:15", "10.5h", "2020-01-01 02:44:15"}, - - {"2020-01-01 13:14:15", "10m", "2020-01-01 13:04:15"}, - {"2020-01-01 13:14:15", "10.5m", "2020-01-01 13:03:45"}, - - {"2020-01-01 13:14:15", "10s", "2020-01-01 13:14:05"}, - {"2020-01-01 13:14:15", "10.5s", "2020-01-01 13:14:04"}, - - {"2020-01-01 13:14:15 XXXX", "10h", ""}, // 异常情况 - {"2020-01-01 13:14:15", "10x", ""}, // 异常情况 - } - - for _, v := range Tests { - output := Parse(v.input).SubDuration(v.duration) - - if output.Error != nil { - fmt.Println("catch an exception in SubDuration():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) - } - } - - for _, v := range Tests { - output := SetTimezone("XXXX").Parse(v.input).SubDuration(v.duration) - - if output.Error != nil { - fmt.Println("catch an exception in SubDuration():", output.Error) - return - } - - if output.ToDateTimeString() != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) - } - } -} - -func TestCarbon_AddCenturies(t *testing.T) { - type Test struct { - input string // 输入值 - centuries int // 输入参数 - output string // 期望输出值 - } - - Tests := []Test{ - {"2020-01-01", 3, "2320-01-01"}, - {"2020-01-31", 3, "2320-01-31"}, - {"2020-02-01", 3, "2320-02-01"}, - {"2020-02-28", 3, "2320-02-28"}, - {"2020-02-29", 3, "2320-02-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddCenturies(v.centuries).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddCenturies(v.centuries).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddCenturiesNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - centuries int // 输入参数 - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2320-01-01"}, - {"2020-01-31", 3, "2320-01-31"}, - {"2020-02-01", 3, "2320-02-01"}, - {"2020-02-28", 3, "2320-02-28"}, - {"2020-02-29", 3, "2320-02-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddCenturiesNoOverflow(v.centuries).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddCenturiesNoOverflow(v.centuries).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubCenturies(t *testing.T) { - type Test struct { - input string // 输入值 - centuries int // 输入参数 - output string // 期望输出值 - } - - Tests := []Test{ - {"2020-01-01", 3, "1720-01-01"}, - {"2020-01-31", 3, "1720-01-31"}, - {"2020-02-01", 3, "1720-02-01"}, - {"2020-02-28", 3, "1720-02-28"}, - {"2020-02-29", 3, "1720-02-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubCenturies(v.centuries).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubCenturies(v.centuries).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubCenturiesNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - centuries int - output string // 期望输出值 - }{ - {"2020-01-01", 3, "1720-01-01"}, - {"2020-01-31", 3, "1720-01-31"}, - {"2020-02-01", 3, "1720-02-01"}, - {"2020-02-28", 3, "1720-02-28"}, - {"2020-02-29", 3, "1720-02-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubCenturiesNoOverflow(v.centuries).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubCenturiesNoOverflow(v.centuries).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddCentury(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2120-01-01"}, - {"2020-01-31", "2120-01-31"}, - {"2020-02-01", "2120-02-01"}, - {"2020-02-28", "2120-02-28"}, - {"2020-02-29", "2120-02-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddCentury().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddCentury().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddCenturyNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2120-01-01"}, - {"2020-01-31", "2120-01-31"}, - {"2020-02-01", "2120-02-01"}, - {"2020-02-28", "2120-02-28"}, - {"2020-02-29", "2120-02-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddCenturyNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddCenturyNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubCentury(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "1920-01-01"}, - {"2020-01-31", "1920-01-31"}, - {"2020-02-01", "1920-02-01"}, - {"2020-02-28", "1920-02-28"}, - {"2020-02-29", "1920-02-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubCentury().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubCentury().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubCenturyNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "1920-01-01"}, - {"2020-01-31", "1920-01-31"}, - {"2020-02-01", "1920-02-01"}, - {"2020-02-28", "1920-02-28"}, - {"2020-02-29", "1920-02-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubCenturyNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Expected %s, but got %s", v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubCenturyNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddYears(t *testing.T) { - Tests := []struct { - input string // 输入值 - years int // 输入参数 - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2023-01-01"}, - {"2020-01-31", 3, "2023-01-31"}, - {"2020-02-01", 3, "2023-02-01"}, - {"2020-02-28", 3, "2023-02-28"}, - {"2020-02-29", 3, "2023-03-01"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddYears(v.years).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddYears(v.years).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddYearsNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - years int // 输入参数 - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2023-01-01"}, - {"2020-01-31", 3, "2023-01-31"}, - {"2020-02-01", 3, "2023-02-01"}, - {"2020-02-28", 3, "2023-02-28"}, - {"2020-02-29", 3, "2023-02-28"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddYearsNoOverflow(v.years).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddYearsNoOverflow(v.years).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubYears(t *testing.T) { - type Test struct { - input string // 输入值 - years int // 输入参数 - output string // 期望输出值 - } - - Tests := []Test{ - {"2020-01-01", 3, "2017-01-01"}, - {"2020-01-31", 3, "2017-01-31"}, - {"2020-02-01", 3, "2017-02-01"}, - {"2020-02-28", 3, "2017-02-28"}, - {"2020-02-29", 3, "2017-03-01"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubYears(v.years).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubYears(v.years).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubYearsNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - years int - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2017-01-01"}, - {"2020-01-31", 3, "2017-01-31"}, - {"2020-02-01", 3, "2017-02-01"}, - {"2020-02-28", 3, "2017-02-28"}, - {"2020-02-29", 3, "2017-02-28"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubYearsNoOverflow(v.years).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubYearsNoOverflow(v.years).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2021-01-01"}, - {"2020-01-31", "2021-01-31"}, - {"2020-02-01", "2021-02-01"}, - {"2020-02-28", "2021-02-28"}, - {"2020-02-29", "2021-03-01"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddYear().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddYear().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddYearNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2021-01-01"}, - {"2020-01-31", "2021-01-31"}, - {"2020-02-01", "2021-02-01"}, - {"2020-02-28", "2021-02-28"}, - {"2020-02-29", "2021-02-28"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddYearNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddYearNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2019-01-01"}, - {"2020-01-31", "2019-01-31"}, - {"2020-02-01", "2019-02-01"}, - {"2020-02-28", "2019-02-28"}, - {"2020-02-29", "2019-03-01"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubYear().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubYear().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubYearNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2019-01-01"}, - {"2020-01-31", "2019-01-31"}, - {"2020-02-01", "2019-02-01"}, - {"2020-02-28", "2019-02-28"}, - {"2020-02-29", "2019-02-28"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubYearNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Expected %s, but got %s", v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubYearNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddQuarters(t *testing.T) { - Tests := []struct { - input string // 输入值 - quarters int - output string // 期望输出值 - }{ - {"2019-08-01", 2, "2020-02-01"}, - {"2019-08-31", 2, "2020-03-02"}, - {"2020-01-01", 2, "2020-07-01"}, - {"2020-02-28", 2, "2020-08-28"}, - {"2020-02-29", 2, "2020-08-29"}, - {"2020-08-31", 2, "2021-03-03"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddQuarters(v.quarters).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddQuarters(v.quarters).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddQuartersNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - quarters int - output string // 期望输出值 - }{ - {"2019-08-01", 2, "2020-02-01"}, - {"2019-08-31", 2, "2020-02-29"}, - {"2020-01-01", 2, "2020-07-01"}, - {"2020-02-28", 2, "2020-08-28"}, - {"2020-02-29", 2, "2020-08-29"}, - {"2020-08-31", 2, "2021-02-28"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddQuartersNoOverflow(v.quarters).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddQuartersNoOverflow(v.quarters).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubQuarters(t *testing.T) { - Tests := []struct { - input string // 输入值 - quarters int - output string // 期望输出值 - }{ - {"2019-08-01", 2, "2019-02-01"}, - {"2019-08-31", 2, "2019-03-03"}, - {"2020-01-01", 2, "2019-07-01"}, - {"2020-02-28", 2, "2019-08-28"}, - {"2020-02-29", 2, "2019-08-29"}, - {"2020-08-31", 2, "2020-03-02"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubQuarters(v.quarters).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubQuarters(v.quarters).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubQuartersNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - quarters int - output string // 期望输出值 - }{ - {"2019-08-01", 2, "2019-02-01"}, - {"2019-08-31", 2, "2019-02-28"}, - {"2020-01-01", 2, "2019-07-01"}, - {"2020-02-28", 2, "2019-08-28"}, - {"2020-02-29", 2, "2019-08-29"}, - {"2020-08-31", 2, "2020-02-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubQuartersNoOverflow(v.quarters).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubQuartersNoOverflow(v.quarters).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddQuarter(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2019-11-01", "2020-02-01"}, - {"2019-11-30", "2020-03-01"}, - {"2020-02-28", "2020-05-28"}, - {"2020-02-29", "2020-05-29"}, - {"2020-08-31", "2020-12-01"}, - {"2020-11-01", "2021-02-01"}, - {"2020-11-30", "2021-03-02"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddQuarter().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddQuarter().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddQuarterNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2019-11-01", "2020-02-01"}, - {"2019-11-30", "2020-02-29"}, - {"2020-02-28", "2020-05-28"}, - {"2020-02-29", "2020-05-29"}, - {"2020-08-31", "2020-11-30"}, - {"2020-11-01", "2021-02-01"}, - {"2020-11-30", "2021-02-28"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddQuarterNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddQuarterNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubQuarter(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2019-04-01", "2019-01-01"}, - {"2019-04-30", "2019-01-30"}, - {"2020-05-01", "2020-02-01"}, - {"2020-05-31", "2020-03-02"}, - {"2020-04-01", "2020-01-01"}, - {"2020-04-30", "2020-01-30"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubQuarter().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubQuarter().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubQuarterNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2019-04-01", "2019-01-01"}, - {"2019-04-30", "2019-01-30"}, - {"2020-05-01", "2020-02-01"}, - {"2020-05-31", "2020-02-29"}, - {"2020-04-01", "2020-01-01"}, - {"2020-04-30", "2020-01-30"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubQuarterNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubQuarterNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddMonths(t *testing.T) { - Tests := []struct { - input string // 输入值 - months int - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2020-04-01"}, - {"2020-01-31", 3, "2020-05-01"}, - {"2020-02-01", 3, "2020-05-01"}, - {"2020-02-28", 3, "2020-05-28"}, - {"2020-02-29", 3, "2020-05-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddMonths(v.months).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddMonths(v.months).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddMonthsNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - months int - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2020-04-01"}, - {"2020-01-31", 3, "2020-04-30"}, - {"2020-02-01", 3, "2020-05-01"}, - {"2020-02-28", 3, "2020-05-28"}, - {"2020-02-29", 3, "2020-05-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddMonthsNoOverflow(v.months).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddMonthsNoOverflow(v.months).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubMonths(t *testing.T) { - Tests := []struct { - input string // 输入值 - months int - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2019-10-01"}, - {"2020-01-31", 3, "2019-10-31"}, - {"2020-02-01", 3, "2019-11-01"}, - {"2020-02-28", 3, "2019-11-28"}, - {"2020-02-29", 3, "2019-11-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubMonths(v.months).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubMonths(v.months).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubMonthsNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - months int - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2019-10-01"}, - {"2020-01-31", 3, "2019-10-31"}, - {"2020-02-01", 3, "2019-11-01"}, - {"2020-02-28", 3, "2019-11-28"}, - {"2020-02-29", 3, "2019-11-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubMonthsNoOverflow(v.months).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubMonthsNoOverflow(v.months).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddMonth(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2020-02-01"}, - {"2020-01-31", "2020-03-02"}, - {"2020-02-01", "2020-03-01"}, - {"2020-02-28", "2020-03-28"}, - {"2020-02-29", "2020-03-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddMonth().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddMonth().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddMonthNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2020-02-01"}, - {"2020-01-31", "2020-02-29"}, - {"2020-02-01", "2020-03-01"}, - {"2020-02-28", "2020-03-28"}, - {"2020-02-29", "2020-03-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddMonthNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddMonthNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubMonth(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2019-12-01"}, - {"2020-01-31", "2019-12-31"}, - {"2020-02-01", "2020-01-01"}, - {"2020-02-28", "2020-01-28"}, - {"2020-02-29", "2020-01-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubMonth().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubMonth().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubMonthNoOverflow(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2019-12-01"}, - {"2020-01-31", "2019-12-31"}, - {"2020-02-01", "2020-01-01"}, - {"2020-02-28", "2020-01-28"}, - {"2020-02-29", "2020-01-29"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubMonthNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubMonthNoOverflow().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddWeeks(t *testing.T) { - Tests := []struct { - input string // 输入值 - weeks int - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2020-01-22"}, - {"2020-01-31", 3, "2020-02-21"}, - {"2020-02-01", 3, "2020-02-22"}, - {"2020-02-28", 3, "2020-03-20"}, - {"2020-02-29", 3, "2020-03-21"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddWeeks(v.weeks).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddWeeks(v.weeks).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubWeeks(t *testing.T) { - Tests := []struct { - input string // 输入值 - weeks int - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2019-12-11"}, - {"2020-01-31", 3, "2020-01-10"}, - {"2020-02-01", 3, "2020-01-11"}, - {"2020-02-28", 3, "2020-02-07"}, - {"2020-02-29", 3, "2020-02-08"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubWeeks(v.weeks).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubWeeks(v.weeks).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddWeek(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2020-01-08"}, - {"2020-01-31", "2020-02-07"}, - {"2020-02-01", "2020-02-08"}, - {"2020-02-28", "2020-03-06"}, - {"2020-02-29", "2020-03-07"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddWeek().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddWeek().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubWeek(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2019-12-25"}, - {"2020-01-31", "2020-01-24"}, - {"2020-02-01", "2020-01-25"}, - {"2020-02-28", "2020-02-21"}, - {"2020-02-29", "2020-02-22"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubWeek().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubWeek().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddDays(t *testing.T) { - Tests := []struct { - input string // 输入值 - days int - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2020-01-04"}, - {"2020-01-31", 3, "2020-02-03"}, - {"2020-02-01", 3, "2020-02-04"}, - {"2020-02-28", 3, "2020-03-02"}, - {"2020-02-29", 3, "2020-03-03"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddDays(v.days).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddDays(v.days).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubDays(t *testing.T) { - Tests := []struct { - input string // 输入值 - days int - output string // 期望输出值 - }{ - {"2020-01-01", 3, "2019-12-29"}, - {"2020-01-31", 3, "2020-01-28"}, - {"2020-02-01", 3, "2020-01-29"}, - {"2020-02-28", 3, "2020-02-25"}, - {"2020-02-29", 3, "2020-02-26"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubDays(v.days).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubDays(v.days).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddDay(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2020-01-02"}, - {"2020-01-31", "2020-02-01"}, - {"2020-02-01", "2020-02-02"}, - {"2020-02-28", "2020-02-29"}, - {"2020-02-29", "2020-03-01"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddDay().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddDay().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubDay(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01", "2019-12-31"}, - {"2020-01-31", "2020-01-30"}, - {"2020-02-01", "2020-01-31"}, - {"2020-02-28", "2020-02-27"}, - {"2020-02-29", "2020-02-28"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubDay().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubDay().ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddHours(t *testing.T) { - Tests := []struct { - input string // 输入值 - hours int - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", 3, "2020-01-01 16:14:15"}, - {"2020-01-31 13:14:15", 3, "2020-01-31 16:14:15"}, - {"2020-02-01 13:14:15", 3, "2020-02-01 16:14:15"}, - {"2020-02-28 13:14:15", 3, "2020-02-28 16:14:15"}, - {"2020-02-29 13:14:15", 3, "2020-02-29 16:14:15"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddHours(v.hours).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddHours(v.hours).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubHours(t *testing.T) { - Tests := []struct { - input string // 输入值 - hours int - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", 3, "2020-01-01 10:14:15"}, - {"2020-01-31 13:14:15", 3, "2020-01-31 10:14:15"}, - {"2020-02-01 13:14:15", 3, "2020-02-01 10:14:15"}, - {"2020-02-28 13:14:15", 3, "2020-02-28 10:14:15"}, - {"2020-02-29 13:14:15", 3, "2020-02-29 10:14:15"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubHours(v.hours).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubHours(v.hours).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddHour(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", "2020-01-01 14:14:15"}, - {"2020-01-31 13:14:15", "2020-01-31 14:14:15"}, - {"2020-02-01 13:14:15", "2020-02-01 14:14:15"}, - {"2020-02-28 13:14:15", "2020-02-28 14:14:15"}, - {"2020-02-29 13:14:15", "2020-02-29 14:14:15"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddHour().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddHour().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubHour(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", "2020-01-01 12:14:15"}, - {"2020-01-31 13:14:15", "2020-01-31 12:14:15"}, - {"2020-02-01 13:14:15", "2020-02-01 12:14:15"}, - {"2020-02-28 13:14:15", "2020-02-28 12:14:15"}, - {"2020-02-29 13:14:15", "2020-02-29 12:14:15"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubHour().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubHour().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddMinutes(t *testing.T) { - Tests := []struct { - input string // 输入值 - minutes int - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", 3, "2020-01-01 13:17:15"}, - {"2020-01-31 13:14:15", 3, "2020-01-31 13:17:15"}, - {"2020-02-01 13:14:15", 3, "2020-02-01 13:17:15"}, - {"2020-02-28 13:14:15", 3, "2020-02-28 13:17:15"}, - {"2020-02-29 13:14:15", 3, "2020-02-29 13:17:15"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddMinutes(v.minutes).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddMinutes(v.minutes).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubMinutes(t *testing.T) { - Tests := []struct { - input string // 输入值 - minutes int - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", 3, "2020-01-01 13:11:15"}, - {"2020-01-31 13:14:15", 3, "2020-01-31 13:11:15"}, - {"2020-02-01 13:14:15", 3, "2020-02-01 13:11:15"}, - {"2020-02-28 13:14:15", 3, "2020-02-28 13:11:15"}, - {"2020-02-29 13:14:15", 3, "2020-02-29 13:11:15"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubMinutes(v.minutes).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubMinutes(v.minutes).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddMinute(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", "2020-01-01 13:15:15"}, - {"2020-01-31 13:14:15", "2020-01-31 13:15:15"}, - {"2020-02-01 13:14:15", "2020-02-01 13:15:15"}, - {"2020-02-28 13:14:15", "2020-02-28 13:15:15"}, - {"2020-02-29 13:14:15", "2020-02-29 13:15:15"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddMinute().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddMinute().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubMinute(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", "2020-01-01 13:13:15"}, - {"2020-01-31 13:14:15", "2020-01-31 13:13:15"}, - {"2020-02-01 13:14:15", "2020-02-01 13:13:15"}, - {"2020-02-28 13:14:15", "2020-02-28 13:13:15"}, - {"2020-02-29 13:14:15", "2020-02-29 13:13:15"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubMinute().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubMinute().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddSeconds(t *testing.T) { - Tests := []struct { - input string // 输入值 - seconds int - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", 3, "2020-01-01 13:14:18"}, - {"2020-01-31 13:14:15", 3, "2020-01-31 13:14:18"}, - {"2020-02-01 13:14:15", 3, "2020-02-01 13:14:18"}, - {"2020-02-28 13:14:15", 3, "2020-02-28 13:14:18"}, - {"2020-02-29 13:14:15", 3, "2020-02-29 13:14:18"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddSeconds(v.seconds).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddSeconds(v.seconds).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubSeconds(t *testing.T) { - Tests := []struct { - input string // 输入值 - seconds int - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", 3, "2020-01-01 13:14:12"}, - {"2020-01-31 13:14:15", 3, "2020-01-31 13:14:12"}, - {"2020-02-01 13:14:15", 3, "2020-02-01 13:14:12"}, - {"2020-02-28 13:14:15", 3, "2020-02-28 13:14:12"}, - {"2020-02-29 13:14:15", 3, "2020-02-29 13:14:12"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubSeconds(v.seconds).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubSeconds(v.seconds).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_AddSecond(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", "2020-01-01 13:14:16"}, - {"2020-01-31 13:14:15", "2020-01-31 13:14:16"}, - {"2020-02-01 13:14:15", "2020-02-01 13:14:16"}, - {"2020-02-28 13:14:15", "2020-02-28 13:14:16"}, - {"2020-02-29 13:14:15", "2020-02-29 13:14:16"}, - } - - for _, v := range Tests { - output := Parse(v.input).AddSecond().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).AddSecond().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_SubSecond(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-01-01 13:14:15", "2020-01-01 13:14:14"}, - {"2020-01-31 13:14:15", "2020-01-31 13:14:14"}, - {"2020-02-01 13:14:15", "2020-02-01 13:14:14"}, - {"2020-02-28 13:14:15", "2020-02-28 13:14:14"}, - {"2020-02-29 13:14:15", "2020-02-29 13:14:14"}, - } - - for _, v := range Tests { - output := Parse(v.input).SubSecond().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } - - for _, v := range Tests { - output := SetTimezone(PRC).Parse(v.input).SubSecond().ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } + t.Errorf("Expected %s, but got %s", expected, output) } } diff --git a/comparer.go b/comparer.go new file mode 100755 index 0000000..b9ab69d --- /dev/null +++ b/comparer.go @@ -0,0 +1,243 @@ +package carbon + +import "time" + +// IsZero 是否是零值 +func (c Carbon) IsZero() bool { + return c.Time.In(c.Loc).IsZero() +} + +// IsNow 是否是当前时间 +func (c Carbon) IsNow() bool { + return c.ToTimestamp() == c.Now().ToTimestamp() +} + +// IsFuture 是否是未来时间 +func (c Carbon) IsFuture() bool { + return c.ToTimestamp() > c.Now().ToTimestamp() +} + +// IsPast 是否是过去时间 +func (c Carbon) IsPast() bool { + return c.ToTimestamp() < c.Now().ToTimestamp() +} + +// IsLeapYear 是否是闰年 +func (c Carbon) IsLeapYear() bool { + year := c.Time.In(c.Loc).Year() + if year%400 == 0 || (year%4 == 0 && year%100 != 0) { + return true + } + return false +} + +// IsLongYear 是否是长年 +func (c Carbon) IsLongYear() bool { + t := time.Date(c.Year(), time.December, 31, 0, 0, 0, 0, c.Loc) + _, w := t.ISOWeek() + return w == weeksPerLongYear +} + +// IsJanuary 是否是一月 +func (c Carbon) IsJanuary() bool { + return c.Time.In(c.Loc).Month() == time.January +} + +// IsMonday 是否是二月 +func (c Carbon) IsFebruary() bool { + return c.Time.In(c.Loc).Month() == time.February +} + +// IsMarch 是否是三月 +func (c Carbon) IsMarch() bool { + return c.Time.In(c.Loc).Month() == time.March +} + +// IsApril 是否是四月 +func (c Carbon) IsApril() bool { + return c.Time.In(c.Loc).Month() == time.April +} + +// IsMay 是否是五月 +func (c Carbon) IsMay() bool { + return c.Time.In(c.Loc).Month() == time.May +} + +// IsJune 是否是六月 +func (c Carbon) IsJune() bool { + return c.Time.In(c.Loc).Month() == time.June +} + +// IsJuly 是否是七月 +func (c Carbon) IsJuly() bool { + return c.Time.In(c.Loc).Month() == time.July +} + +// IsAugust 是否是八月 +func (c Carbon) IsAugust() bool { + return c.Time.In(c.Loc).Month() == time.August +} + +// IsSeptember 是否是九月 +func (c Carbon) IsSeptember() bool { + return c.Time.In(c.Loc).Month() == time.September +} + +// IsOctober 是否是十月 +func (c Carbon) IsOctober() bool { + return c.Time.In(c.Loc).Month() == time.October +} + +// IsNovember 是否是十一月 +func (c Carbon) IsNovember() bool { + return c.Time.In(c.Loc).Month() == time.November +} + +// IsDecember 是否是十二月 +func (c Carbon) IsDecember() bool { + return c.Time.In(c.Loc).Month() == time.December +} + +// IsMonday 是否是周一 +func (c Carbon) IsMonday() bool { + return c.Time.In(c.Loc).Weekday() == time.Monday +} + +// IsTuesday 是否是周二 +func (c Carbon) IsTuesday() bool { + return c.Time.In(c.Loc).Weekday() == time.Tuesday +} + +// IsWednesday 是否是周三 +func (c Carbon) IsWednesday() bool { + return c.Time.In(c.Loc).Weekday() == time.Wednesday +} + +// IsThursday 是否是周四 +func (c Carbon) IsThursday() bool { + return c.Time.In(c.Loc).Weekday() == time.Thursday +} + +// IsFriday 是否是周五 +func (c Carbon) IsFriday() bool { + return c.Time.In(c.Loc).Weekday() == time.Friday +} + +// IsSaturday 是否是周六 +func (c Carbon) IsSaturday() bool { + return c.Time.In(c.Loc).Weekday() == time.Saturday +} + +// IsSunday 是否是周日 +func (c Carbon) IsSunday() bool { + return c.Time.In(c.Loc).Weekday() == time.Sunday +} + +// IsWeekday 是否是工作日 +func (c Carbon) IsWeekday() bool { + return !c.IsSaturday() && !c.IsSunday() +} + +// IsWeekend 是否是周末 +func (c Carbon) IsWeekend() bool { + return c.IsSaturday() || c.IsSunday() +} + +// IsYesterday 是否是昨天 +func (c Carbon) IsYesterday() bool { + return c.ToDateString() == Now().SubDay().ToDateString() +} + +// IsToday 是否是今天 +func (c Carbon) IsToday() bool { + return c.ToDateString() == c.Now().ToDateString() +} + +// IsTomorrow 是否是明天 +func (c Carbon) IsTomorrow() bool { + return c.ToDateString() == Now().AddDay().ToDateString() +} + +// Compare 时间比较 +func (c Carbon) Compare(operator string, t Carbon) bool { + switch operator { + case "=": + return c.Eq(t) + case "<>": + return !c.Eq(t) + case "!=": + return !c.Eq(t) + case ">": + return c.Gt(t) + case ">=": + return c.Gte(t) + case "<": + return c.Lt(t) + case "<=": + return c.Lte(t) + } + + return false +} + +// Gt 大于 +func (c Carbon) Gt(t Carbon) bool { + return c.Time.After(t.Time) +} + +// Lt 小于 +func (c Carbon) Lt(t Carbon) bool { + return c.Time.Before(t.Time) +} + +// Eq 等于 +func (c Carbon) Eq(t Carbon) bool { + return c.Time.Equal(t.Time) +} + +// Ne 不等于 +func (c Carbon) Ne(t Carbon) bool { + return !c.Eq(t) +} + +// Gte 大于等于 +func (c Carbon) Gte(t Carbon) bool { + return c.Gt(t) || c.Eq(t) +} + +// Lte 小于等于 +func (c Carbon) Lte(t Carbon) bool { + return c.Lt(t) || c.Eq(t) +} + +// Between 是否在两个时间之间(不包括这两个时间) +func (c Carbon) Between(start Carbon, end Carbon) bool { + if c.Gt(start) && c.Lt(end) { + return true + } + return false +} + +// BetweenIncludedStartTime 是否在两个时间之间(包括开始时间) +func (c Carbon) BetweenIncludedStartTime(start Carbon, end Carbon) bool { + if c.Gte(start) && c.Lt(end) { + return true + } + return false +} + +// BetweenIncludedEndTime 是否在两个时间之间(包括结束时间) +func (c Carbon) BetweenIncludedEndTime(start Carbon, end Carbon) bool { + if c.Gt(start) && c.Lte(end) { + return true + } + return false +} + +// BetweenIncludedBoth 是否在两个时间之间(包括这两个时间) +func (c Carbon) BetweenIncludedBoth(start Carbon, end Carbon) bool { + if c.Gte(start) && c.Lte(end) { + return true + } + return false +} diff --git a/comparer_test.go b/comparer_test.go new file mode 100755 index 0000000..d50d63c --- /dev/null +++ b/comparer_test.go @@ -0,0 +1,1357 @@ +package carbon + +import ( + "testing" +) + +func TestCarbon_IsZero(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"0000-00-00 00:00:00", true}, + {"0000-00-00", true}, + {"2020-08-05 00:00:00", false}, + {"2020-08-05", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsZero() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsNow(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"0000-00-00 00:00:00", false}, + {Tomorrow().ToDateTimeString(), false}, + {Now().ToDateTimeString(), true}, + {Yesterday().ToDateTimeString(), false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsNow() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsFuture(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"0000-00-00 00:00:00", false}, + {Tomorrow().ToDateTimeString(), true}, + {Now().ToDateTimeString(), false}, + {Yesterday().ToDateTimeString(), false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsFuture() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsPast(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"0000-00-00 00:00:00", true}, + {Tomorrow().ToDateTimeString(), false}, + {Now().ToDateTimeString(), false}, + {Yesterday().ToDateTimeString(), true}, + } + + for _, v := range Tests { + output := Parse(v.input).IsPast() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsLeapYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2016-01-01", true}, + {"2017-01-01", false}, + {"2018-01-01", false}, + {"2019-01-01", false}, + {"2020-01-01", true}, + } + + for _, v := range Tests { + output := Parse(v.input).IsLeapYear() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsLongYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2015-01-01", true}, + {"2016-01-01", false}, + {"2017-01-01", false}, + {"2018-01-01", false}, + {"2019-01-01", false}, + {"2020-01-01", true}, + } + + for _, v := range Tests { + output := Parse(v.input).IsLongYear() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsJanuary(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", true}, + {"2020-02-01", false}, + {"2020-03-01", false}, + {"2020-04-01", false}, + {"2020-05-01", false}, + {"2020-06-01", false}, + {"2020-07-01", false}, + {"2020-08-01", false}, + {"2020-09-01", false}, + {"2020-10-01", false}, + {"2020-11-01", false}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsJanuary() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsFebruary(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", true}, + {"2020-03-01", false}, + {"2020-04-01", false}, + {"2020-05-01", false}, + {"2020-06-01", false}, + {"2020-07-01", false}, + {"2020-08-01", false}, + {"2020-09-01", false}, + {"2020-10-01", false}, + {"2020-11-01", false}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsFebruary() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsMarch(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", false}, + {"2020-03-01", true}, + {"2020-04-01", false}, + {"2020-05-01", false}, + {"2020-06-01", false}, + {"2020-07-01", false}, + {"2020-08-01", false}, + {"2020-09-01", false}, + {"2020-10-01", false}, + {"2020-11-01", false}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsMarch() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsApril(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", false}, + {"2020-03-01", false}, + {"2020-04-01", true}, + {"2020-05-01", false}, + {"2020-06-01", false}, + {"2020-07-01", false}, + {"2020-08-01", false}, + {"2020-09-01", false}, + {"2020-10-01", false}, + {"2020-11-01", false}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsApril() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsMay(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", false}, + {"2020-03-01", false}, + {"2020-04-01", false}, + {"2020-05-01", true}, + {"2020-06-01", false}, + {"2020-07-01", false}, + {"2020-08-01", false}, + {"2020-09-01", false}, + {"2020-10-01", false}, + {"2020-11-01", false}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsMay() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsJune(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", false}, + {"2020-03-01", false}, + {"2020-04-01", false}, + {"2020-05-01", false}, + {"2020-06-01", true}, + {"2020-07-01", false}, + {"2020-08-01", false}, + {"2020-09-01", false}, + {"2020-10-01", false}, + {"2020-11-01", false}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsJune() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsJuly(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", false}, + {"2020-03-01", false}, + {"2020-04-01", false}, + {"2020-05-01", false}, + {"2020-06-01", false}, + {"2020-07-01", true}, + {"2020-08-01", false}, + {"2020-09-01", false}, + {"2020-10-01", false}, + {"2020-11-01", false}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsJuly() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsAugust(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", false}, + {"2020-03-01", false}, + {"2020-04-01", false}, + {"2020-05-01", false}, + {"2020-06-01", false}, + {"2020-07-01", false}, + {"2020-08-01", true}, + {"2020-09-01", false}, + {"2020-10-01", false}, + {"2020-11-01", false}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsAugust() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsSeptember(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", false}, + {"2020-03-01", false}, + {"2020-04-01", false}, + {"2020-05-01", false}, + {"2020-06-01", false}, + {"2020-07-01", false}, + {"2020-08-01", false}, + {"2020-09-01", true}, + {"2020-10-01", false}, + {"2020-11-01", false}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsSeptember() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsOctober(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", false}, + {"2020-03-01", false}, + {"2020-04-01", false}, + {"2020-05-01", false}, + {"2020-06-01", false}, + {"2020-07-01", false}, + {"2020-08-01", false}, + {"2020-09-01", false}, + {"2020-10-01", true}, + {"2020-11-01", false}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsOctober() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsNovember(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", false}, + {"2020-03-01", false}, + {"2020-04-01", false}, + {"2020-05-01", false}, + {"2020-06-01", false}, + {"2020-07-01", false}, + {"2020-08-01", false}, + {"2020-09-01", false}, + {"2020-10-01", false}, + {"2020-11-01", true}, + {"2020-12-01", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsNovember() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsDecember(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-01-01", false}, + {"2020-02-01", false}, + {"2020-03-01", false}, + {"2020-04-01", false}, + {"2020-05-01", false}, + {"2020-06-01", false}, + {"2020-07-01", false}, + {"2020-08-01", false}, + {"2020-09-01", false}, + {"2020-10-01", false}, + {"2020-11-01", false}, + {"2020-12-01", true}, + } + + for _, v := range Tests { + output := Parse(v.input).IsDecember() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsMonday(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-10-05", true}, + {"2020-10-06", false}, + {"2020-10-07", false}, + {"2020-10-08", false}, + {"2020-10-09", false}, + {"2020-10-10", false}, + {"2020-10-11", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsMonday() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsTuesday(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-10-05", false}, + {"2020-10-06", true}, + {"2020-10-07", false}, + {"2020-10-08", false}, + {"2020-10-09", false}, + {"2020-10-10", false}, + {"2020-10-11", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsTuesday() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsWednesday(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-10-05", false}, + {"2020-10-06", false}, + {"2020-10-07", true}, + {"2020-10-08", false}, + {"2020-10-09", false}, + {"2020-10-10", false}, + {"2020-10-11", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsWednesday() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsThursday(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-10-05", false}, + {"2020-10-06", false}, + {"2020-10-07", false}, + {"2020-10-08", true}, + {"2020-10-09", false}, + {"2020-10-10", false}, + {"2020-10-11", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsThursday() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsFriday(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-10-05", false}, + {"2020-10-06", false}, + {"2020-10-07", false}, + {"2020-10-08", false}, + {"2020-10-09", true}, + {"2020-10-10", false}, + {"2020-10-11", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsFriday() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsSaturday(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-10-05", false}, + {"2020-10-06", false}, + {"2020-10-07", false}, + {"2020-10-08", false}, + {"2020-10-09", false}, + {"2020-10-10", true}, + {"2020-10-11", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsSaturday() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsSunday(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-10-05", false}, + {"2020-10-06", false}, + {"2020-10-07", false}, + {"2020-10-08", false}, + {"2020-10-09", false}, + {"2020-10-10", false}, + {"2020-10-11", true}, + } + + for _, v := range Tests { + output := Parse(v.input).IsSunday() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsWeekday(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-10-05", true}, + {"2020-10-06", true}, + {"2020-10-07", true}, + {"2020-10-08", true}, + {"2020-10-09", true}, + {"2020-10-10", false}, + {"2020-10-11", false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsWeekday() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsWeekend(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"2020-10-05", false}, + {"2020-10-06", false}, + {"2020-10-07", false}, + {"2020-10-08", false}, + {"2020-10-09", false}, + {"2020-10-10", true}, + {"2020-10-11", true}, + } + + for _, v := range Tests { + output := Parse(v.input).IsWeekend() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsYesterday(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {Now().ToDateTimeString(), false}, + {Yesterday().ToDateTimeString(), true}, + {Tomorrow().ToDateTimeString(), false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsYesterday() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsToday(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {Now().ToDateTimeString(), true}, + {Yesterday().ToDateTimeString(), false}, + {Tomorrow().ToDateTimeString(), false}, + } + + for _, v := range Tests { + output := Parse(v.input).IsToday() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_IsTomorrow(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {Now().ToDateTimeString(), false}, + {Yesterday().ToDateTimeString(), false}, + {Tomorrow().ToDateTimeString(), true}, + } + + for _, v := range Tests { + output := Parse(v.input).IsTomorrow() + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s, expected %s, but got %s\n", v.input, expected, reality) + } + } +} + +func TestCarbon_Compare(t *testing.T) { + now := Now() + tomorrow := Tomorrow() + yesterday := Yesterday() + Tests := []struct { + input Carbon // 输入值 + operator string // 输入参数 + time Carbon // 输入参数 + output bool // 期望输出值 + }{ + {now, ">", yesterday, true}, + {now, "<", yesterday, false}, + {now, "<", tomorrow, true}, + {now, ">", tomorrow, false}, + {now, "=", now, true}, + {now, ">=", now, true}, + {now, "<=", now, true}, + {now, "!=", now, false}, + {now, "<>", now, false}, + {now, "!=", yesterday, true}, + {now, "<>", yesterday, true}, + {now, "+", yesterday, false}, + } + + for _, v := range Tests { + output := v.input.Compare(v.operator, v.time) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s %s %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.operator, v.time.ToDateTimeString(), expected, reality) + } + } +} + +func TestCarbon_Gt(t *testing.T) { + now := Now() + tomorrow := Tomorrow() + yesterday := Yesterday() + Tests := []struct { + input Carbon // 输入值 + time Carbon // 输入参数 + output bool // 期望输出值 + }{ + {now, now, false}, + {now, yesterday, true}, + {now, tomorrow, false}, + } + + for _, v := range Tests { + output := v.input.Gt(v.time) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s > %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) + } + } +} + +func TestCarbon_Lt(t *testing.T) { + now := Now() + tomorrow := Tomorrow() + yesterday := Yesterday() + Tests := []struct { + input Carbon // 输入值 + time Carbon // 输入参数 + output bool // 期望输出值 + }{ + {now, now, false}, + {now, yesterday, false}, + {now, tomorrow, true}, + } + + for _, v := range Tests { + output := v.input.Lt(v.time) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s < %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) + } + } +} + +func TestCarbon_Eq(t *testing.T) { + now := Now() + tomorrow := Tomorrow() + yesterday := Yesterday() + Tests := []struct { + input Carbon // 输入值 + time Carbon // 输入参数 + output bool // 期望输出值 + }{ + {now, now, true}, + {now, yesterday, false}, + {now, tomorrow, false}, + } + + for _, v := range Tests { + output := v.input.Eq(v.time) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s = %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) + } + } +} + +func TestCarbon_Ne(t *testing.T) { + now := Now() + tomorrow := Tomorrow() + yesterday := Yesterday() + Tests := []struct { + input Carbon // 输入值 + time Carbon // 输入参数 + output bool // 期望输出值 + }{ + {now, now, false}, + {now, yesterday, true}, + {now, tomorrow, true}, + } + + for _, v := range Tests { + output := v.input.Ne(v.time) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s != %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) + } + } +} + +func TestCarbon_Gte(t *testing.T) { + now := Now() + tomorrow := Tomorrow() + yesterday := Yesterday() + Tests := []struct { + input Carbon // 输入值 + time Carbon // 输入参数 + output bool // 期望输出值 + }{ + {now, now, true}, + {now, yesterday, true}, + {now, tomorrow, false}, + } + + for _, v := range Tests { + output := v.input.Gte(v.time) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s >= %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) + } + } +} + +func TestCarbon_Lte(t *testing.T) { + now := Now() + tomorrow := Tomorrow() + yesterday := Yesterday() + Tests := []struct { + input Carbon // 输入值 + time Carbon // 输入参数 + output bool // 期望输出值 + }{ + {now, now, true}, + {now, yesterday, false}, + {now, tomorrow, true}, + } + + for _, v := range Tests { + output := v.input.Lte(v.time) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s <= %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) + } + } +} + +func TestCarbon_Between(t *testing.T) { + Tests := []struct { + input Carbon // 输入值 + time1 Carbon // 输入参数 + time2 Carbon // 输入参数 + output bool // 期望输出值 + }{ + {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), false}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-06 13:14:15"), false}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-05 13:14:15"), false}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-06 13:14:15"), true}, + } + + for _, v := range Tests { + output := v.input.Between(v.time1, v.time2) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s < %s < %s, expected %s, but got %s\n", v.time1.ToDateTimeString(), v.input.ToDateTimeString(), v.time2.ToDateTimeString(), expected, reality) + } + } +} + +func TestCarbon_BetweenIncludedStartTime(t *testing.T) { + Tests := []struct { + input Carbon // 输入值 + time1 Carbon // 输入参数 + time2 Carbon // 输入参数 + output bool // 期望输出值 + }{ + {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), false}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-06 13:14:15"), true}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-05 13:14:15"), false}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-06 13:14:15"), true}, + } + + for _, v := range Tests { + output := v.input.BetweenIncludedStartTime(v.time1, v.time2) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s <= %s < %s, expected %s, but got %s\n", v.time1.ToDateTimeString(), v.input.ToDateTimeString(), v.time2.ToDateTimeString(), expected, reality) + } + } +} + +func TestCarbon_BetweenIncludedEndTime(t *testing.T) { + Tests := []struct { + input Carbon // 输入值 + time1 Carbon // 输入参数 + time2 Carbon // 输入参数 + output bool // 期望输出值 + }{ + {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), false}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-06 13:14:15"), false}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-05 13:14:15"), true}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-06 13:14:15"), true}, + } + + for _, v := range Tests { + output := v.input.BetweenIncludedEndTime(v.time1, v.time2) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s < %s <= %s, expected %s, but got %s\n", v.time1.ToDateTimeString(), v.input.ToDateTimeString(), v.time2.ToDateTimeString(), expected, reality) + } + } +} + +func TestCarbon_BetweenIncludedBoth(t *testing.T) { + Tests := []struct { + input Carbon // 输入值 + time1 Carbon // 输入参数 + time2 Carbon // 输入参数 + output bool // 期望输出值 + }{ + {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), true}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-06 13:14:15"), true}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-05 13:14:15"), true}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-06 13:14:15"), true}, + {Parse("2020-08-05 13:14:15"), Parse("2020-08-06 13:14:15"), Parse("2020-08-06 13:14:15"), false}, + } + + for _, v := range Tests { + output := v.input.BetweenIncludedBoth(v.time1, v.time2) + + if output != v.output { + expected := "false" + if v.output == true { + expected = "true" + } + + reality := "false" + if output == true { + reality = "true" + } + t.Errorf("Input %s <= %s <= %s, expected %s, but got %s\n", v.time1.ToDateTimeString(), v.input.ToDateTimeString(), v.time2.ToDateTimeString(), expected, reality) + } + } +} diff --git a/constant.go b/constant.go deleted file mode 100644 index d5bbefb..0000000 --- a/constant.go +++ /dev/null @@ -1,130 +0,0 @@ -package carbon - -import "time" - -// 版权信息 -const ( - Version = "v1.3.1" - Author = "gouguoyin" - Email = "mail@gouguoyin.cn" - Blog = "www.gouguoyin.cn" -) - -// 时区常量 -const ( - Local = "Local" - CET = "CET" - EET = "EET" - EST = "EST" - GMT = "GMT" - UTC = "UTC" - UCT = "UCT" - MST = "MST" - - Cuba = "Cuba" - Egypt = "Egypt" - Eire = "Eire" - Greenwich = "Greenwich" - Iceland = "Iceland" - Iran = "Iran" - Israel = "Israel" - Jamaica = "Jamaica" - Japan = "Japan" - Libya = "Libya" - Poland = "Poland" - Portugal = "Portugal" - PRC = "PRC" - Singapore = "Singapore" - Turkey = "Turkey" - Zulu = "Zulu" - - Shanghai = "Asia/Shanghai" - Chongqing = "Asia/Chongqing" - HongKong = "Asia/Hong_Kong" - Macao = "Asia/Macao" - Taipei = "Asia/Taipei" - Tokyo = "Asia/Tokyo" - London = "Europe/London" - NewYork = "America/New_York" - LosAngeles = "America/Los_Angeles" -) - -// 月份常量 -const ( - January = "January" // 一月 - February = "February" // 二月 - March = "March" // 三月 - April = "April" // 四月 - May = "May" // 五月 - June = "June" // 六月 - July = "July" // 七月 - August = "August" // 八月 - September = "September" // 九月 - October = "October" // 十月 - November = "November" // 十一月 - December = "December" // 十二月 -) - -// 星期常量 -const ( - Monday = "Monday" // 周一 - Tuesday = "Tuesday" // 周二 - Wednesday = "Wednesday" // 周三 - Thursday = "Thursday" // 周四 - Friday = "Friday" // 周五 - Saturday = "Saturday" // 周六 - Sunday = "Sunday" // 周日 -) - -// 数字常量 -const ( - YearsPerMillennium = 1000 // 每千年1000年 - YearsPerCentury = 100 // 每世纪100年 - YearsPerDecade = 10 // 每十年10年 - QuartersPerYear = 4 // 每年4季度 - MonthsPerYear = 12 // 每年12月 - MonthsPerQuarter = 3 // 每季度3月 - WeeksPerNormalYear = 52 // 每常规年52周 - weeksPerLongYear = 53 // 每长年53周 - WeeksPerMonth = 4 // 每月4周 - DaysPerLeapYear = 366 // 每闰年366天 - DaysPerNormalYear = 365 // 每常规年365天 - DaysPerWeek = 7 // 每周7天 - HoursPerWeek = 168 // 每周168小时 - HoursPerDay = 24 // 每天24小时 - MinutesPerDay = 1440 // 每天1440分钟 - MinutesPerHour = 60 // 每小时60分钟 - SecondsPerWeek = 604800 // 每周604800秒 - SecondsPerDay = 86400 // 每天86400秒 - SecondsPerHour = 3600 // 每小时3600秒 - SecondsPerMinute = 60 // 每分钟60秒 - MillisecondsPerSecond = 1000 // 每秒1000毫秒 - MicrosecondsPerMillisecond = 1000 // 每毫秒1000微秒 - MicrosecondsPerSecond = 1000000 // 每秒1000000微秒 -) - -// 时间格式化常量 -const ( - AnsicFormat = time.ANSIC - UnixDateFormat = time.UnixDate - RubyDateFormat = time.RubyDate - RFC822Format = time.RFC822 - RFC822ZFormat = time.RFC822Z - RFC850Format = time.RFC850 - RFC1123Format = time.RFC1123 - RFC1123ZFormat = time.RFC1123Z - RssFormat = time.RFC1123Z - RFC2822Format = time.RFC1123Z - RFC3339Format = time.RFC3339 - KitchenFormat = time.Kitchen - CookieFormat = "Monday, 02-Jan-2006 15:04:05 MST" - RFC1036Format = "Mon, 02 Jan 06 15:04:05 -0700" - RFC7231Format = "Mon, 02 Jan 2006 15:04:05 GMT" - DayDateTimeFormat = "Mon, Aug 2, 2006 3:04 PM" - DateTimeFormat = "2006-01-02 15:04:05" - DateFormat = "2006-01-02" - TimeFormat = "15:04:05" - ShortDateTimeFormat = "20060102150405" - ShortDateFormat = "20060102" - ShortTimeFormat = "150405" -) diff --git a/converter.go b/converter.go new file mode 100755 index 0000000..9a96653 --- /dev/null +++ b/converter.go @@ -0,0 +1,14 @@ +package carbon + +import "time" + +// Time2Carbon 将 time.Time 转换成 Carbon +func Time2Carbon(tt time.Time) Carbon { + loc, _ := time.LoadLocation(Local) + return Carbon{Time: tt, Loc: loc} +} + +// Carbon2Time 将 Carbon 转换成 time.Time +func (c Carbon) Carbon2Time() time.Time { + return c.Time +} diff --git a/converter_test.go b/converter_test.go new file mode 100755 index 0000000..3d79618 --- /dev/null +++ b/converter_test.go @@ -0,0 +1,40 @@ +package carbon + +import ( + "testing" + "time" +) + +func TestCarbon_Time2Carbon(t *testing.T) { + Tests := []struct { + time time.Time // // 输入参数 + output string // 期望输出值 + }{ + {time.Now(), time.Now().Format(DateTimeFormat)}, + } + + for _, v := range Tests { + output := Time2Carbon(v.time).ToDateTimeString() + + if output != v.output { + t.Errorf("Expected %s, but got %s", v.output, output) + } + } +} + +func TestCarbon_Carbon2Time(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-08-05", "2020-08-05"}, + } + + for _, v := range Tests { + output := Parse(v.input).Carbon2Time().Format("2006-01-02") + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} diff --git a/coverage.html b/coverage.html deleted file mode 100644 index 0c85fa5..0000000 --- a/coverage.html +++ /dev/null @@ -1,1867 +0,0 @@ - - - - go-carbon代码测试覆盖率报告 - - - - -
- -
- not tracked - not covered - covered -
-
-
-
package carbon
-
-var (
-        // 十二生肖
-        SymbolicAnimals = [12]string{"猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊"}
-
-        // 天干
-        HeavenlyStems = [10]string{"庚", "辛", "壬", "癸", "甲", "乙", "丙", "丙", "戊", "己"}
-
-        // 地支
-        EarthlyBranches = [12]string{"申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未"}
-)
-
-// ToAnimalYear 获取生肖年
-func (c Carbon) ToAnimalYear() string {
-        if c.Time.IsZero() {
-                return ""
-        }
-        year := c.Time.Year()
-        return SymbolicAnimals[year%12]
-}
-
-// ToLunarYear 获取农历年
-func (c Carbon) ToLunarYear() string {
-        if c.Time.IsZero() {
-                return ""
-        }
-        year := c.Time.Year()
-        return HeavenlyStems[year%10] + EarthlyBranches[year%12]
-}
-
-// IsYearOfRat 是否是鼠年
-func (c Carbon) IsYearOfRat() bool {
-        year := c.Time.Year()
-        if year%12 == 4 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfOx 是否是牛年
-func (c Carbon) IsYearOfOx() bool {
-        year := c.Time.Year()
-        if year%12 == 5 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfTiger 是否是虎年
-func (c Carbon) IsYearOfTiger() bool {
-        year := c.Time.Year()
-        if year%12 == 6 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfRabbit 是否是兔年
-func (c Carbon) IsYearOfRabbit() bool {
-        year := c.Time.Year()
-        if year%12 == 7 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfDragon 是否是龙年
-func (c Carbon) IsYearOfDragon() bool {
-        year := c.Time.Year()
-        if year%12 == 8 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfSnake 是否是蛇年
-func (c Carbon) IsYearOfSnake() bool {
-        year := c.Time.Year()
-        if year%12 == 9 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfHorse 是否是马年
-func (c Carbon) IsYearOfHorse() bool {
-        year := c.Time.Year()
-        if year%12 == 10 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfGoat 是否是羊年
-func (c Carbon) IsYearOfGoat() bool {
-        year := c.Time.Year()
-        if year%12 == 11 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfMonkey 是否是猴年
-func (c Carbon) IsYearOfMonkey() bool {
-        year := c.Time.Year()
-        if year%12 == 0 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfRooster 是否是鸡年
-func (c Carbon) IsYearOfRooster() bool {
-        year := c.Time.Year()
-        if year%12 == 1 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfDog 是否是狗年
-func (c Carbon) IsYearOfDog() bool {
-        year := c.Time.Year()
-        if year%12 == 2 {
-                return true
-        }
-        return false
-}
-
-// IsYearOfPig 是否是猪年
-func (c Carbon) IsYearOfPig() bool {
-        year := c.Time.Year()
-        if year%12 == 3 {
-                return true
-        }
-        return false
-}
-
- - - - - -
- - - \ No newline at end of file diff --git a/creator.go b/creator.go new file mode 100755 index 0000000..6610fb0 --- /dev/null +++ b/creator.go @@ -0,0 +1,65 @@ +package carbon + +import ( + "strconv" + "time" +) + +// CreateFromTimestamp 从时间戳创建Carbon实例 +func (c Carbon) CreateFromTimestamp(timestamp int64) Carbon { + ts := timestamp + switch len(strconv.FormatInt(timestamp, 10)) { + case 10: + ts = timestamp + case 13: + ts = timestamp / 1e3 + case 16: + ts = timestamp / 1e6 + case 19: + ts = timestamp / 1e9 + default: + ts = 0 + } + c.Time = time.Unix(ts, 0) + return c +} + +// CreateFromTimestamp 从时间戳创建Carbon实例(默认时区) +func CreateFromTimestamp(timestamp int64) Carbon { + return SetTimezone(Local).CreateFromTimestamp(timestamp) +} + +// CreateFromDateTime 从年月日时分秒创建Carbon实例 +func (c Carbon) CreateFromDateTime(year int, month int, day int, hour int, minute int, second int) Carbon { + c.Time = time.Date(year, time.Month(month), day, hour, minute, second, 0, c.Loc) + return c +} + +// CreateFromDateTime 从年月日时分秒创建Carbon实例(默认时区) +func CreateFromDateTime(year int, month int, day int, hour int, minute int, second int) Carbon { + return SetTimezone(Local).CreateFromDateTime(year, month, day, hour, minute, second) +} + +// CreateFromDate 从年月日创建Carbon实例 +func (c Carbon) CreateFromDate(year int, month int, day int) Carbon { + hour, minute, second := time.Now().Clock() + c.Time = time.Date(year, time.Month(month), day, hour, minute, second, 0, c.Loc) + return c +} + +// CreateFromDate 从年月日创建Carbon实例(默认时区) +func CreateFromDate(year int, month int, day int) Carbon { + return SetTimezone(Local).CreateFromDate(year, month, day) +} + +// CreateFromTime 从时分秒创建Carbon实例 +func (c Carbon) CreateFromTime(hour int, minute int, second int) Carbon { + year, month, day := time.Now().Date() + c.Time = time.Date(year, month, day, hour, minute, second, 0, c.Loc) + return c +} + +// CreateFromTime 从时分秒创建Carbon实例(默认时区) +func CreateFromTime(hour int, minute int, second int) Carbon { + return SetTimezone(Local).CreateFromTime(hour, minute, second) +} diff --git a/creator_test.go b/creator_test.go new file mode 100755 index 0000000..3c0fa2a --- /dev/null +++ b/creator_test.go @@ -0,0 +1,124 @@ +package carbon + +import ( + "testing" +) + +func TestCarbon_CreateFromTimestamp(t *testing.T) { + Tests := []struct { + timestamp int64 // 输入参数 + output string // 期望输出值 + }{ + {123456, "1970-01-01 08:00:00"}, + {1577855655, "2020-01-01 13:14:15"}, + {1604074084682, "2020-10-31 00:08:04"}, + {1604074196366540, "2020-10-31 00:09:56"}, + {1604074298500312000, "2020-10-31 00:11:38"}, + } + + for _, v := range Tests { + output := CreateFromTimestamp(v.timestamp).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %d, expected %s, but got %s", v.timestamp, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).CreateFromTimestamp(v.timestamp).ToDateTimeString() + + if output != v.output { + t.Errorf("Expected %s, but got %s", v.output, output) + } + } +} + +func TestCarbon_CreateFromDateTime(t *testing.T) { + Tests := []struct { + year, month, day, hour, minute, second int // 输入参数 + output string // 期望输出值 + }{ + {2020, 01, 01, 13, 14, 15, "2020-01-01 13:14:15"}, + {2020, 1, 31, 13, 14, 15, "2020-01-31 13:14:15"}, + {2020, 2, 1, 13, 14, 15, "2020-02-01 13:14:15"}, + {2020, 2, 28, 13, 14, 15, "2020-02-28 13:14:15"}, + {2020, 2, 29, 13, 14, 15, "2020-02-29 13:14:15"}, + } + + for _, v := range Tests { + output := CreateFromDateTime(v.year, v.month, v.day, v.hour, v.minute, v.second).ToDateTimeString() + + if output != v.output { + t.Errorf("Expected %s, but got %s", v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).CreateFromDateTime(v.year, v.month, v.day, v.hour, v.minute, v.second).ToDateTimeString() + + if output != v.output { + t.Errorf("Expected %s, but got %s", v.output, output) + } + } +} + +func TestCarbon_CreateFromDate(t *testing.T) { + clock := Now().ToTimeString() + + Tests := []struct { + year, month, day int // 输入参数 + output string // 期望输出值 + }{ + {2020, 01, 01, "2020-01-01 " + clock}, + {2020, 1, 31, "2020-01-31 " + clock}, + {2020, 2, 1, "2020-02-01 " + clock}, + {2020, 2, 28, "2020-02-28 " + clock}, + {2020, 2, 29, "2020-02-29 " + clock}, + } + + for _, v := range Tests { + output := CreateFromDate(v.year, v.month, v.day).ToDateTimeString() + + if output != v.output { + t.Errorf("Expected %s, but got %s", v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).CreateFromDate(v.year, v.month, v.day).ToDateTimeString() + + if output != v.output { + t.Errorf("Expected %s, but got %s", v.output, output) + } + } +} + +func TestCarbon_CreateFromTime(t *testing.T) { + date := Now().ToDateString() + + Tests := []struct { + hour, minute, second int // 输入参数 + output string // 期望输出值 + }{ + {0, 0, 0, date + " 00:00:00"}, + {00, 00, 15, date + " 00:00:15"}, + {00, 14, 15, date + " 00:14:15"}, + {13, 14, 15, date + " 13:14:15"}, + } + + for _, v := range Tests { + output := CreateFromTime(v.hour, v.minute, v.second).ToDateTimeString() + + if output != v.output { + t.Errorf("Expected %s, but got %s", v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).CreateFromTime(v.hour, v.minute, v.second).ToDateTimeString() + + if output != v.output { + t.Errorf("Expected %s, but got %s", v.output, output) + } + } +} diff --git a/difference.go b/difference.go new file mode 100755 index 0000000..32accac --- /dev/null +++ b/difference.go @@ -0,0 +1,223 @@ +package carbon + +import ( + "strings" +) + +// DiffInYears 相差多少年 +func (c Carbon) DiffInYears(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return c.DiffInMonths(end) / 12 +} + +// DiffInYearsWithAbs 相差多少年(绝对值) +func (c Carbon) DiffInYearsWithAbs(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return getAbsValue(c.DiffInYears(end)) +} + +// DiffInMonths 相差多少月 +func (c Carbon) DiffInMonths(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + + dy, dm, dd := end.Year()-c.Year(), end.Month()-c.Month(), end.Day()-c.Day() + + if dd < 0 { + dm = dm - 1 + } + + if dy == 0 && dm == 0 { + return 0 + } + + if dy == 0 && dm != 0 && dd != 0 { + if int(end.DiffInHoursWithAbs(c)) < c.DaysInMonth()*HoursPerDay { + return 0 + } + return int64(dm) + } + + return int64(dy*MonthsPerYear + dm) +} + +// DiffInMonthsWithAbs 相差多少月(绝对值) +func (c Carbon) DiffInMonthsWithAbs(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return getAbsValue(c.DiffInMonths(end)) +} + +// DiffInWeeks 相差多少周 +func (c Carbon) DiffInWeeks(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return c.DiffInDays(end) / DaysPerWeek +} + +// DiffInWeeksWithAbs 相差多少周(绝对值) +func (c Carbon) DiffInWeeksWithAbs(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return getAbsValue(c.DiffInWeeks(end)) +} + +// DiffInDays 相差多少天 +func (c Carbon) DiffInDays(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return c.DiffInSeconds(end) / SecondsPerDay +} + +// DiffInDaysWithAbs 相差多少天(绝对值) +func (c Carbon) DiffInDaysWithAbs(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return getAbsValue(c.DiffInDays(end)) +} + +// DiffInHours 相差多少小时 +func (c Carbon) DiffInHours(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return c.DiffInSeconds(end) / SecondsPerHour +} + +// DiffInHoursWithAbs 相差多少小时(绝对值) +func (c Carbon) DiffInHoursWithAbs(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return getAbsValue(c.DiffInHours(end)) +} + +// DiffInMinutes 相差多少分钟 +func (c Carbon) DiffInMinutes(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return c.DiffInSeconds(end) / SecondsPerMinute +} + +// DiffInMinutesWithAbs 相差多少分钟(绝对值) +func (c Carbon) DiffInMinutesWithAbs(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return getAbsValue(c.DiffInMinutes(end)) +} + +// DiffInSeconds 相差多少秒 +func (c Carbon) DiffInSeconds(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + if c.Time.IsZero() && end.Time.IsZero() { + return 0 + } + + if end.Time.IsZero() { + return -c.ToTimestamp() + } + if c.Time.IsZero() { + return end.ToTimestamp() + } + + return end.ToTimestamp() - c.ToTimestamp() +} + +// DiffInSecondsWithAbs 相差多少秒(绝对值) +func (c Carbon) DiffInSecondsWithAbs(arg ...Carbon) int64 { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + return getAbsValue(c.DiffInSeconds(end)) +} + +// DiffForHumans 获取对人类友好的可读格式时间差 +func (c Carbon) DiffForHumans(arg ...Carbon) string { + end := c.Now() + if len(arg) > 0 { + end = arg[0] + } + + var unit string + var diff int64 + + switch true { + case c.DiffInYearsWithAbs(end) > 0: + unit = "year" + diff = c.DiffInYearsWithAbs(end) + break + case c.DiffInMonthsWithAbs(end) > 0: + unit = "month" + diff = c.DiffInMonthsWithAbs(end) + break + case c.DiffInWeeksWithAbs(end) > 0: + unit = "week" + diff = c.DiffInWeeksWithAbs(end) + break + case c.DiffInDaysWithAbs(end) > 0: + unit = "day" + diff = c.DiffInDaysWithAbs(end) + break + case c.DiffInHoursWithAbs(end) > 0: + unit = "hour" + diff = c.DiffInHoursWithAbs(end) + break + case c.DiffInMinutesWithAbs(end) > 0: + unit = "minute" + diff = c.DiffInMinutesWithAbs(end) + break + case c.DiffInSecondsWithAbs(end) > 0: + unit = "second" + diff = c.DiffInSecondsWithAbs(end) + break + case c.DiffInSecondsWithAbs(end) == 0: + unit = "now" + diff = 0 + return c.Lang.translate(unit, diff) + } + + translation := c.Lang.translate(unit, diff) + + if c.Lt(end) && len(arg) == 0 { + return strings.Replace(c.Lang.resources["ago"], "%s", translation, 1) + } + if c.Lt(end) && len(arg) > 0 { + return strings.Replace(c.Lang.resources["before"], "%s", translation, 1) + } + if c.Gt(end) && len(arg) == 0 { + return strings.Replace(c.Lang.resources["from_now"], "%s", translation, 1) + } + if c.Gt(end) && len(arg) > 0 { + return strings.Replace(c.Lang.resources["after"], "%s", translation, 1) + } + + return translation +} diff --git a/difference_test.go b/difference_test.go new file mode 100755 index 0000000..68076b3 --- /dev/null +++ b/difference_test.go @@ -0,0 +1,456 @@ +package carbon + +import ( + "testing" +) + +func TestCarbon_DiffInYears(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"2020-08-05 13:14:15", "2020-07-28 13:14:00", 0}, + {"2020-12-31 13:14:15", "2021-01-01 13:14:15", 0}, + {"2020-08-05 13:14:15", "2021-08-28 13:14:59", 1}, + {"2020-08-05 13:14:15", "2018-08-28 13:14:59", -2}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInYears(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func Test1Carbon_DiffInYearsWithAbs(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"2020-08-05 13:14:15", "2020-07-28 13:14:00", 0}, + {"2020-12-31 13:14:15", "2021-01-01 13:14:15", 0}, + {"2020-08-05 13:14:15", "2021-08-28 13:14:59", 1}, + {"2020-08-05 13:14:15", "2018-08-28 13:14:59", 2}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInYearsWithAbs(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInMonths(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"2020-08-05 13:14:15", "2020-07-28 13:14:00", 0}, + {"2020-12-31 13:14:15", "2021-01-31 13:14:15", 1}, + {"2020-08-05 13:14:15", "2021-08-28 13:14:59", 12}, + {"2020-08-05 13:14:15", "2018-08-28 13:14:59", -24}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInMonths(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInMonthsWithAbs(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"2020-08-05 13:14:15", "2020-07-28 13:14:00", 0}, + {"2020-12-31 13:14:15", "2021-01-01 13:14:15", 0}, + {"2020-08-05 13:14:15", "2021-08-28 13:14:59", 12}, + {"2020-08-05 13:14:15", "2018-08-28 13:14:59", 24}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInMonthsWithAbs(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInWeeks(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"0000-00-00 00:00:00", "", 0}, + {"", "0000-00-00 00:00:00", 0}, + {"", "", 0}, + {"2020-08-05 13:14:15", "", -2639}, + {"", "2020-08-05 13:14:15", 2639}, + {"2020-08-05 13:14:15", "2020-07-28 13:14:00", -1}, + {"2020-08-05 13:14:15", "2020-07-28 13:14:15", -1}, + {"2020-08-05 13:14:15", "2020-07-28 13:14:59", -1}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:00", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, + {"2020-08-05 13:14:15", "2020-08-12 13:14:00", 0}, + {"2020-08-05 13:14:15", "2020-08-12 13:14:15", 1}, + {"2020-08-05 13:14:15", "2020-08-12 13:14:59", 1}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInWeeks(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInWeeksWithAbs(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"0000-00-00 00:00:00", "", 0}, + {"", "0000-00-00 00:00:00", 0}, + {"", "", 0}, + {"2020-08-05 13:14:15", "", 2639}, + {"", "2020-08-05 13:14:15", 2639}, + {"2020-08-05 13:14:15", "2020-07-28 13:14:00", 1}, + {"2020-08-05 13:14:15", "2020-07-28 13:14:15", 1}, + {"2020-08-05 13:14:15", "2020-07-28 13:14:59", 1}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:00", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, + {"2020-08-05 13:14:15", "2020-08-12 13:14:00", 0}, + {"2020-08-05 13:14:15", "2020-08-12 13:14:15", 1}, + {"2020-08-05 13:14:15", "2020-08-12 13:14:59", 1}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInWeeksWithAbs(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInDays(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"0000-00-00 00:00:00", "", 0}, + {"", "0000-00-00 00:00:00", 0}, + {"", "", 0}, + {"2020-08-05 13:14:15", "", -18479}, + {"", "2020-08-05 13:14:15", 18479}, + {"2020-08-05 13:14:15", "2020-08-04 13:00:00", -1}, + {"2020-08-05 13:14:15", "2020-08-04 13:14:15", -1}, + {"2020-08-05 13:14:15", "2020-08-04 13:14:59", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:00:00", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, + {"2020-08-05 13:14:15", "2020-08-06 13:00:00", 0}, + {"2020-08-05 13:14:15", "2020-08-06 13:14:15", 1}, + {"2020-08-05 13:14:15", "2020-08-06 13:14:59", 1}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInDays(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInDaysWithAbs(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"0000-00-00 00:00:00", "", 0}, + {"", "0000-00-00 00:00:00", 0}, + {"", "", 0}, + {"2020-08-05 13:14:15", "", 18479}, + {"", "2020-08-05 13:14:15", 18479}, + {"2020-08-05 13:14:15", "2020-08-04 13:00:00", 1}, + {"2020-08-05 13:14:15", "2020-08-04 13:14:15", 1}, + {"2020-08-05 13:14:15", "2020-08-04 13:14:59", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:00:00", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, + {"2020-08-05 13:14:15", "2020-08-06 13:00:00", 0}, + {"2020-08-05 13:14:15", "2020-08-06 13:14:15", 1}, + {"2020-08-05 13:14:15", "2020-08-06 13:14:59", 1}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInDaysWithAbs(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInHours(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"0000-00-00 00:00:00", "", 0}, + {"", "0000-00-00 00:00:00", 0}, + {"", "", 0}, + {"2020-08-05 13:14:15", "", -443501}, + {"", "2020-08-05 13:14:15", 443501}, + {"2020-08-05 13:14:15", "2020-08-05 12:14:00", -1}, + {"2020-08-05 13:14:15", "2020-08-05 12:14:15", -1}, + {"2020-08-05 13:14:15", "2020-08-05 12:14:59", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:00", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, + {"2020-08-05 13:14:15", "2020-08-05 14:14:00", 0}, + {"2020-08-05 13:14:15", "2020-08-05 14:14:15", 1}, + {"2020-08-05 13:14:15", "2020-08-05 14:14:59", 1}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInHours(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInHoursWithAbs(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"0000-00-00 00:00:00", "", 0}, + {"", "0000-00-00 00:00:00", 0}, + {"", "", 0}, + {"2020-08-05 13:14:15", "", 443501}, + {"", "2020-08-05 13:14:15", 443501}, + {"2020-08-05 13:14:15", "2020-08-05 12:14:00", 1}, + {"2020-08-05 13:14:15", "2020-08-05 12:14:15", 1}, + {"2020-08-05 13:14:15", "2020-08-05 12:14:59", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:00", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, + {"2020-08-05 13:14:15", "2020-08-05 14:14:00", 0}, + {"2020-08-05 13:14:15", "2020-08-05 14:14:15", 1}, + {"2020-08-05 13:14:15", "2020-08-05 14:14:59", 1}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInHoursWithAbs(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInMinutes(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"0000-00-00 00:00:00", "", 0}, + {"", "0000-00-00 00:00:00", 0}, + {"", "", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:13:00", -1}, + {"2020-08-05 13:14:15", "2020-08-05 13:13:15", -1}, + {"2020-08-05 13:14:15", "2020-08-05 13:13:59", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:15:00", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:15:15", 1}, + {"2020-08-05 13:14:15", "2020-08-05 13:15:59", 1}, + {"2020-08-05 13:14:15", "2020-08-05 13:16:00", 1}, + {"2020-08-05 13:14:15", "2020-08-05 13:16:15", 2}, + {"2020-08-05 13:14:15", "2020-08-05 13:16:59", 2}, + {"2020-08-05 13:14:15", "", -26610074}, + {"", "2010-08-05 13:14:15", 21349754}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInMinutes(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInMinutesWithAbs(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"0000-00-00 00:00:00", "", 0}, + {"", "0000-00-00 00:00:00", 0}, + {"", "", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:13:00", 1}, + {"2020-08-05 13:14:15", "2020-08-05 13:13:15", 1}, + {"2020-08-05 13:14:15", "2020-08-05 13:13:59", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:15:00", 0}, + {"2020-08-05 13:14:15", "2020-08-05 13:15:15", 1}, + {"2020-08-05 13:14:15", "2020-08-05 13:15:59", 1}, + {"2020-08-05 13:14:15", "2020-08-05 13:16:00", 1}, + {"2020-08-05 13:14:15", "2020-08-05 13:16:15", 2}, + {"2020-08-05 13:14:15", "2020-08-05 13:16:59", 2}, + {"2020-08-05 13:14:15", "", 26610074}, + {"", "2010-08-05 13:14:15", 21349754}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInMinutesWithAbs(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInSeconds(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"0000-00-00 00:00:00", "", 0}, + {"", "0000-00-00 00:00:00", 0}, + {"", "", 0}, + {"2020-08-05 13:14:15", "", -1596604455}, + {"", "2010-08-05 13:14:15", 1280985255}, + {"2020-08-05 13:14:15", "2010-08-05 13:14:15", -315619200}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInSeconds(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffInSecondsWithAbs(t *testing.T) { + Tests := []struct { + input1 string // 输入值1 + input2 string // 输入值2 + output int64 // 期望输出值 + }{ + {"0000-00-00 00:00:00", "", 0}, + {"", "0000-00-00 00:00:00", 0}, + {"", "", 0}, + {"2020-08-05 13:14:15", "", 1596604455}, + {"", "2010-08-05 13:14:15", 1280985255}, + {"2020-08-05 13:14:15", "2010-08-05 13:14:15", 315619200}, + } + + for _, v := range Tests { + output := Parse(v.input1).DiffInSecondsWithAbs(Parse(v.input2)) + + if output != v.output { + t.Errorf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) + } + } +} + +func TestCarbon_DiffForHumans1(t *testing.T) { + Tests := []struct { + input Carbon // 输入值 + output string // 期望输出值 + }{ + {Now(), "just now"}, + {Now().AddYears(1), "1 year from now"}, + {Now().SubYears(1), "1 year ago"}, + {Now().AddYears(10), "10 years from now"}, + {Now().SubYears(10), "10 years ago"}, + + {Now().AddMonths(1), "1 month from now"}, + {Now().SubMonths(1), "1 month ago"}, + {Now().AddMonths(10), "10 months from now"}, + {Now().SubMonths(10), "10 months ago"}, + + {Now().AddDays(1), "1 day from now"}, + {Now().SubDays(1), "1 day ago"}, + {Now().AddDays(10), "1 week from now"}, + {Now().SubDays(10), "1 week ago"}, + + {Now().AddHours(1), "1 hour from now"}, + {Now().SubHours(1), "1 hour ago"}, + {Now().AddHours(10), "10 hours from now"}, + {Now().SubHours(10), "10 hours ago"}, + + {Now().AddMinutes(1), "1 minute from now"}, + {Now().SubMinutes(1), "1 minute ago"}, + {Now().AddMinutes(10), "10 minutes from now"}, + {Now().SubMinutes(10), "10 minutes ago"}, + + {Now().AddSeconds(1), "1 second from now"}, + {Now().SubSeconds(1), "1 second ago"}, + {Now().AddSeconds(10), "10 seconds from now"}, + {Now().SubSeconds(10), "10 seconds ago"}, + } + + for _, v := range Tests { + output := (v.input).DiffForHumans() + + if output != v.output { + t.Errorf("Input time %s, expected %s, but got %s", v.input.ToDateTimeString(), v.output, output) + } + } +} + +func TestCarbon_DiffForHumans2(t *testing.T) { + Tests := []struct { + input1 Carbon // 输入值1 + input2 Carbon // 输入值2 + output string // 期望输出值 + }{ + {Now(), Now(), "刚刚"}, + {Now().AddYears(1), Now(), "1 年后"}, + {Now().SubYears(1), Now(), "1 年前"}, + {Now().AddYears(10), Now(), "10 年后"}, + {Now().SubYears(10), Now(), "10 年前"}, + + {Now().AddMonths(1), Now(), "1 个月后"}, + {Now().SubMonths(1), Now(), "1 个月前"}, + {Now().AddMonths(10), Now(), "10 个月后"}, + {Now().SubMonths(10), Now(), "10 个月前"}, + } + + for _, v := range Tests { + output := (v.input1).SetLocale("zh-CN").DiffForHumans(v.input2) + + if output != v.output { + t.Errorf("Input time %s, expected %s, but got %s", v.input1.ToDateTimeString(), v.output, output) + } + } +} diff --git a/display.go b/display.go new file mode 100755 index 0000000..30d7133 --- /dev/null +++ b/display.go @@ -0,0 +1,264 @@ +package carbon + +import ( + "bytes" + "strconv" + "time" +) + +// ToString 输出"2006-01-02 15:04:05.999999999 -0700 MST"格式字符串 +func (c Carbon) ToString() string { + return c.Time.In(c.Loc).String() +} + +// ToTimestamp ToTimestampWithSecond的简称 +func (c Carbon) ToTimestamp() int64 { + return c.ToTimestampWithSecond() +} + +// ToTimestampWithSecond 输出秒级时间戳 +func (c Carbon) ToTimestampWithSecond() int64 { + return c.Time.Unix() +} + +// ToTimestampWithMillisecond 输出毫秒级时间戳 +func (c Carbon) ToTimestampWithMillisecond() int64 { + return c.Time.UnixNano() / int64(time.Millisecond) +} + +// ToTimestampWithMicrosecond 输出微秒级时间戳 +func (c Carbon) ToTimestampWithMicrosecond() int64 { + return c.Time.UnixNano() / int64(time.Microsecond) +} + +// ToTimestampWithNanosecond 输出纳秒级时间戳 +func (c Carbon) ToTimestampWithNanosecond() int64 { + return c.Time.UnixNano() +} + +// Format ToFormatString的简称 +func (c Carbon) Format(format string) string { + return c.ToFormatString(format) +} + +// ToFormatString 输出指定格式时间 +func (c Carbon) ToFormatString(format string) string { + if c.IsZero() { + return "" + } + + runes := []rune(format) + buffer := bytes.NewBuffer(nil) + for i := 0; i < len(runes); i++ { + if layout, ok := formats[byte(runes[i])]; ok { + buffer.WriteString(c.Time.In(c.Loc).Format(layout)) + } else { + switch runes[i] { + case '\\': + buffer.WriteRune(runes[i+1]) + i += 2 + continue + case 'W': // ISO-8601 格式数字表示的年份中的第几周,取值范围 1-52 + buffer.WriteString(strconv.Itoa(c.WeekOfYear())) + case 'N': // ISO-8601 格式数字表示的星期中的第几天,取值范围 1-7 + buffer.WriteString(strconv.Itoa(c.DayOfWeek())) + case 'S': // 月份中第几天的英文缩写后缀,如st, nd, rd, th + suffix := "th" + switch c.Day() { + case 1, 21, 31: + suffix = "st" + case 2, 22: + suffix = "nd" + case 3, 23: + suffix = "rd" + } + buffer.WriteString(suffix) + case 'L': // 是否为闰年,如果是闰年为 1,否则为 0 + if c.IsLeapYear() { + buffer.WriteString("1") + } else { + buffer.WriteString("0") + } + case 'G': // 数字表示的小时,24 小时格式,没有前导零,取值范围 0-23 + buffer.WriteString(strconv.Itoa(c.Hour())) + case 'U': // 秒级时间戳,如 1611818268 + buffer.WriteString(strconv.FormatInt(c.ToTimestamp(), 10)) + case 'u': // 数字表示的毫秒,如 999 + buffer.WriteString(strconv.Itoa(c.Millisecond())) + case 'w': // 数字表示的星期中的第几天,取值范围 0-6 + buffer.WriteString(strconv.Itoa(c.DayOfWeek() - 1)) + case 't': // 指定的月份有几天,取值范围 28-31 + buffer.WriteString(strconv.Itoa(c.DaysInMonth())) + case 'z': // 年份中的第几天,取值范围 0-365 + buffer.WriteString(strconv.Itoa(c.DayOfYear() - 1)) + case 'e': // 当前时区,如 UTC,GMT,Atlantic/Azores + buffer.WriteString(c.Timezone()) + default: + buffer.WriteRune(runes[i]) + } + } + } + return buffer.String() +} + +// ToDayDateTimeString 输出天数日期时间字符串 +func (c Carbon) ToDayDateTimeString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(DayDateTimeFormat) +} + +// ToDateTimeString 输出日期时间字符串 +func (c Carbon) ToDateTimeString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(DateTimeFormat) +} + +// ToDateString 输出日期字符串 +func (c Carbon) ToDateString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(DateFormat) +} + +// ToTimeString 输出时间字符串 +func (c Carbon) ToTimeString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(TimeFormat) +} + +// ToAtomString 输出Atom格式字符串 +func (c Carbon) ToAtomString() string { + return c.ToRfc3339String() +} + +// ToAnsicString 输出Ansic格式字符串 +func (c Carbon) ToAnsicString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(AnsicFormat) +} + +// ToCookieString 输出Cookie格式字符串 +func (c Carbon) ToCookieString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(CookieFormat) +} + +// ToRssString 输出RSS格式字符串 +func (c Carbon) ToRssString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RssFormat) +} + +// ToW3cString 输出W3C格式字符串 +func (c Carbon) ToW3cString() string { + return c.ToRfc3339String() +} + +// ToUnixDateString 输出UnixDate格式字符串 +func (c Carbon) ToUnixDateString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(UnixDateFormat) +} + +// ToUnixDateString 输出RubyDate格式字符串 +func (c Carbon) ToRubyDateString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RubyDateFormat) +} + +// ToKitchenString 输出Kitchen格式字符串 +func (c Carbon) ToKitchenString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(KitchenFormat) +} + +// ToRfc822String 输出RFC822格式字符串 +func (c Carbon) ToRfc822String() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RFC822Format) +} + +// ToRfc822zString 输出RFC822Z格式字符串 +func (c Carbon) ToRfc822zString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RFC822ZFormat) +} + +// ToRfc850String 输出RFC850格式字符串 +func (c Carbon) ToRfc850String() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RFC850Format) +} + +// ToRfc1036String 输出RFC1036格式字符串 +func (c Carbon) ToRfc1036String() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RFC1036Format) +} + +// ToRfc1123String 输出RFC1123格式字符串 +func (c Carbon) ToRfc1123String() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RFC1123Format) +} + +// ToRfc1123ZString 输出RFC1123Z格式字符串 +func (c Carbon) ToRfc1123ZString() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RFC1123ZFormat) +} + +// ToRfc2822String 输出RFC2822格式字符串 +func (c Carbon) ToRfc2822String() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RFC2822Format) +} + +// ToRfc3339String 输出RFC3339格式字符串 +func (c Carbon) ToRfc3339String() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RFC3339Format) +} + +// ToRfc7231String 输出RFC7231格式字符串 +func (c Carbon) ToRfc7231String() string { + if c.IsZero() { + return "" + } + return c.Time.In(c.Loc).Format(RFC7231Format) +} diff --git a/display_test.go b/display_test.go new file mode 100755 index 0000000..23f7ca4 --- /dev/null +++ b/display_test.go @@ -0,0 +1,576 @@ +package carbon + +import ( + "testing" +) + +func TestCarbon_ToString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-08-05 13:14:15", "2020-08-05 13:14:15 +0800 CST"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToTimestamp(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int64 // 期望输出值 + }{ + {"2020-01-01 13:14:15", 1577855655}, + {"2020-01-31 13:14:15", 1580447655}, + {"2020-02-01 13:14:15", 1580534055}, + {"2020-02-28 13:14:15", 1582866855}, + {"2020-02-29 13:14:15", 1582953255}, + } + + for _, v := range Tests { + output := Parse(v.input).ToTimestamp() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_ToTimestampWithSecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int64 // 期望输出值 + }{ + {"2020-01-01 13:14:15", 1577855655}, + {"2020-01-31 13:14:15", 1580447655}, + {"2020-02-01 13:14:15", 1580534055}, + {"2020-02-28 13:14:15", 1582866855}, + {"2020-02-29 13:14:15", 1582953255}, + } + + for _, v := range Tests { + output := Parse(v.input).ToTimestampWithSecond() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_ToTimestampWithMillisecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int64 // 期望输出值 + }{ + {"2020-01-01 13:14:15", 1577855655000}, + {"2020-01-31 13:14:15", 1580447655000}, + {"2020-02-01 13:14:15", 1580534055000}, + {"2020-02-28 13:14:15", 1582866855000}, + {"2020-02-29 13:14:15", 1582953255000}, + } + + for _, v := range Tests { + output := Parse(v.input).ToTimestampWithMillisecond() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_ToTimestampWithMicrosecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int64 // 期望输出值 + }{ + {"2020-01-01 13:14:15", 1577855655000000}, + {"2020-01-31 13:14:15", 1580447655000000}, + {"2020-02-01 13:14:15", 1580534055000000}, + {"2020-02-28 13:14:15", 1582866855000000}, + {"2020-02-29 13:14:15", 1582953255000000}, + } + + for _, v := range Tests { + output := Parse(v.input).ToTimestampWithMicrosecond() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_ToTimestampWithNanosecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int64 // 期望输出值 + }{ + {"2020-01-01 13:14:15", 1577855655000000000}, + {"2020-01-31 13:14:15", 1580447655000000000}, + {"2020-02-01 13:14:15", 1580534055000000000}, + {"2020-02-28 13:14:15", 1582866855000000000}, + {"2020-02-29 13:14:15", 1582953255000000000}, + } + + for _, v := range Tests { + output := Parse(v.input).ToTimestampWithNanosecond() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Format(t *testing.T) { + Tests := []struct { + input string // 输入值 + format string // 输入参数 + output string // 期望输出值 + }{ + {"", "Y年m月d日", ""}, + {"0000-00-00 00:00:00", "Y年m月d日", ""}, + {"0000-00-00", "Y年m月d日", ""}, + {"00:00:00", "Y年m月d日", ""}, + {"2020-08-05 13:14:15", "Y年m月d日", "2020年08月05日"}, + {"2020-08-05 01:14:15", "j", "5"}, + {"2020-08-05 01:14:15", "W", "32"}, + {"2020-08-05 01:14:15", "M", "Aug"}, + {"2020-08-05 01:14:15", "F", "August"}, + {"2020-08-05 01:14:15", "N", "3"}, + {"2020-08-05 01:14:15", "L", "1"}, + {"2020-08-05 01:14:15", "L", "1"}, + {"2021-08-05 01:14:15", "L", "0"}, + {"2020-08-05 01:14:15", "G", "1"}, + {"2020-08-05 13:14:15", "U", "1596604455"}, + {"2020-08-05 13:14:15.999", "u", "999"}, + {"2020-08-05 13:14:15", "w", "2"}, + {"2020-08-05 13:14:15", "t", "31"}, + {"2020-08-05 13:14:15", "z", "217"}, + {"2020-08-05 13:14:15", "e", "Local"}, + {"2020-08-05 13:14:15", "jS", "5th"}, + {"2020-08-22 13:14:15", "jS", "22nd"}, + {"2020-08-23 13:14:15", "jS", "23rd"}, + {"2020-08-31 13:14:15", "jS", "31st"}, + {"2020-08-05 13:14:15", "l jS \\o\\f F Y h:i:s A", "Wednesday 5th of August 2020 01:14:15 PM"}, + } + + for _, v := range Tests { + output := Parse(v.input).Format(v.format) + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToDayDateTimeString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"", ""}, + {"0000-00-00 00:00:00", ""}, + {"0000-00-00", ""}, + {"00:00:00", ""}, + {"2020-08-05 13:14:15", "Wed, Aug 5, 2020 1:14 PM"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToDayDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToDateTimeString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"", ""}, + {"0000-00-00 00:00:00", ""}, + {"0000-00-00", ""}, + {"00:00:00", ""}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:15"}, + {"2020-08-05", "2020-08-05 00:00:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToDateString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"", ""}, + {"0000-00-00 00:00:00", ""}, + {"0000-00-00", ""}, + {"00:00:00", ""}, + {"2020-08-05 13:14:15", "2020-08-05"}, + {"2020-08-05", "2020-08-05"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToTimeString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "13:14:15"}, + {"2020-08-05", "00:00:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToAtomString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "2020-08-05T13:14:15+08:00"}, + {"2020-08-05", "2020-08-05T00:00:00+08:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToAtomString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToAnsicString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wed Aug 5 13:14:15 2020"}, + {"2020-08-05", "Wed Aug 5 00:00:00 2020"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToAnsicString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToCookieString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wednesday, 05-Aug-2020 13:14:15 CST"}, + {"2020-08-05", "Wednesday, 05-Aug-2020 00:00:00 CST"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToCookieString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRssString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wed, 05 Aug 2020 13:14:15 +0800"}, + {"2020-08-05", "Wed, 05 Aug 2020 00:00:00 +0800"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRssString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToW3cString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "2020-08-05T13:14:15+08:00"}, + {"2020-08-05", "2020-08-05T00:00:00+08:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToW3cString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToUnixDateString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wed Aug 5 13:14:15 CST 2020"}, + {"2020-08-05", "Wed Aug 5 00:00:00 CST 2020"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToUnixDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRubyDateString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wed Aug 05 13:14:15 +0800 2020"}, + {"2020-08-05", "Wed Aug 05 00:00:00 +0800 2020"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRubyDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToKitchenString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "1:14PM"}, + {"2020-08-05", "12:00AM"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToKitchenString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRfc822String(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "05 Aug 20 13:14 CST"}, + {"2020-08-05", "05 Aug 20 00:00 CST"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRfc822String() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRfc822zString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "05 Aug 20 13:14 +0800"}, + {"2020-08-05", "05 Aug 20 00:00 +0800"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRfc822zString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRfc850String(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wednesday, 05-Aug-20 13:14:15 CST"}, + {"2020-08-05", "Wednesday, 05-Aug-20 00:00:00 CST"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRfc850String() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRfc1036String(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wed, 05 Aug 20 13:14:15 +0800"}, + {"2020-08-05", "Wed, 05 Aug 20 00:00:00 +0800"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRfc1036String() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRfc1123String(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wed, 05 Aug 2020 13:14:15 CST"}, + {"2020-08-05", "Wed, 05 Aug 2020 00:00:00 CST"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRfc1123String() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRfc1123ZString(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wed, 05 Aug 2020 13:14:15 +0800"}, + {"2020-08-05", "Wed, 05 Aug 2020 00:00:00 +0800"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRfc1123ZString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRfc2822String(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wed, 05 Aug 2020 13:14:15 +0800"}, + {"2020-08-05", "Wed, 05 Aug 2020 00:00:00 +0800"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRfc2822String() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRfc3339String(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "2020-08-05T13:14:15+08:00"}, + {"2020-08-05", "2020-08-05T00:00:00+08:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRfc3339String() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_ToRfc7231String(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "Wed, 05 Aug 2020 13:14:15 GMT"}, + {"2020-08-05", "Wed, 05 Aug 2020 00:00:00 GMT"}, + } + + for _, v := range Tests { + output := Parse(v.input).ToRfc7231String() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} diff --git a/final.go b/final.go deleted file mode 100755 index 9e32ab8..0000000 --- a/final.go +++ /dev/null @@ -1,832 +0,0 @@ -package carbon - -import ( - "bytes" - "strconv" - "strings" - "time" -) - -// ToString 输出"2006-01-02 15:04:05.999999999 -0700 MST"格式字符串 -func (c Carbon) ToString() string { - return c.Time.In(c.Loc).String() -} - -// ToTimestamp ToTimestampWithSecond的简称 -func (c Carbon) ToTimestamp() int64 { - return c.ToTimestampWithSecond() -} - -// ToTimestampWithSecond 输出秒级时间戳 -func (c Carbon) ToTimestampWithSecond() int64 { - return c.Time.Unix() -} - -// ToTimestampWithMillisecond 输出毫秒级时间戳 -func (c Carbon) ToTimestampWithMillisecond() int64 { - return c.Time.UnixNano() / int64(time.Millisecond) -} - -// ToTimestampWithMicrosecond 输出微秒级时间戳 -func (c Carbon) ToTimestampWithMicrosecond() int64 { - return c.Time.UnixNano() / int64(time.Microsecond) -} - -// ToTimestampWithNanosecond 输出纳秒级时间戳 -func (c Carbon) ToTimestampWithNanosecond() int64 { - return c.Time.UnixNano() -} - -// Format ToFormatString的简称 -func (c Carbon) Format(format string) string { - return c.ToFormatString(format) -} - -// ToFormatString 输出指定格式时间 -func (c Carbon) ToFormatString(format string) string { - if c.IsZero() { - return "" - } - - runes := []rune(format) - buffer := bytes.NewBuffer(nil) - for i := 0; i < len(runes); i++ { - if layout, ok := formats[byte(runes[i])]; ok { - buffer.WriteString(c.Time.In(c.Loc).Format(layout)) - } else { - switch runes[i] { - case '\\': - buffer.WriteRune(runes[i+1]) - i += 2 - continue - case 'W': // ISO-8601 格式数字表示的年份中的第几周,取值范围 1-52 - buffer.WriteString(strconv.Itoa(c.WeekOfYear())) - case 'N': // ISO-8601 格式数字表示的星期中的第几天,取值范围 1-7 - buffer.WriteString(strconv.Itoa(c.DayOfWeek())) - case 'S': // 月份中第几天的英文缩写后缀,如st, nd, rd, th - suffix := "th" - switch c.Day() { - case 1, 21, 31: - suffix = "st" - case 2, 22: - suffix = "nd" - case 3, 23: - suffix = "rd" - } - buffer.WriteString(suffix) - case 'L': // 是否为闰年,如果是闰年为 1,否则为 0 - if c.IsLeapYear() { - buffer.WriteString("1") - } else { - buffer.WriteString("0") - } - case 'G': // 数字表示的小时,24 小时格式,没有前导零,取值范围 0-23 - buffer.WriteString(strconv.Itoa(c.Hour())) - case 'U': // 秒级时间戳,如 1611818268 - buffer.WriteString(strconv.FormatInt(c.ToTimestamp(), 10)) - case 'u': // 数字表示的毫秒,如 999 - buffer.WriteString(strconv.Itoa(c.Millisecond())) - case 'w': // 数字表示的星期中的第几天,取值范围 0-6 - buffer.WriteString(strconv.Itoa(c.DayOfWeek() - 1)) - case 't': // 指定的月份有几天,取值范围 28-31 - buffer.WriteString(strconv.Itoa(c.DaysInMonth())) - case 'z': // 年份中的第几天,取值范围 0-365 - buffer.WriteString(strconv.Itoa(c.DayOfYear() - 1)) - case 'e': // 当前时区,如 UTC,GMT,Atlantic/Azores - buffer.WriteString(c.Timezone()) - default: - buffer.WriteRune(runes[i]) - } - } - } - return buffer.String() -} - -// ToDayDateTimeString 输出天数日期时间字符串 -func (c Carbon) ToDayDateTimeString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(DayDateTimeFormat) -} - -// ToDateTimeString 输出日期时间字符串 -func (c Carbon) ToDateTimeString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(DateTimeFormat) -} - -// ToDateString 输出日期字符串 -func (c Carbon) ToDateString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(DateFormat) -} - -// ToTimeString 输出时间字符串 -func (c Carbon) ToTimeString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(TimeFormat) -} - -// ToAtomString 输出Atom格式字符串 -func (c Carbon) ToAtomString() string { - return c.ToRfc3339String() -} - -// ToAnsicString 输出Ansic格式字符串 -func (c Carbon) ToAnsicString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(AnsicFormat) -} - -// ToCookieString 输出Cookie格式字符串 -func (c Carbon) ToCookieString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(CookieFormat) -} - -// ToRssString 输出RSS格式字符串 -func (c Carbon) ToRssString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RssFormat) -} - -// ToW3cString 输出W3C格式字符串 -func (c Carbon) ToW3cString() string { - return c.ToRfc3339String() -} - -// ToUnixDateString 输出UnixDate格式字符串 -func (c Carbon) ToUnixDateString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(UnixDateFormat) -} - -// ToUnixDateString 输出RubyDate格式字符串 -func (c Carbon) ToRubyDateString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RubyDateFormat) -} - -// ToKitchenString 输出Kitchen格式字符串 -func (c Carbon) ToKitchenString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(KitchenFormat) -} - -// ToRfc822String 输出RFC822格式字符串 -func (c Carbon) ToRfc822String() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RFC822Format) -} - -// ToRfc822zString 输出RFC822Z格式字符串 -func (c Carbon) ToRfc822zString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RFC822ZFormat) -} - -// ToRfc850String 输出RFC850格式字符串 -func (c Carbon) ToRfc850String() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RFC850Format) -} - -// ToRfc1036String 输出RFC1036格式字符串 -func (c Carbon) ToRfc1036String() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RFC1036Format) -} - -// ToRfc1123String 输出RFC1123格式字符串 -func (c Carbon) ToRfc1123String() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RFC1123Format) -} - -// ToRfc1123ZString 输出RFC1123Z格式字符串 -func (c Carbon) ToRfc1123ZString() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RFC1123ZFormat) -} - -// ToRfc2822String 输出RFC2822格式字符串 -func (c Carbon) ToRfc2822String() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RFC2822Format) -} - -// ToRfc3339String 输出RFC3339格式字符串 -func (c Carbon) ToRfc3339String() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RFC3339Format) -} - -// ToRfc7231String 输出RFC7231格式字符串 -func (c Carbon) ToRfc7231String() string { - if c.IsZero() { - return "" - } - return c.Time.In(c.Loc).Format(RFC7231Format) -} - -// DiffInYears 相差多少年 -func (start Carbon) DiffInYears(end Carbon) int64 { - return int64(start.DiffInMonths(end) / 12) -} - -// DiffInYearsWithAbs 相差多少年(绝对值) -func (start Carbon) DiffInYearsWithAbs(end Carbon) int64 { - return getAbsValue(start.DiffInYears(end)) -} - -// DiffInMonths 相差多少月 -func (start Carbon) DiffInMonths(end Carbon) int64 { - return int64((end.Year()-start.Year())*MonthsPerYear + end.Month() - start.Month()) -} - -// DiffInMonthsWithAbs 相差多少月(绝对值) -func (start Carbon) DiffInMonthsWithAbs(end Carbon) int64 { - return getAbsValue(start.DiffInMonths(end)) -} - -// DiffInWeeks 相差多少周 -func (start Carbon) DiffInWeeks(end Carbon) int64 { - return start.DiffInDays(end) / DaysPerWeek -} - -// DiffInWeeksWithAbs 相差多少周(绝对值) -func (start Carbon) DiffInWeeksWithAbs(end Carbon) int64 { - return getAbsValue(start.DiffInWeeks(end)) -} - -// DiffInDays 相差多少天 -func (start Carbon) DiffInDays(end Carbon) int64 { - return start.DiffInSeconds(end) / SecondsPerDay -} - -// DiffInDaysWithAbs 相差多少天(绝对值) -func (start Carbon) DiffInDaysWithAbs(end Carbon) int64 { - return getAbsValue(start.DiffInDays(end)) -} - -// DiffInHours 相差多少小时 -func (start Carbon) DiffInHours(end Carbon) int64 { - return start.DiffInSeconds(end) / SecondsPerHour -} - -// DiffInHoursWithAbs 相差多少小时(绝对值) -func (start Carbon) DiffInHoursWithAbs(end Carbon) int64 { - return getAbsValue(start.DiffInHours(end)) -} - -// DiffInMinutes 相差多少分钟 -func (start Carbon) DiffInMinutes(end Carbon) int64 { - return start.DiffInSeconds(end) / SecondsPerMinute -} - -// DiffInMinutesWithAbs 相差多少分钟(绝对值) -func (start Carbon) DiffInMinutesWithAbs(end Carbon) int64 { - return getAbsValue(start.DiffInMinutes(end)) -} - -// DiffInSeconds 相差多少秒 -func (start Carbon) DiffInSeconds(end Carbon) int64 { - if start.Time.IsZero() && end.Time.IsZero() { - return 0 - } - - if end.Time.IsZero() { - return -start.ToTimestamp() - } - if start.Time.IsZero() { - return end.ToTimestamp() - } - - return end.ToTimestamp() - start.ToTimestamp() -} - -// DiffInSecondsWithAbs 相差多少秒(绝对值) -func (start Carbon) DiffInSecondsWithAbs(end Carbon) int64 { - return getAbsValue(start.DiffInSeconds(end)) -} - -// DiffForHumans 获取对人类友好的可读格式时间差 -func (c Carbon) DiffForHumans() string { - var unit string - var count int64 - now := c.Now() - switch true { - case c.DiffInYearsWithAbs(now) > 0: - unit = "year" - count = c.DiffInYearsWithAbs(now) - break - case c.DiffInMonthsWithAbs(now) > 0: - unit = "month" - count = c.DiffInMonthsWithAbs(now) - break - case c.DiffInWeeksWithAbs(now) > 0: - unit = "week" - count = c.DiffInWeeksWithAbs(now) - break - case c.DiffInDaysWithAbs(now) > 0: - unit = "day" - count = c.DiffInDaysWithAbs(now) - break - case c.DiffInHoursWithAbs(now) > 0: - unit = "hour" - count = c.DiffInHoursWithAbs(now) - break - case c.DiffInMinutesWithAbs(now) > 0: - unit = "minute" - count = c.DiffInMinutesWithAbs(now) - break - case c.DiffInSecondsWithAbs(now) > 10: - unit = "second" - count = c.DiffInSecondsWithAbs(now) - break - case c.DiffInSecondsWithAbs(now) <= 10: - unit = "now" - count = 0 - break - } - - locale := NewLanguage().locale - if c.Lang != nil && c.Lang.locale != "" { - locale = c.Lang.locale - } - - c = c.SetLocale(locale) - translation := c.Lang.translate(unit, count) - if c.IsFuture() { - return strings.Replace(c.Lang.resources["future"], "{time}", translation, 1) - } - if c.IsPast() { - return strings.Replace(c.Lang.resources["past"], "{time}", translation, 1) - } - return c.Lang.resources["now"] -} - -// DaysInYear 获取本年的总天数 -func (c Carbon) DaysInYear() int { - if c.IsZero() { - return 0 - } - days := DaysPerNormalYear - if c.IsLeapYear() { - days = DaysPerLeapYear - } - return days -} - -// DaysInMonth 获取本月的总天数 -func (c Carbon) DaysInMonth() int { - if c.IsZero() { - return 0 - } - return c.EndOfMonth().Time.In(c.Loc).Day() -} - -// MonthOfYear 获取本年的第几月 -func (c Carbon) MonthOfYear() int { - if c.IsZero() { - return 0 - } - return int(c.Time.In(c.Loc).Month()) -} - -// DayOfYear 获取本年的第几天 -func (c Carbon) DayOfYear() int { - if c.IsZero() { - return 0 - } - return c.Time.In(c.Loc).YearDay() -} - -// DayOfMonth 获取本月的第几天 -func (c Carbon) DayOfMonth() int { - if c.IsZero() { - return 0 - } - return c.Time.In(c.Loc).Day() -} - -// DayOfWeek 获取本周的第几天 -func (c Carbon) DayOfWeek() int { - if c.IsZero() { - return 0 - } - return int(c.Time.In(c.Loc).Weekday()) -} - -// WeekOfYear 获取本年的第几周 -func (c Carbon) WeekOfYear() int { - if c.IsZero() { - return 0 - } - _, week := c.Time.In(c.Loc).ISOWeek() - return week -} - -// WeekOfMonth 获取本月的第几周 -func (c Carbon) WeekOfMonth() int { - if c.IsZero() { - return 0 - } - day := c.Time.In(c.Loc).Day() - if day < DaysPerWeek { - return 1 - } - return day%DaysPerWeek + 1 -} - -// Timezone 获取时区 -func (c Carbon) Timezone() string { - return c.Loc.String() -} - -// Locale 获取语言区域 -func (c Carbon) Locale() string { - return c.Lang.locale -} - -// Age 获取年龄 -func (c Carbon) Age() int { - if c.IsZero() { - return 0 - } - if c.ToTimestamp() > Now().ToTimestamp() { - return 0 - } - age := time.Now().Year() - c.Time.In(c.Loc).Year() - if int(time.Now().Month())*100+time.Now().Day() < int(c.Time.In(c.Loc).Month())*100+c.Time.In(c.Loc).Day() { - age = age - 1 - } - return age -} - -// 获取当前年 -func (c Carbon) Year() int { - if c.IsZero() { - return 0 - } - return c.Time.In(c.Loc).Year() -} - -// 获取当前季度 -func (c Carbon) Quarter() int { - if c.IsZero() { - return 0 - } - month := c.Time.In(c.Loc).Month() - quarter := 0 - switch { - case month >= 1 && month <= 3: - quarter = 1 - case month >= 4 && month <= 6: - quarter = 2 - case month >= 7 && month <= 9: - quarter = 3 - case month >= 10 && month <= 12: - quarter = 4 - } - return quarter -} - -// 获取当前月 -func (c Carbon) Month() int { - if c.IsZero() { - return 0 - } - return c.MonthOfYear() -} - -// 获取当前日 -func (c Carbon) Day() int { - if c.IsZero() { - return 0 - } - return c.DayOfMonth() -} - -// 获取当前小时 -func (c Carbon) Hour() int { - if c.IsZero() { - return 0 - } - return c.Time.In(c.Loc).Hour() -} - -// 获取当前分钟数 -func (c Carbon) Minute() int { - if c.IsZero() { - return 0 - } - return c.Time.In(c.Loc).Minute() -} - -// 获取当前秒数 -func (c Carbon) Second() int { - if c.IsZero() { - return 0 - } - return c.Time.In(c.Loc).Second() -} - -// 获取当前毫秒数 -func (c Carbon) Millisecond() int { - if c.IsZero() { - return 0 - } - return c.Time.In(c.Loc).Nanosecond() / 1e6 -} - -// 获取当前微秒数 -func (c Carbon) Microsecond() int { - if c.IsZero() { - return 0 - } - return c.Time.In(c.Loc).Nanosecond() / 1e9 -} - -// 获取当前纳秒数 -func (c Carbon) Nanosecond() int { - if c.IsZero() { - return 0 - } - return c.Time.In(c.Loc).Nanosecond() -} - -// IsZero 是否是零值 -func (c Carbon) IsZero() bool { - return c.Time.In(c.Loc).IsZero() -} - -// IsNow 是否是当前时间 -func (c Carbon) IsNow() bool { - return c.ToTimestamp() == c.Now().ToTimestamp() -} - -// IsFuture 是否是未来时间 -func (c Carbon) IsFuture() bool { - return c.ToTimestamp() > c.Now().ToTimestamp() -} - -// IsPast 是否是过去时间 -func (c Carbon) IsPast() bool { - return c.ToTimestamp() < c.Now().ToTimestamp() -} - -// IsLeapYear 是否是闰年 -func (c Carbon) IsLeapYear() bool { - year := c.Time.In(c.Loc).Year() - if year%400 == 0 || (year%4 == 0 && year%100 != 0) { - return true - } - return false -} - -// IsLongYear 是否是长年 -func (c Carbon) IsLongYear() bool { - t := time.Date(c.Year(), time.December, 31, 0, 0, 0, 0, c.Loc) - _, w := t.ISOWeek() - return w == weeksPerLongYear -} - -// IsJanuary 是否是一月 -func (c Carbon) IsJanuary() bool { - return c.Time.In(c.Loc).Month() == time.January -} - -// IsMonday 是否是二月 -func (c Carbon) IsFebruary() bool { - return c.Time.In(c.Loc).Month() == time.February -} - -// IsMarch 是否是三月 -func (c Carbon) IsMarch() bool { - return c.Time.In(c.Loc).Month() == time.March -} - -// IsApril 是否是四月 -func (c Carbon) IsApril() bool { - return c.Time.In(c.Loc).Month() == time.April -} - -// IsMay 是否是五月 -func (c Carbon) IsMay() bool { - return c.Time.In(c.Loc).Month() == time.May -} - -// IsJune 是否是六月 -func (c Carbon) IsJune() bool { - return c.Time.In(c.Loc).Month() == time.June -} - -// IsJuly 是否是七月 -func (c Carbon) IsJuly() bool { - return c.Time.In(c.Loc).Month() == time.July -} - -// IsAugust 是否是八月 -func (c Carbon) IsAugust() bool { - return c.Time.In(c.Loc).Month() == time.August -} - -// IsSeptember 是否是九月 -func (c Carbon) IsSeptember() bool { - return c.Time.In(c.Loc).Month() == time.September -} - -// IsOctober 是否是十月 -func (c Carbon) IsOctober() bool { - return c.Time.In(c.Loc).Month() == time.October -} - -// IsNovember 是否是十一月 -func (c Carbon) IsNovember() bool { - return c.Time.In(c.Loc).Month() == time.November -} - -// IsDecember 是否是十二月 -func (c Carbon) IsDecember() bool { - return c.Time.In(c.Loc).Month() == time.December -} - -// IsMonday 是否是周一 -func (c Carbon) IsMonday() bool { - return c.Time.In(c.Loc).Weekday() == time.Monday -} - -// IsTuesday 是否是周二 -func (c Carbon) IsTuesday() bool { - return c.Time.In(c.Loc).Weekday() == time.Tuesday -} - -// IsWednesday 是否是周三 -func (c Carbon) IsWednesday() bool { - return c.Time.In(c.Loc).Weekday() == time.Wednesday -} - -// IsThursday 是否是周四 -func (c Carbon) IsThursday() bool { - return c.Time.In(c.Loc).Weekday() == time.Thursday -} - -// IsFriday 是否是周五 -func (c Carbon) IsFriday() bool { - return c.Time.In(c.Loc).Weekday() == time.Friday -} - -// IsSaturday 是否是周六 -func (c Carbon) IsSaturday() bool { - return c.Time.In(c.Loc).Weekday() == time.Saturday -} - -// IsSunday 是否是周日 -func (c Carbon) IsSunday() bool { - return c.Time.In(c.Loc).Weekday() == time.Sunday -} - -// IsWeekday 是否是工作日 -func (c Carbon) IsWeekday() bool { - return !c.IsSaturday() && !c.IsSunday() -} - -// IsWeekend 是否是周末 -func (c Carbon) IsWeekend() bool { - return c.IsSaturday() || c.IsSunday() -} - -// IsYesterday 是否是昨天 -func (c Carbon) IsYesterday() bool { - return c.ToDateString() == Now().SubDay().ToDateString() -} - -// IsToday 是否是今天 -func (c Carbon) IsToday() bool { - return c.ToDateString() == c.Now().ToDateString() -} - -// IsTomorrow 是否是明天 -func (c Carbon) IsTomorrow() bool { - return c.ToDateString() == Now().AddDay().ToDateString() -} - -// Compare 时间比较 -func (c Carbon) Compare(operator string, t Carbon) bool { - switch operator { - case "=": - return c.Eq(t) - case "<>": - return !c.Eq(t) - case "!=": - return !c.Eq(t) - case ">": - return c.Gt(t) - case ">=": - return c.Gte(t) - case "<": - return c.Lt(t) - case "<=": - return c.Lte(t) - } - - return false -} - -// Gt 大于 -func (c Carbon) Gt(t Carbon) bool { - return c.Time.After(t.Time) -} - -// Lt 小于 -func (c Carbon) Lt(t Carbon) bool { - return c.Time.Before(t.Time) -} - -// Eq 等于 -func (c Carbon) Eq(t Carbon) bool { - return c.Time.Equal(t.Time) -} - -// Ne 不等于 -func (c Carbon) Ne(t Carbon) bool { - return !c.Eq(t) -} - -// Gte 大于等于 -func (c Carbon) Gte(t Carbon) bool { - return c.Gt(t) || c.Eq(t) -} - -// Lte 小于等于 -func (c Carbon) Lte(t Carbon) bool { - return c.Lt(t) || c.Eq(t) -} - -// Between 是否在两个时间之间(不包括这两个时间) -func (c Carbon) Between(start Carbon, end Carbon) bool { - if c.Gt(start) && c.Lt(end) { - return true - } - return false -} - -// BetweenIncludedStartTime 是否在两个时间之间(包括开始时间) -func (c Carbon) BetweenIncludedStartTime(start Carbon, end Carbon) bool { - if c.Gte(start) && c.Lt(end) { - return true - } - return false -} - -// BetweenIncludedEndTime 是否在两个时间之间(包括结束时间) -func (c Carbon) BetweenIncludedEndTime(start Carbon, end Carbon) bool { - if c.Gt(start) && c.Lte(end) { - return true - } - return false -} - -// BetweenIncludedBoth 是否在两个时间之间(包括这两个时间) -func (c Carbon) BetweenIncludedBoth(start Carbon, end Carbon) bool { - if c.Gte(start) && c.Lte(end) { - return true - } - return false -} diff --git a/final_test.go b/final_test.go deleted file mode 100755 index e9b667a..0000000 --- a/final_test.go +++ /dev/null @@ -1,2826 +0,0 @@ -package carbon - -import ( - "testing" -) - -func TestCarbon_Carbon2Time(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-08-05", "2020-08-05"}, - } - - for _, v := range Tests { - output := Parse(v.input).Carbon2Time().Format("2006-01-02") - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"2020-08-05 13:14:15", "2020-08-05 13:14:15 +0800 CST"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToTimestamp(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int64 // 期望输出值 - }{ - {"2020-01-01 13:14:15", 1577855655}, - {"2020-01-31 13:14:15", 1580447655}, - {"2020-02-01 13:14:15", 1580534055}, - {"2020-02-28 13:14:15", 1582866855}, - {"2020-02-29 13:14:15", 1582953255}, - } - - for _, v := range Tests { - output := Parse(v.input).ToTimestamp() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_ToTimestampWithSecond(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int64 // 期望输出值 - }{ - {"2020-01-01 13:14:15", 1577855655}, - {"2020-01-31 13:14:15", 1580447655}, - {"2020-02-01 13:14:15", 1580534055}, - {"2020-02-28 13:14:15", 1582866855}, - {"2020-02-29 13:14:15", 1582953255}, - } - - for _, v := range Tests { - output := Parse(v.input).ToTimestampWithSecond() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_ToTimestampWithMillisecond(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int64 // 期望输出值 - }{ - {"2020-01-01 13:14:15", 1577855655000}, - {"2020-01-31 13:14:15", 1580447655000}, - {"2020-02-01 13:14:15", 1580534055000}, - {"2020-02-28 13:14:15", 1582866855000}, - {"2020-02-29 13:14:15", 1582953255000}, - } - - for _, v := range Tests { - output := Parse(v.input).ToTimestampWithMillisecond() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_ToTimestampWithMicrosecond(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int64 // 期望输出值 - }{ - {"2020-01-01 13:14:15", 1577855655000000}, - {"2020-01-31 13:14:15", 1580447655000000}, - {"2020-02-01 13:14:15", 1580534055000000}, - {"2020-02-28 13:14:15", 1582866855000000}, - {"2020-02-29 13:14:15", 1582953255000000}, - } - - for _, v := range Tests { - output := Parse(v.input).ToTimestampWithMicrosecond() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_ToTimestampWithNanosecond(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int64 // 期望输出值 - }{ - {"2020-01-01 13:14:15", 1577855655000000000}, - {"2020-01-31 13:14:15", 1580447655000000000}, - {"2020-02-01 13:14:15", 1580534055000000000}, - {"2020-02-28 13:14:15", 1582866855000000000}, - {"2020-02-29 13:14:15", 1582953255000000000}, - } - - for _, v := range Tests { - output := Parse(v.input).ToTimestampWithNanosecond() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Format(t *testing.T) { - Tests := []struct { - input string // 输入值 - format string // 输入参数 - output string // 期望输出值 - }{ - {"", "Y年m月d日", ""}, - {"0000-00-00 00:00:00", "Y年m月d日", ""}, - {"0000-00-00", "Y年m月d日", ""}, - {"00:00:00", "Y年m月d日", ""}, - {"2020-08-05 13:14:15", "Y年m月d日", "2020年08月05日"}, - {"2020-08-05 01:14:15", "j", "5"}, - {"2020-08-05 01:14:15", "W", "32"}, - {"2020-08-05 01:14:15", "M", "Aug"}, - {"2020-08-05 01:14:15", "F", "August"}, - {"2020-08-05 01:14:15", "N", "3"}, - {"2020-08-05 01:14:15", "L", "1"}, - {"2020-08-05 01:14:15", "L", "1"}, - {"2021-08-05 01:14:15", "L", "0"}, - {"2020-08-05 01:14:15", "G", "1"}, - {"2020-08-05 13:14:15", "U", "1596604455"}, - {"2020-08-05 13:14:15.999", "u", "999"}, - {"2020-08-05 13:14:15", "w", "2"}, - {"2020-08-05 13:14:15", "t", "31"}, - {"2020-08-05 13:14:15", "z", "217"}, - {"2020-08-05 13:14:15", "e", "Local"}, - {"2020-08-05 13:14:15", "jS", "5th"}, - {"2020-08-22 13:14:15", "jS", "22nd"}, - {"2020-08-23 13:14:15", "jS", "23rd"}, - {"2020-08-31 13:14:15", "jS", "31st"}, - {"2020-08-05 13:14:15", "l jS \\o\\f F Y h:i:s A", "Wednesday 5th of August 2020 01:14:15 PM"}, - } - - for _, v := range Tests { - output := Parse(v.input).Format(v.format) - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToDayDateTimeString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"", ""}, - {"0000-00-00 00:00:00", ""}, - {"0000-00-00", ""}, - {"00:00:00", ""}, - {"2020-08-05 13:14:15", "Wed, Aug 5, 2020 1:14 PM"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToDayDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToDateTimeString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"", ""}, - {"0000-00-00 00:00:00", ""}, - {"0000-00-00", ""}, - {"00:00:00", ""}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:15"}, - {"2020-08-05", "2020-08-05 00:00:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToDateTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToDateString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"", ""}, - {"0000-00-00 00:00:00", ""}, - {"0000-00-00", ""}, - {"00:00:00", ""}, - {"2020-08-05 13:14:15", "2020-08-05"}, - {"2020-08-05", "2020-08-05"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToTimeString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "13:14:15"}, - {"2020-08-05", "00:00:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToTimeString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToAtomString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "2020-08-05T13:14:15+08:00"}, - {"2020-08-05", "2020-08-05T00:00:00+08:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToAtomString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToAnsicString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wed Aug 5 13:14:15 2020"}, - {"2020-08-05", "Wed Aug 5 00:00:00 2020"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToAnsicString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToCookieString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wednesday, 05-Aug-2020 13:14:15 CST"}, - {"2020-08-05", "Wednesday, 05-Aug-2020 00:00:00 CST"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToCookieString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRssString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wed, 05 Aug 2020 13:14:15 +0800"}, - {"2020-08-05", "Wed, 05 Aug 2020 00:00:00 +0800"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRssString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToW3cString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "2020-08-05T13:14:15+08:00"}, - {"2020-08-05", "2020-08-05T00:00:00+08:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToW3cString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToUnixDateString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wed Aug 5 13:14:15 CST 2020"}, - {"2020-08-05", "Wed Aug 5 00:00:00 CST 2020"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToUnixDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRubyDateString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wed Aug 05 13:14:15 +0800 2020"}, - {"2020-08-05", "Wed Aug 05 00:00:00 +0800 2020"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRubyDateString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToKitchenString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "1:14PM"}, - {"2020-08-05", "12:00AM"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToKitchenString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRfc822String(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "05 Aug 20 13:14 CST"}, - {"2020-08-05", "05 Aug 20 00:00 CST"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRfc822String() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRfc822zString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "05 Aug 20 13:14 +0800"}, - {"2020-08-05", "05 Aug 20 00:00 +0800"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRfc822zString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRfc850String(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wednesday, 05-Aug-20 13:14:15 CST"}, - {"2020-08-05", "Wednesday, 05-Aug-20 00:00:00 CST"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRfc850String() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRfc1036String(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wed, 05 Aug 20 13:14:15 +0800"}, - {"2020-08-05", "Wed, 05 Aug 20 00:00:00 +0800"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRfc1036String() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRfc1123String(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wed, 05 Aug 2020 13:14:15 CST"}, - {"2020-08-05", "Wed, 05 Aug 2020 00:00:00 CST"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRfc1123String() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRfc1123ZString(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wed, 05 Aug 2020 13:14:15 +0800"}, - {"2020-08-05", "Wed, 05 Aug 2020 00:00:00 +0800"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRfc1123ZString() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRfc2822String(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wed, 05 Aug 2020 13:14:15 +0800"}, - {"2020-08-05", "Wed, 05 Aug 2020 00:00:00 +0800"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRfc2822String() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRfc3339String(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "2020-08-05T13:14:15+08:00"}, - {"2020-08-05", "2020-08-05T00:00:00+08:00"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRfc3339String() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_ToRfc7231String(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"0000-00-00 00:00:00", ""}, - {"2020-08-05 13:14:15", "Wed, 05 Aug 2020 13:14:15 GMT"}, - {"2020-08-05", "Wed, 05 Aug 2020 00:00:00 GMT"}, - } - - for _, v := range Tests { - output := Parse(v.input).ToRfc7231String() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, v.output, output) - } - } -} - -func TestCarbon_DiffInYears(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"2020-08-05 13:14:15", "2020-07-28 13:14:00", 0}, - {"2020-12-31 13:14:15", "2021-01-01 13:14:15", 0}, - {"2020-08-05 13:14:15", "2021-08-28 13:14:59", 1}, - {"2020-08-05 13:14:15", "2018-08-28 13:14:59", -2}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInYears(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func Test1Carbon_DiffInYearsWithAbs(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"2020-08-05 13:14:15", "2020-07-28 13:14:00", 0}, - {"2020-12-31 13:14:15", "2021-01-01 13:14:15", 0}, - {"2020-08-05 13:14:15", "2021-08-28 13:14:59", 1}, - {"2020-08-05 13:14:15", "2018-08-28 13:14:59", 2}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInYearsWithAbs(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInMonths(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"2020-08-05 13:14:15", "2020-07-28 13:14:00", -1}, - {"2020-12-31 13:14:15", "2021-01-01 13:14:15", 1}, - {"2020-08-05 13:14:15", "2021-08-28 13:14:59", 12}, - {"2020-08-05 13:14:15", "2018-08-28 13:14:59", -24}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInMonths(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInMonthsWithAbs(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"2020-08-05 13:14:15", "2020-07-28 13:14:00", 1}, - {"2020-12-31 13:14:15", "2021-01-01 13:14:15", 1}, - {"2020-08-05 13:14:15", "2021-08-28 13:14:59", 12}, - {"2020-08-05 13:14:15", "2018-08-28 13:14:59", 24}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInMonthsWithAbs(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInWeeks(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"0000-00-00 00:00:00", "", 0}, - {"", "0000-00-00 00:00:00", 0}, - {"", "", 0}, - {"2020-08-05 13:14:15", "", -2639}, - {"", "2020-08-05 13:14:15", 2639}, - {"2020-08-05 13:14:15", "2020-07-28 13:14:00", -1}, - {"2020-08-05 13:14:15", "2020-07-28 13:14:15", -1}, - {"2020-08-05 13:14:15", "2020-07-28 13:14:59", -1}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:00", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, - {"2020-08-05 13:14:15", "2020-08-12 13:14:00", 0}, - {"2020-08-05 13:14:15", "2020-08-12 13:14:15", 1}, - {"2020-08-05 13:14:15", "2020-08-12 13:14:59", 1}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInWeeks(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInWeeksWithAbs(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"0000-00-00 00:00:00", "", 0}, - {"", "0000-00-00 00:00:00", 0}, - {"", "", 0}, - {"2020-08-05 13:14:15", "", 2639}, - {"", "2020-08-05 13:14:15", 2639}, - {"2020-08-05 13:14:15", "2020-07-28 13:14:00", 1}, - {"2020-08-05 13:14:15", "2020-07-28 13:14:15", 1}, - {"2020-08-05 13:14:15", "2020-07-28 13:14:59", 1}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:00", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, - {"2020-08-05 13:14:15", "2020-08-12 13:14:00", 0}, - {"2020-08-05 13:14:15", "2020-08-12 13:14:15", 1}, - {"2020-08-05 13:14:15", "2020-08-12 13:14:59", 1}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInWeeksWithAbs(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInDays(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"0000-00-00 00:00:00", "", 0}, - {"", "0000-00-00 00:00:00", 0}, - {"", "", 0}, - {"2020-08-05 13:14:15", "", -18479}, - {"", "2020-08-05 13:14:15", 18479}, - {"2020-08-05 13:14:15", "2020-08-04 13:00:00", -1}, - {"2020-08-05 13:14:15", "2020-08-04 13:14:15", -1}, - {"2020-08-05 13:14:15", "2020-08-04 13:14:59", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:00:00", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, - {"2020-08-05 13:14:15", "2020-08-06 13:00:00", 0}, - {"2020-08-05 13:14:15", "2020-08-06 13:14:15", 1}, - {"2020-08-05 13:14:15", "2020-08-06 13:14:59", 1}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInDays(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInDaysWithAbs(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"0000-00-00 00:00:00", "", 0}, - {"", "0000-00-00 00:00:00", 0}, - {"", "", 0}, - {"2020-08-05 13:14:15", "", 18479}, - {"", "2020-08-05 13:14:15", 18479}, - {"2020-08-05 13:14:15", "2020-08-04 13:00:00", 1}, - {"2020-08-05 13:14:15", "2020-08-04 13:14:15", 1}, - {"2020-08-05 13:14:15", "2020-08-04 13:14:59", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:00:00", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, - {"2020-08-05 13:14:15", "2020-08-06 13:00:00", 0}, - {"2020-08-05 13:14:15", "2020-08-06 13:14:15", 1}, - {"2020-08-05 13:14:15", "2020-08-06 13:14:59", 1}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInDaysWithAbs(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInHours(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"0000-00-00 00:00:00", "", 0}, - {"", "0000-00-00 00:00:00", 0}, - {"", "", 0}, - {"2020-08-05 13:14:15", "", -443501}, - {"", "2020-08-05 13:14:15", 443501}, - {"2020-08-05 13:14:15", "2020-08-05 12:14:00", -1}, - {"2020-08-05 13:14:15", "2020-08-05 12:14:15", -1}, - {"2020-08-05 13:14:15", "2020-08-05 12:14:59", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:00", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, - {"2020-08-05 13:14:15", "2020-08-05 14:14:00", 0}, - {"2020-08-05 13:14:15", "2020-08-05 14:14:15", 1}, - {"2020-08-05 13:14:15", "2020-08-05 14:14:59", 1}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInHours(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInHoursWithAbs(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"0000-00-00 00:00:00", "", 0}, - {"", "0000-00-00 00:00:00", 0}, - {"", "", 0}, - {"2020-08-05 13:14:15", "", 443501}, - {"", "2020-08-05 13:14:15", 443501}, - {"2020-08-05 13:14:15", "2020-08-05 12:14:00", 1}, - {"2020-08-05 13:14:15", "2020-08-05 12:14:15", 1}, - {"2020-08-05 13:14:15", "2020-08-05 12:14:59", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:00", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:15", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:14:59", 0}, - {"2020-08-05 13:14:15", "2020-08-05 14:14:00", 0}, - {"2020-08-05 13:14:15", "2020-08-05 14:14:15", 1}, - {"2020-08-05 13:14:15", "2020-08-05 14:14:59", 1}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInHoursWithAbs(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInMinutes(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"0000-00-00 00:00:00", "", 0}, - {"", "0000-00-00 00:00:00", 0}, - {"", "", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:13:00", -1}, - {"2020-08-05 13:14:15", "2020-08-05 13:13:15", -1}, - {"2020-08-05 13:14:15", "2020-08-05 13:13:59", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:15:00", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:15:15", 1}, - {"2020-08-05 13:14:15", "2020-08-05 13:15:59", 1}, - {"2020-08-05 13:14:15", "2020-08-05 13:16:00", 1}, - {"2020-08-05 13:14:15", "2020-08-05 13:16:15", 2}, - {"2020-08-05 13:14:15", "2020-08-05 13:16:59", 2}, - {"2020-08-05 13:14:15", "", -26610074}, - {"", "2010-08-05 13:14:15", 21349754}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInMinutes(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInMinutesWithAbs(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"0000-00-00 00:00:00", "", 0}, - {"", "0000-00-00 00:00:00", 0}, - {"", "", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:13:00", 1}, - {"2020-08-05 13:14:15", "2020-08-05 13:13:15", 1}, - {"2020-08-05 13:14:15", "2020-08-05 13:13:59", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:15:00", 0}, - {"2020-08-05 13:14:15", "2020-08-05 13:15:15", 1}, - {"2020-08-05 13:14:15", "2020-08-05 13:15:59", 1}, - {"2020-08-05 13:14:15", "2020-08-05 13:16:00", 1}, - {"2020-08-05 13:14:15", "2020-08-05 13:16:15", 2}, - {"2020-08-05 13:14:15", "2020-08-05 13:16:59", 2}, - {"2020-08-05 13:14:15", "", 26610074}, - {"", "2010-08-05 13:14:15", 21349754}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInMinutesWithAbs(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInSeconds(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"0000-00-00 00:00:00", "", 0}, - {"", "0000-00-00 00:00:00", 0}, - {"", "", 0}, - {"2020-08-05 13:14:15", "", -1596604455}, - {"", "2010-08-05 13:14:15", 1280985255}, - {"2020-08-05 13:14:15", "2010-08-05 13:14:15", -315619200}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInSeconds(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffInSecondsWithAbs(t *testing.T) { - Tests := []struct { - input1 string // 输入值1 - input2 string // 输入值2 - output int64 // 期望输出值 - }{ - {"0000-00-00 00:00:00", "", 0}, - {"", "0000-00-00 00:00:00", 0}, - {"", "", 0}, - {"2020-08-05 13:14:15", "", 1596604455}, - {"", "2010-08-05 13:14:15", 1280985255}, - {"2020-08-05 13:14:15", "2010-08-05 13:14:15", 315619200}, - } - - for _, v := range Tests { - output := Parse(v.input1).DiffInSecondsWithAbs(Parse(v.input2)) - - if output != v.output { - t.Fatalf("Input start time %s and end time %s, expected %d, but got %d", v.input1, v.input2, v.output, output) - } - } -} - -func TestCarbon_DiffForHumans1(t *testing.T) { - Tests := []struct { - input string // 输入值1 - output string // 期望输出值 - }{ - {Now().ToDateTimeString(), "just now"}, - {Now().AddYears(1).ToDateTimeString(), "in 1 year"}, - {Now().SubYears(1).ToDateTimeString(), "1 year ago"}, - {Now().AddYears(10).ToDateTimeString(), "in 10 years"}, - {Now().SubYears(10).ToDateTimeString(), "10 years ago"}, - - {Now().AddMonths(1).ToDateTimeString(), "in 1 month"}, - {Now().SubMonths(1).ToDateTimeString(), "1 month ago"}, - {Now().AddMonths(10).ToDateTimeString(), "in 10 months"}, - {Now().SubMonths(10).ToDateTimeString(), "10 months ago"}, - } - - for _, v := range Tests { - output := Parse(v.input).DiffForHumans() - - if output != v.output { - t.Fatalf("Input time %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_DiffForHumans2(t *testing.T) { - Tests := []struct { - input string // 输入值1 - output string // 期望输出值 - }{ - {Now().ToDateTimeString(), "刚刚"}, - {Now().AddYears(1).ToDateTimeString(), "1 年后"}, - {Now().SubYears(1).ToDateTimeString(), "1 年前"}, - {Now().AddYears(10).ToDateTimeString(), "10 年后"}, - {Now().SubYears(10).ToDateTimeString(), "10 年前"}, - - {Now().AddMonths(1).ToDateTimeString(), "1 月后"}, - {Now().SubMonths(1).ToDateTimeString(), "1 月前"}, - {Now().AddMonths(10).ToDateTimeString(), "10 月后"}, - {Now().SubMonths(10).ToDateTimeString(), "10 月前"}, - } - - for _, v := range Tests { - output := Parse(v.input).SetLocale("zh-CN").DiffForHumans() - - if output != v.output { - t.Fatalf("Input time %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_DaysInYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"0000-00-00 00:00:00", 0}, - {"2020-08-05", 366}, - {"2021-08-05", 365}, - } - - for _, v := range Tests { - output := Parse(v.input).DaysInYear() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_DaysInMonth(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"0000-00-00 00:00:00", 0}, - {"2020-01-05", 31}, - {"2020-02-05", 29}, - {"2020-03-05", 31}, - {"2020-04-05", 30}, - {"2020-05-05", 31}, - {"2021-06-05", 30}, - {"2021-07-05", 31}, - {"2021-08-05", 31}, - {"2021-09-05", 30}, - {"2021-10-05", 31}, - {"2021-11-05", 30}, - {"2021-12-05", 31}, - } - - for _, v := range Tests { - output := Parse(v.input).DaysInMonth() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_MonthOfYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"0000-00-00 00:00:00", 0}, - {"2020-01-05", 1}, - {"2020-02-05", 2}, - {"2020-03-05", 3}, - {"2020-04-05", 4}, - {"2020-05-05", 5}, - {"2021-06-05", 6}, - {"2021-07-05", 7}, - {"2021-08-05", 8}, - {"2021-09-05", 9}, - {"2021-10-05", 10}, - {"2021-11-05", 11}, - {"2021-12-05", 12}, - } - - for _, v := range Tests { - output := Parse(v.input).MonthOfYear() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_DayOfYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"0000-00-00", 0}, - {"2020-01-01", 1}, - {"2020-01-31", 31}, - {"2020-08-05", 218}, - } - - for _, v := range Tests { - output := Parse(v.input).DayOfYear() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_DayOfMonth(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"0000-00-00", 0}, - {"2020-01-01", 1}, - {"2020-01-31", 31}, - {"2020-08-05", 5}, - } - - for _, v := range Tests { - output := Parse(v.input).DayOfMonth() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_DayOfWeek(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"0000-00-00", 0}, - {"2020-01-01", 3}, - {"2020-01-31", 5}, - {"2020-02-28", 5}, - {"2020-01-29", 3}, - {"2020-08-05", 3}, - } - - for _, v := range Tests { - output := Parse(v.input).DayOfWeek() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_WeekOfYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"0000-00-00", 0}, - {"2019-12-31", 1}, - {"2020-01-01", 1}, - {"2020-01-31", 5}, - {"2020-02-28", 9}, - {"2020-01-29", 5}, - {"2020-08-05", 32}, - } - - for _, v := range Tests { - output := Parse(v.input).WeekOfYear() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_WeekOfMonth(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"0000-00-00", 0}, - {"2020-01-01", 1}, - {"2020-01-31", 4}, - {"2020-02-28", 1}, - {"2020-01-29", 2}, - {"2020-08-05", 1}, - } - - for _, v := range Tests { - output := Parse(v.input).WeekOfMonth() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Timezone(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {PRC, PRC}, - {Tokyo, Tokyo}, - } - - for _, v := range Tests { - output := SetTimezone(v.input).Timezone() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_Locale(t *testing.T) { - Tests := []struct { - input string // 输入值 - output string // 期望输出值 - }{ - {"en", "en"}, - {"zh-CN", "zh-CN"}, - } - - for _, v := range Tests { - output := Now().SetLocale(v.input).Locale() - - if output != v.output { - t.Fatalf("Input %s, expected %s, but got %s", v.input, v.output, output) - } - } -} - -func TestCarbon_Age(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0", 0}, - {"0000-00-00", 0}, - {Now().AddYears(18).ToDateTimeString(), 0}, - {Now().SubYears(18).ToDateTimeString(), 18}, - {CreateFromDate(Now().Year(), 12, 31).SubYears(18).ToDateTimeString(), 17}, - } - - for _, v := range Tests { - output := Parse(v.input).Age() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Year(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0000-00-00", 0}, - {"2020-08-05", 2020}, - } - - for _, v := range Tests { - output := Parse(v.input).Year() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Quarter(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0000-00-00", 0}, - {"2020-01-05", 1}, - {"2020-04-05", 2}, - {"2020-08-05", 3}, - {"2020-11-05", 4}, - } - - for _, v := range Tests { - output := Parse(v.input).Quarter() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Month(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0000-00-00 00:00:00", 0}, - {"0000-00-00", 0}, - {"2020-08-05 13:14:15", 8}, - {"2020-08-05", 8}, - } - - for _, v := range Tests { - output := Parse(v.input).Month() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Day(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0000-00-00 00:00:00", 0}, - {"0000-00-00", 0}, - {"2020-08-05 13:14:15", 5}, - {"2020-08-05", 5}, - } - - for _, v := range Tests { - output := Parse(v.input).Day() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Hour(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0000-00-00 00:00:00", 0}, - {"0000-00-00", 0}, - {"2020-08-05 13:14:15", 13}, - {"2020-08-05", 0}, - } - - for _, v := range Tests { - output := Parse(v.input).Hour() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Minute(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0000-00-00 00:00:00", 0}, - {"0000-00-00", 0}, - {"2020-08-05 13:14:15", 14}, - {"2020-08-05", 0}, - } - - for _, v := range Tests { - output := Parse(v.input).Minute() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Second(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0000-00-00 00:00:00", 0}, - {"0000-00-00", 0}, - {"2020-08-05 13:14:15", 15}, - {"2020-08-05", 0}, - } - - for _, v := range Tests { - output := Parse(v.input).Second() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Millisecond(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0000-00-00 00:00:00", 0}, - {"0000-00-00", 0}, - {"2020-08-05 13:14:15", 0}, - {"2020-08-05", 0}, - } - - for _, v := range Tests { - output := Parse(v.input).Millisecond() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Microsecond(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0000-00-00 00:00:00", 0}, - {"0000-00-00", 0}, - {"2020-08-05 13:14:15", 0}, - {"2020-08-05", 0}, - } - - for _, v := range Tests { - output := Parse(v.input).Microsecond() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_Nanosecond(t *testing.T) { - Tests := []struct { - input string // 输入值 - output int // 期望输出值 - }{ - {"", 0}, - {"0000-00-00 00:00:00", 0}, - {"0000-00-00", 0}, - {"2020-08-05 13:14:15", 0}, - {"2020-08-05", 0}, - } - - for _, v := range Tests { - output := Parse(v.input).Nanosecond() - - if output != v.output { - t.Fatalf("Input %s, expected %d, but got %d", v.input, v.output, output) - } - } -} - -func TestCarbon_IsZero(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"0000-00-00 00:00:00", true}, - {"0000-00-00", true}, - {"2020-08-05 00:00:00", false}, - {"2020-08-05", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsZero() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsNow(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"0000-00-00 00:00:00", false}, - {Tomorrow().ToDateTimeString(), false}, - {Now().ToDateTimeString(), true}, - {Yesterday().ToDateTimeString(), false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsNow() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsFuture(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"0000-00-00 00:00:00", false}, - {Tomorrow().ToDateTimeString(), true}, - {Now().ToDateTimeString(), false}, - {Yesterday().ToDateTimeString(), false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsFuture() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsPast(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"0000-00-00 00:00:00", true}, - {Tomorrow().ToDateTimeString(), false}, - {Now().ToDateTimeString(), false}, - {Yesterday().ToDateTimeString(), true}, - } - - for _, v := range Tests { - output := Parse(v.input).IsPast() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsLeapYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2016-01-01", true}, - {"2017-01-01", false}, - {"2018-01-01", false}, - {"2019-01-01", false}, - {"2020-01-01", true}, - } - - for _, v := range Tests { - output := Parse(v.input).IsLeapYear() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsLongYear(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2015-01-01", true}, - {"2016-01-01", false}, - {"2017-01-01", false}, - {"2018-01-01", false}, - {"2019-01-01", false}, - {"2020-01-01", true}, - } - - for _, v := range Tests { - output := Parse(v.input).IsLongYear() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsJanuary(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", true}, - {"2020-02-01", false}, - {"2020-03-01", false}, - {"2020-04-01", false}, - {"2020-05-01", false}, - {"2020-06-01", false}, - {"2020-07-01", false}, - {"2020-08-01", false}, - {"2020-09-01", false}, - {"2020-10-01", false}, - {"2020-11-01", false}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsJanuary() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsFebruary(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", true}, - {"2020-03-01", false}, - {"2020-04-01", false}, - {"2020-05-01", false}, - {"2020-06-01", false}, - {"2020-07-01", false}, - {"2020-08-01", false}, - {"2020-09-01", false}, - {"2020-10-01", false}, - {"2020-11-01", false}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsFebruary() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsMarch(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", false}, - {"2020-03-01", true}, - {"2020-04-01", false}, - {"2020-05-01", false}, - {"2020-06-01", false}, - {"2020-07-01", false}, - {"2020-08-01", false}, - {"2020-09-01", false}, - {"2020-10-01", false}, - {"2020-11-01", false}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsMarch() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsApril(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", false}, - {"2020-03-01", false}, - {"2020-04-01", true}, - {"2020-05-01", false}, - {"2020-06-01", false}, - {"2020-07-01", false}, - {"2020-08-01", false}, - {"2020-09-01", false}, - {"2020-10-01", false}, - {"2020-11-01", false}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsApril() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsMay(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", false}, - {"2020-03-01", false}, - {"2020-04-01", false}, - {"2020-05-01", true}, - {"2020-06-01", false}, - {"2020-07-01", false}, - {"2020-08-01", false}, - {"2020-09-01", false}, - {"2020-10-01", false}, - {"2020-11-01", false}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsMay() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsJune(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", false}, - {"2020-03-01", false}, - {"2020-04-01", false}, - {"2020-05-01", false}, - {"2020-06-01", true}, - {"2020-07-01", false}, - {"2020-08-01", false}, - {"2020-09-01", false}, - {"2020-10-01", false}, - {"2020-11-01", false}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsJune() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsJuly(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", false}, - {"2020-03-01", false}, - {"2020-04-01", false}, - {"2020-05-01", false}, - {"2020-06-01", false}, - {"2020-07-01", true}, - {"2020-08-01", false}, - {"2020-09-01", false}, - {"2020-10-01", false}, - {"2020-11-01", false}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsJuly() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsAugust(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", false}, - {"2020-03-01", false}, - {"2020-04-01", false}, - {"2020-05-01", false}, - {"2020-06-01", false}, - {"2020-07-01", false}, - {"2020-08-01", true}, - {"2020-09-01", false}, - {"2020-10-01", false}, - {"2020-11-01", false}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsAugust() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsSeptember(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", false}, - {"2020-03-01", false}, - {"2020-04-01", false}, - {"2020-05-01", false}, - {"2020-06-01", false}, - {"2020-07-01", false}, - {"2020-08-01", false}, - {"2020-09-01", true}, - {"2020-10-01", false}, - {"2020-11-01", false}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsSeptember() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsOctober(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", false}, - {"2020-03-01", false}, - {"2020-04-01", false}, - {"2020-05-01", false}, - {"2020-06-01", false}, - {"2020-07-01", false}, - {"2020-08-01", false}, - {"2020-09-01", false}, - {"2020-10-01", true}, - {"2020-11-01", false}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsOctober() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsNovember(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", false}, - {"2020-03-01", false}, - {"2020-04-01", false}, - {"2020-05-01", false}, - {"2020-06-01", false}, - {"2020-07-01", false}, - {"2020-08-01", false}, - {"2020-09-01", false}, - {"2020-10-01", false}, - {"2020-11-01", true}, - {"2020-12-01", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsNovember() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsDecember(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-01-01", false}, - {"2020-02-01", false}, - {"2020-03-01", false}, - {"2020-04-01", false}, - {"2020-05-01", false}, - {"2020-06-01", false}, - {"2020-07-01", false}, - {"2020-08-01", false}, - {"2020-09-01", false}, - {"2020-10-01", false}, - {"2020-11-01", false}, - {"2020-12-01", true}, - } - - for _, v := range Tests { - output := Parse(v.input).IsDecember() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsMonday(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-10-05", true}, - {"2020-10-06", false}, - {"2020-10-07", false}, - {"2020-10-08", false}, - {"2020-10-09", false}, - {"2020-10-10", false}, - {"2020-10-11", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsMonday() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsTuesday(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-10-05", false}, - {"2020-10-06", true}, - {"2020-10-07", false}, - {"2020-10-08", false}, - {"2020-10-09", false}, - {"2020-10-10", false}, - {"2020-10-11", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsTuesday() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsWednesday(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-10-05", false}, - {"2020-10-06", false}, - {"2020-10-07", true}, - {"2020-10-08", false}, - {"2020-10-09", false}, - {"2020-10-10", false}, - {"2020-10-11", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsWednesday() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsThursday(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-10-05", false}, - {"2020-10-06", false}, - {"2020-10-07", false}, - {"2020-10-08", true}, - {"2020-10-09", false}, - {"2020-10-10", false}, - {"2020-10-11", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsThursday() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsFriday(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-10-05", false}, - {"2020-10-06", false}, - {"2020-10-07", false}, - {"2020-10-08", false}, - {"2020-10-09", true}, - {"2020-10-10", false}, - {"2020-10-11", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsFriday() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsSaturday(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-10-05", false}, - {"2020-10-06", false}, - {"2020-10-07", false}, - {"2020-10-08", false}, - {"2020-10-09", false}, - {"2020-10-10", true}, - {"2020-10-11", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsSaturday() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsSunday(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-10-05", false}, - {"2020-10-06", false}, - {"2020-10-07", false}, - {"2020-10-08", false}, - {"2020-10-09", false}, - {"2020-10-10", false}, - {"2020-10-11", true}, - } - - for _, v := range Tests { - output := Parse(v.input).IsSunday() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsWeekday(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-10-05", true}, - {"2020-10-06", true}, - {"2020-10-07", true}, - {"2020-10-08", true}, - {"2020-10-09", true}, - {"2020-10-10", false}, - {"2020-10-11", false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsWeekday() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsWeekend(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {"2020-10-05", false}, - {"2020-10-06", false}, - {"2020-10-07", false}, - {"2020-10-08", false}, - {"2020-10-09", false}, - {"2020-10-10", true}, - {"2020-10-11", true}, - } - - for _, v := range Tests { - output := Parse(v.input).IsWeekend() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsYesterday(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {Now().ToDateTimeString(), false}, - {Yesterday().ToDateTimeString(), true}, - {Tomorrow().ToDateTimeString(), false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsYesterday() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsToday(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {Now().ToDateTimeString(), true}, - {Yesterday().ToDateTimeString(), false}, - {Tomorrow().ToDateTimeString(), false}, - } - - for _, v := range Tests { - output := Parse(v.input).IsToday() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_IsTomorrow(t *testing.T) { - Tests := []struct { - input string // 输入值 - output bool // 期望输出值 - }{ - {Now().ToDateTimeString(), false}, - {Yesterday().ToDateTimeString(), false}, - {Tomorrow().ToDateTimeString(), true}, - } - - for _, v := range Tests { - output := Parse(v.input).IsTomorrow() - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s, expected %s, but got %s\n", v.input, expected, reality) - } - } -} - -func TestCarbon_Compare(t *testing.T) { - now := Now() - tomorrow := Tomorrow() - yesterday := Yesterday() - Tests := []struct { - input Carbon // 输入值 - operator string // 输入参数 - time Carbon // 输入参数 - output bool // 期望输出值 - }{ - {now, ">", yesterday, true}, - {now, "<", yesterday, false}, - {now, "<", tomorrow, true}, - {now, ">", tomorrow, false}, - {now, "=", now, true}, - {now, ">=", now, true}, - {now, "<=", now, true}, - {now, "!=", now, false}, - {now, "<>", now, false}, - {now, "!=", yesterday, true}, - {now, "<>", yesterday, true}, - {now, "+", yesterday, false}, - } - - for _, v := range Tests { - output := v.input.Compare(v.operator, v.time) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s %s %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.operator, v.time.ToDateTimeString(), expected, reality) - } - } -} - -func TestCarbon_Gt(t *testing.T) { - now := Now() - tomorrow := Tomorrow() - yesterday := Yesterday() - Tests := []struct { - input Carbon // 输入值 - time Carbon // 输入参数 - output bool // 期望输出值 - }{ - {now, now, false}, - {now, yesterday, true}, - {now, tomorrow, false}, - } - - for _, v := range Tests { - output := v.input.Gt(v.time) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s > %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) - } - } -} - -func TestCarbon_Lt(t *testing.T) { - now := Now() - tomorrow := Tomorrow() - yesterday := Yesterday() - Tests := []struct { - input Carbon // 输入值 - time Carbon // 输入参数 - output bool // 期望输出值 - }{ - {now, now, false}, - {now, yesterday, false}, - {now, tomorrow, true}, - } - - for _, v := range Tests { - output := v.input.Lt(v.time) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s < %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) - } - } -} - -func TestCarbon_Eq(t *testing.T) { - now := Now() - tomorrow := Tomorrow() - yesterday := Yesterday() - Tests := []struct { - input Carbon // 输入值 - time Carbon // 输入参数 - output bool // 期望输出值 - }{ - {now, now, true}, - {now, yesterday, false}, - {now, tomorrow, false}, - } - - for _, v := range Tests { - output := v.input.Eq(v.time) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s = %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) - } - } -} - -func TestCarbon_Ne(t *testing.T) { - now := Now() - tomorrow := Tomorrow() - yesterday := Yesterday() - Tests := []struct { - input Carbon // 输入值 - time Carbon // 输入参数 - output bool // 期望输出值 - }{ - {now, now, false}, - {now, yesterday, true}, - {now, tomorrow, true}, - } - - for _, v := range Tests { - output := v.input.Ne(v.time) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s != %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) - } - } -} - -func TestCarbon_Gte(t *testing.T) { - now := Now() - tomorrow := Tomorrow() - yesterday := Yesterday() - Tests := []struct { - input Carbon // 输入值 - time Carbon // 输入参数 - output bool // 期望输出值 - }{ - {now, now, true}, - {now, yesterday, true}, - {now, tomorrow, false}, - } - - for _, v := range Tests { - output := v.input.Gte(v.time) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s >= %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) - } - } -} - -func TestCarbon_Lte(t *testing.T) { - now := Now() - tomorrow := Tomorrow() - yesterday := Yesterday() - Tests := []struct { - input Carbon // 输入值 - time Carbon // 输入参数 - output bool // 期望输出值 - }{ - {now, now, true}, - {now, yesterday, false}, - {now, tomorrow, true}, - } - - for _, v := range Tests { - output := v.input.Lte(v.time) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s <= %s, expected %s, but got %s\n", v.input.ToDateTimeString(), v.time.ToDateTimeString(), expected, reality) - } - } -} - -func TestCarbon_Between(t *testing.T) { - Tests := []struct { - input Carbon // 输入值 - time1 Carbon // 输入参数 - time2 Carbon // 输入参数 - output bool // 期望输出值 - }{ - {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), false}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-06 13:14:15"), false}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-05 13:14:15"), false}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-06 13:14:15"), true}, - } - - for _, v := range Tests { - output := v.input.Between(v.time1, v.time2) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s < %s < %s, expected %s, but got %s\n", v.time1.ToDateTimeString(), v.input.ToDateTimeString(), v.time2.ToDateTimeString(), expected, reality) - } - } -} - -func TestCarbon_BetweenIncludedStartTime(t *testing.T) { - Tests := []struct { - input Carbon // 输入值 - time1 Carbon // 输入参数 - time2 Carbon // 输入参数 - output bool // 期望输出值 - }{ - {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), false}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-06 13:14:15"), true}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-05 13:14:15"), false}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-06 13:14:15"), true}, - } - - for _, v := range Tests { - output := v.input.BetweenIncludedStartTime(v.time1, v.time2) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s <= %s < %s, expected %s, but got %s\n", v.time1.ToDateTimeString(), v.input.ToDateTimeString(), v.time2.ToDateTimeString(), expected, reality) - } - } -} - -func TestCarbon_BetweenIncludedEndTime(t *testing.T) { - Tests := []struct { - input Carbon // 输入值 - time1 Carbon // 输入参数 - time2 Carbon // 输入参数 - output bool // 期望输出值 - }{ - {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), false}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-06 13:14:15"), false}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-05 13:14:15"), true}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-06 13:14:15"), true}, - } - - for _, v := range Tests { - output := v.input.BetweenIncludedEndTime(v.time1, v.time2) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s < %s <= %s, expected %s, but got %s\n", v.time1.ToDateTimeString(), v.input.ToDateTimeString(), v.time2.ToDateTimeString(), expected, reality) - } - } -} - -func TestCarbon_BetweenIncludedBoth(t *testing.T) { - Tests := []struct { - input Carbon // 输入值 - time1 Carbon // 输入参数 - time2 Carbon // 输入参数 - output bool // 期望输出值 - }{ - {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), true}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-05 13:14:15"), Parse("2020-08-06 13:14:15"), true}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-05 13:14:15"), true}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-04 13:14:15"), Parse("2020-08-06 13:14:15"), true}, - {Parse("2020-08-05 13:14:15"), Parse("2020-08-06 13:14:15"), Parse("2020-08-06 13:14:15"), false}, - } - - for _, v := range Tests { - output := v.input.BetweenIncludedBoth(v.time1, v.time2) - - if output != v.output { - expected := "false" - if v.output == true { - expected = "true" - } - - reality := "false" - if output == true { - reality = "true" - } - t.Fatalf("Input %s <= %s <= %s, expected %s, but got %s\n", v.time1.ToDateTimeString(), v.input.ToDateTimeString(), v.time2.ToDateTimeString(), expected, reality) - } - } -} diff --git a/getter.go b/getter.go new file mode 100755 index 0000000..0d8c624 --- /dev/null +++ b/getter.go @@ -0,0 +1,187 @@ +package carbon + +// DaysInYear 获取本年的总天数 +func (c Carbon) DaysInYear() int { + if c.IsZero() { + return 0 + } + days := DaysPerNormalYear + if c.IsLeapYear() { + days = DaysPerLeapYear + } + return days +} + +// DaysInMonth 获取本月的总天数 +func (c Carbon) DaysInMonth() int { + if c.IsZero() { + return 0 + } + return c.EndOfMonth().Time.In(c.Loc).Day() +} + +// MonthOfYear 获取本年的第几月 +func (c Carbon) MonthOfYear() int { + if c.IsZero() { + return 0 + } + return int(c.Time.In(c.Loc).Month()) +} + +// DayOfYear 获取本年的第几天 +func (c Carbon) DayOfYear() int { + if c.IsZero() { + return 0 + } + return c.Time.In(c.Loc).YearDay() +} + +// DayOfMonth 获取本月的第几天 +func (c Carbon) DayOfMonth() int { + if c.IsZero() { + return 0 + } + return c.Time.In(c.Loc).Day() +} + +// DayOfWeek 获取本周的第几天 +func (c Carbon) DayOfWeek() int { + if c.IsZero() { + return 0 + } + return int(c.Time.In(c.Loc).Weekday()) +} + +// WeekOfYear 获取本年的第几周 +func (c Carbon) WeekOfYear() int { + if c.IsZero() { + return 0 + } + _, week := c.Time.In(c.Loc).ISOWeek() + return week +} + +// WeekOfMonth 获取本月的第几周 +func (c Carbon) WeekOfMonth() int { + if c.IsZero() { + return 0 + } + day := c.Time.In(c.Loc).Day() + if day < DaysPerWeek { + return 1 + } + return day%DaysPerWeek + 1 +} + +// Timezone 获取时区 +func (c Carbon) Timezone() string { + return c.Loc.String() +} + +// Locale 获取语言区域 +func (c Carbon) Locale() string { + return c.Lang.locale +} + +// Age 获取年龄 +func (c Carbon) Age() int { + if c.IsZero() { + return 0 + } + now := Now() + if c.ToTimestamp() > now.ToTimestamp() { + return 0 + } + return int(c.DiffInYears(now)) +} + +// 获取当前年 +func (c Carbon) Year() int { + if c.IsZero() { + return 0 + } + return c.Time.In(c.Loc).Year() +} + +// 获取当前季度 +func (c Carbon) Quarter() int { + if c.IsZero() { + return 0 + } + month := c.Month() + switch { + case month >= 10: + return 4 + case month >= 7: + return 3 + case month >= 4: + return 2 + case month >= 1: + return 1 + } + return 0 +} + +// 获取当前月 +func (c Carbon) Month() int { + if c.IsZero() { + return 0 + } + return c.MonthOfYear() +} + +// 获取当前日 +func (c Carbon) Day() int { + if c.IsZero() { + return 0 + } + return c.DayOfMonth() +} + +// 获取当前小时 +func (c Carbon) Hour() int { + if c.IsZero() { + return 0 + } + return c.Time.In(c.Loc).Hour() +} + +// 获取当前分钟数 +func (c Carbon) Minute() int { + if c.IsZero() { + return 0 + } + return c.Time.In(c.Loc).Minute() +} + +// 获取当前秒数 +func (c Carbon) Second() int { + if c.IsZero() { + return 0 + } + return c.Time.In(c.Loc).Second() +} + +// 获取当前毫秒数 +func (c Carbon) Millisecond() int { + if c.IsZero() { + return 0 + } + return c.Time.In(c.Loc).Nanosecond() / 1e6 +} + +// 获取当前微秒数 +func (c Carbon) Microsecond() int { + if c.IsZero() { + return 0 + } + return c.Time.In(c.Loc).Nanosecond() / 1e9 +} + +// 获取当前纳秒数 +func (c Carbon) Nanosecond() int { + if c.IsZero() { + return 0 + } + return c.Time.In(c.Loc).Nanosecond() +} diff --git a/getter_test.go b/getter_test.go new file mode 100755 index 0000000..f8b91a0 --- /dev/null +++ b/getter_test.go @@ -0,0 +1,456 @@ +package carbon + +import ( + "testing" +) + +func TestCarbon_DaysInYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"0000-00-00 00:00:00", 0}, + {"2020-08-05", 366}, + {"2021-08-05", 365}, + } + + for _, v := range Tests { + output := Parse(v.input).DaysInYear() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_DaysInMonth(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"0000-00-00 00:00:00", 0}, + {"2020-01-05", 31}, + {"2020-02-05", 29}, + {"2020-03-05", 31}, + {"2020-04-05", 30}, + {"2020-05-05", 31}, + {"2021-06-05", 30}, + {"2021-07-05", 31}, + {"2021-08-05", 31}, + {"2021-09-05", 30}, + {"2021-10-05", 31}, + {"2021-11-05", 30}, + {"2021-12-05", 31}, + } + + for _, v := range Tests { + output := Parse(v.input).DaysInMonth() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_MonthOfYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"0000-00-00 00:00:00", 0}, + {"2020-01-05", 1}, + {"2020-02-05", 2}, + {"2020-03-05", 3}, + {"2020-04-05", 4}, + {"2020-05-05", 5}, + {"2021-06-05", 6}, + {"2021-07-05", 7}, + {"2021-08-05", 8}, + {"2021-09-05", 9}, + {"2021-10-05", 10}, + {"2021-11-05", 11}, + {"2021-12-05", 12}, + } + + for _, v := range Tests { + output := Parse(v.input).MonthOfYear() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_DayOfYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"0000-00-00", 0}, + {"2020-01-01", 1}, + {"2020-01-31", 31}, + {"2020-08-05", 218}, + } + + for _, v := range Tests { + output := Parse(v.input).DayOfYear() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_DayOfMonth(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"0000-00-00", 0}, + {"2020-01-01", 1}, + {"2020-01-31", 31}, + {"2020-08-05", 5}, + } + + for _, v := range Tests { + output := Parse(v.input).DayOfMonth() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_DayOfWeek(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"0000-00-00", 0}, + {"2020-01-01", 3}, + {"2020-01-31", 5}, + {"2020-02-28", 5}, + {"2020-01-29", 3}, + {"2020-08-05", 3}, + } + + for _, v := range Tests { + output := Parse(v.input).DayOfWeek() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_WeekOfYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"0000-00-00", 0}, + {"2019-12-31", 1}, + {"2020-01-01", 1}, + {"2020-01-31", 5}, + {"2020-02-28", 9}, + {"2020-01-29", 5}, + {"2020-08-05", 32}, + } + + for _, v := range Tests { + output := Parse(v.input).WeekOfYear() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_WeekOfMonth(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"0000-00-00", 0}, + {"2020-01-01", 1}, + {"2020-01-31", 4}, + {"2020-02-28", 1}, + {"2020-01-29", 2}, + {"2020-08-05", 1}, + } + + for _, v := range Tests { + output := Parse(v.input).WeekOfMonth() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Timezone(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {PRC, PRC}, + {Tokyo, Tokyo}, + } + + for _, v := range Tests { + output := SetTimezone(v.input).Timezone() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_Locale(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"en", "en"}, + {"zh-CN", "zh-CN"}, + } + + for _, v := range Tests { + output := Now().SetLocale(v.input).Locale() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_Age(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0", 0}, + {"0000-00-00", 0}, + {Now().AddYears(18).ToDateTimeString(), 0}, + {Now().SubYears(18).ToDateTimeString(), 18}, + } + + for _, v := range Tests { + output := Parse(v.input).Age() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Year(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0000-00-00", 0}, + {"2020-08-05", 2020}, + } + + for _, v := range Tests { + output := Parse(v.input).Year() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Quarter(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0000-00-00", 0}, + {"2020-01-05", 1}, + {"2020-04-05", 2}, + {"2020-08-05", 3}, + {"2020-11-05", 4}, + {"2020-11-33", 0}, + } + + for _, v := range Tests { + output := Parse(v.input).Quarter() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Month(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0000-00-00 00:00:00", 0}, + {"0000-00-00", 0}, + {"2020-08-05 13:14:15", 8}, + {"2020-08-05", 8}, + } + + for _, v := range Tests { + output := Parse(v.input).Month() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Day(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0000-00-00 00:00:00", 0}, + {"0000-00-00", 0}, + {"2020-08-05 13:14:15", 5}, + {"2020-08-05", 5}, + } + + for _, v := range Tests { + output := Parse(v.input).Day() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Hour(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0000-00-00 00:00:00", 0}, + {"0000-00-00", 0}, + {"2020-08-05 13:14:15", 13}, + {"2020-08-05", 0}, + } + + for _, v := range Tests { + output := Parse(v.input).Hour() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Minute(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0000-00-00 00:00:00", 0}, + {"0000-00-00", 0}, + {"2020-08-05 13:14:15", 14}, + {"2020-08-05", 0}, + } + + for _, v := range Tests { + output := Parse(v.input).Minute() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Second(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0000-00-00 00:00:00", 0}, + {"0000-00-00", 0}, + {"2020-08-05 13:14:15", 15}, + {"2020-08-05", 0}, + } + + for _, v := range Tests { + output := Parse(v.input).Second() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Millisecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0000-00-00 00:00:00", 0}, + {"0000-00-00", 0}, + {"2020-08-05 13:14:15", 0}, + {"2020-08-05", 0}, + } + + for _, v := range Tests { + output := Parse(v.input).Millisecond() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Microsecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0000-00-00 00:00:00", 0}, + {"0000-00-00", 0}, + {"2020-08-05 13:14:15", 0}, + {"2020-08-05", 0}, + } + + for _, v := range Tests { + output := Parse(v.input).Microsecond() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} + +func TestCarbon_Nanosecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output int // 期望输出值 + }{ + {"", 0}, + {"0000-00-00 00:00:00", 0}, + {"0000-00-00", 0}, + {"2020-08-05 13:14:15", 0}, + {"2020-08-05", 0}, + } + + for _, v := range Tests { + output := Parse(v.input).Nanosecond() + + if output != v.output { + t.Errorf("Input %s, expected %d, but got %d", v.input, v.output, output) + } + } +} diff --git a/private.go b/helper.go similarity index 98% rename from private.go rename to helper.go index 0d9c202..a446b0e 100755 --- a/private.go +++ b/helper.go @@ -76,6 +76,5 @@ func parseByDuration(duration string) (time.Duration, error) { // getAbsValue 获取绝对值 func getAbsValue(value int64) int64 { - y := value >> 63 - return (value ^ y) - y + return (value ^ value>>31) - value>>31 } diff --git a/lang/en.json b/lang/en.json index 38bb73c..e6fc285 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1,12 +1,14 @@ { - "year":"1 year|{count} years", - "month":"1 month|{count} months", - "week":"1 week|{count} weeks", - "day":"1 day|{count} days", - "hour":"1 hour|{count} hours", - "minute":"1 minute|{count} minutes", - "second":"1 second|{count} seconds", + "year":"1 year|%d years", + "month":"1 month|%d months", + "week":"1 week|%d weeks", + "day":"1 day|%d days", + "hour":"1 hour|%d hours", + "minute":"1 minute|%d minutes", + "second":"1 second|%d seconds", "now": "just now", - "past":"{time} ago", - "future":"in {time}" + "ago":"%s ago", + "from_now":"%s from now", + "before":"%s before", + "after":"%s after" } \ No newline at end of file diff --git a/lang/jp.json b/lang/jp.json new file mode 100755 index 0000000..55a4667 --- /dev/null +++ b/lang/jp.json @@ -0,0 +1,14 @@ +{ + "year":"%d 年", + "month":"%d ヶ月", + "week":"%d 週間", + "day":"%d 日", + "hour":"%d 時間", + "minute":"%d 分钟", + "second":"%d 秒", + "now": "たった今", + "ago":"%s前", + "from_now":"%s後", + "before":"%s前", + "after":"%s後" +} diff --git a/lang/zh-CN.json b/lang/zh-CN.json index 0a89fd9..2b9ed37 100755 --- a/lang/zh-CN.json +++ b/lang/zh-CN.json @@ -1,12 +1,14 @@ { - "year":"{count} 年", - "month":"{count} 月", - "week":"{count} 周", - "day":"{count} 天", - "hour":"{count} 小时", - "minute":"{count} 分钟", - "second":"{count} 秒", + "year":"%d 年", + "month":"%d 个月", + "week":"%d 周", + "day":"%d 天", + "hour":"%d 小时", + "minute":"%d 分钟", + "second":"%d 秒", "now": "刚刚", - "past":"{time}前", - "future":"{time}后" + "ago":"%s前", + "from_now":"%s后", + "before":"%s前", + "after":"%s后" } diff --git a/lang/zh-TW.json b/lang/zh-TW.json index e03fddd..0da4e41 100755 --- a/lang/zh-TW.json +++ b/lang/zh-TW.json @@ -1,12 +1,14 @@ { - "year":"{count} 年", - "month":"{count} 月", - "week":"{count} 周", - "day":"{count} 天", - "hour":"{count} 小時", - "minute":"{count} 分鐘", - "second":"{count} 秒", + "year":"%d 年", + "month":"%d 個月", + "week":"%d 週", + "day":"%d 天", + "hour":"%d 小時", + "minute":"%d 分鐘", + "second":"%d 秒", "now": "剛剛", - "past":"{time}前", - "future":"{time}後" + "ago":"%s前", + "from_now":"%s後", + "before":"%s前", + "after":"%s後" } diff --git a/language.go b/language.go index aa33623..0f04f2e 100755 --- a/language.go +++ b/language.go @@ -9,51 +9,77 @@ import ( "strings" ) +var ( + // 默认语言目录 + defaultDir = "lang" + // 默认语言区域 + defaultLocale = "en" +) + type Language struct { locale string dir string resources map[string]string } +// NewLanguage 初始化Language对象 func NewLanguage() *Language { return &Language{ - locale: "en", - dir: "./lang", + locale: "", + dir: defaultDir, resources: make(map[string]string), } } -// SetLocale 设置语言区域 +// SetLocale 设置区域 func (lang *Language) SetLocale(locale string) error { - err := lang.loadResource(locale) - if err == nil { - lang.locale = locale + if len(lang.resources) != 0 { + return nil } - return err -} - -// loadResource 加载资源 -func (lang *Language) loadResource(locale string) error { fileName := lang.dir + string(os.PathSeparator) + locale + ".json" bytes, err := ioutil.ReadFile(fileName) if err != nil { - return errors.New("not able to read the lang file:" + fileName) + return errors.New("invalid locale \"" + locale + "\", please see the " + lang.dir + " directory for all valid locale") } if err := json.Unmarshal(bytes, &lang.resources); err != nil { return err } + lang.locale = locale return nil } -// translate 翻译 -func (lang *Language) translate(unit string, count int64) string { - s := strings.Split(lang.resources[unit], "|") - if len(s) == 1 { - return strings.Replace(s[0], "{count}", strconv.FormatInt(count, 10), 1) +// SetDir 设置目录 +func (lang *Language) SetDir(dir string) error { + fi, err := os.Stat(dir) + if err != nil || !fi.IsDir() { + return errors.New("invalid directory \"" + dir + "\"") } - - if count > 1 { - return strings.Replace(s[1], "{count}", strconv.FormatInt(count, 10), 1) - } - return s[0] + lang.dir = dir + return nil +} + +// SetResources 设置资源 +func (lang *Language) SetResources(resources map[string]string) { + if len(lang.resources) == 0 { + lang.resources = resources + } else { + for k, v := range resources { + lang.resources[k] = v + } + } +} + +// translate 翻译转换 +func (lang *Language) translate(unit string, diff int64) string { + if len(lang.resources) == 0 { + lang.SetLocale(defaultLocale) + } + array := strings.Split(lang.resources[unit], "|") + if len(array) == 1 { + return strings.Replace(array[0], "%d", strconv.FormatInt(diff, 10), 1) + } + if diff > 1 { + return strings.Replace(array[1], "%d", strconv.FormatInt(diff, 10), 1) + } + return array[0] } diff --git a/language_test.go b/language_test.go new file mode 100755 index 0000000..adee96d --- /dev/null +++ b/language_test.go @@ -0,0 +1,102 @@ +package carbon + +import ( + "testing" +) + +func TestLanguage_SetLocale(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"en", true}, + {"zh-CN", true}, + {"zh-XX", false}, + } + + for _, v := range Tests { + output := NewLanguage().SetLocale(v.input) + + if output == nil { + if v.output == false { + t.Errorf("Input %s, expected true, but got false\n", v.input) + } + } else { + if v.output == true { + t.Errorf("Input %s, expected false, but got true\n", v.input) + } + } + } +} + +func TestLanguage_SetDir(t *testing.T) { + Tests := []struct { + input string // 输入值 + output bool // 期望输出值 + }{ + {"lang", true}, + {"xxxx", false}, + } + + for _, v := range Tests { + output := NewLanguage().SetDir(v.input) + + if output == nil { + if v.output == false { + t.Errorf("Input %s, expected true, but got false\n", v.input) + } + } else { + if v.output == true { + t.Errorf("Input %s, expected false, but got true\n", v.input) + } + } + } +} + +func TestLanguage_SetResources(t *testing.T) { + lang := NewLanguage() + resources := map[string]string{ + "year": "1 yr|%d yrs", + "month": "1 mo|%d mos", + "week": "%dw", + "day": "%dd", + "hour": "%dh", + "minute": "%dm", + "second": "%ds", + "now": "just now", + "ago": "%s ago", + "from_now": "in %s", + "before": "%s before", + "after": "%s after", + } + lang.SetResources(resources) + + Tests := []struct { + input Carbon // 输入值 + output string // 期望输出值 + }{ + {Now(), "just now"}, + {Now().AddYears(1), "in 1 yr"}, + {Now().SubYears(1), "1 yr ago"}, + {Now().AddYears(10), "in 10 yrs"}, + {Now().SubYears(10), "10 yrs ago"}, + + {Now().AddMonths(1), "in 1 mo"}, + {Now().SubMonths(1), "1 mo ago"}, + {Now().AddMonths(10), "in 10 mos"}, + {Now().SubMonths(10), "10 mos ago"}, + + {Now().AddDays(1), "in 1d"}, + {Now().SubDays(1), "1d ago"}, + {Now().AddDays(10), "in 1w"}, + {Now().SubDays(10), "1w ago"}, + } + + for _, v := range Tests { + output := (v.input).SetLanguage(lang).DiffForHumans() + + if output != v.output { + t.Errorf("Input time %s, expected %s, but got %s", v.input.ToDateTimeString(), v.output, output) + } + } +} diff --git a/modifier.go b/modifier.go new file mode 100755 index 0000000..451b021 --- /dev/null +++ b/modifier.go @@ -0,0 +1,98 @@ +package carbon + +import "time" + +// StartOfYear 本年开始时间 +func (c Carbon) StartOfYear() Carbon { + c.Time = time.Date(c.Time.Year(), 1, 1, 0, 0, 0, 0, c.Loc) + return c +} + +// EndOfYear 本年结束时间 +func (c Carbon) EndOfYear() Carbon { + c.Time = time.Date(c.Time.Year(), 12, 31, 23, 59, 59, 0, c.Loc) + return c +} + +// StartOfMonth 本月开始时间 +func (c Carbon) StartOfMonth() Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), 1, 0, 0, 0, 0, c.Loc) + return c +} + +// EndOfMonth 本月结束时间 +func (c Carbon) EndOfMonth() Carbon { + t := time.Date(c.Time.Year(), c.Time.Month(), 1, 23, 59, 59, 0, c.Loc) + c.Time = t.AddDate(0, 1, -1) + return c +} + +// StartOfWeek 本周开始时间 +func (c Carbon) StartOfWeek() Carbon { + days := c.Time.Weekday() + if days == 0 { + days = DaysPerWeek + } + t := time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), 0, 0, 0, 0, c.Loc) + c.Time = t.AddDate(0, 0, int(1-days)) + return c +} + +// EndOfWeek 本周结束时间 +func (c Carbon) EndOfWeek() Carbon { + days := c.Time.Weekday() + if days == 0 { + days = DaysPerWeek + } + t := time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), 23, 59, 59, 0, c.Loc) + c.Time = t.AddDate(0, 0, int(DaysPerWeek-days)) + return c +} + +// StartOfDay 本日开始时间 +func (c Carbon) StartOfDay() Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), 0, 0, 0, 0, c.Loc) + return c +} + +// EndOfDay 本日结束时间 +func (c Carbon) EndOfDay() Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), 23, 59, 59, 0, c.Loc) + return c +} + +// StartOfHour 小时开始时间 +func (c Carbon) StartOfHour() Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), 0, 0, 0, c.Loc) + return c +} + +// EndOfHour 小时结束时间 +func (c Carbon) EndOfHour() Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), 59, 59, 0, c.Loc) + return c +} + +// StartOfMinute 分钟开始时间 +func (c Carbon) StartOfMinute() Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), 0, 0, c.Loc) + return c +} + +// EndOfMinute 分钟结束时间 +func (c Carbon) EndOfMinute() Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), 59, 0, c.Loc) + return c +} + +// StartOfSecond 秒开始时间 +func (c Carbon) StartOfSecond() Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), c.Time.Second(), 0, c.Loc) + return c +} + +// EndOfSecond 秒结束时间 +func (c Carbon) EndOfSecond() Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), c.Time.Second(), 999999999, c.Loc) + return c +} diff --git a/modifier_test.go b/modifier_test.go new file mode 100755 index 0000000..c15eba8 --- /dev/null +++ b/modifier_test.go @@ -0,0 +1,301 @@ +package carbon + +import ( + "testing" +) + +func TestCarbon_StartOfYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-01-01 00:00:00"}, + {"2020-01-31 23:59:59", "2020-01-01 00:00:00"}, + {"2020-02-01 13:14:15", "2020-01-01 00:00:00"}, + {"2020-02-28", "2020-01-01 00:00:00"}, + {"2020-02-29", "2020-01-01 00:00:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).StartOfYear().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_EndOfYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-12-31 23:59:59"}, + {"2020-01-31 23:59:59", "2020-12-31 23:59:59"}, + {"2020-02-01 13:14:15", "2020-12-31 23:59:59"}, + {"2020-02-28", "2020-12-31 23:59:59"}, + {"2020-02-29", "2020-12-31 23:59:59"}, + } + + for _, v := range Tests { + output := Parse(v.input).EndOfYear().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_StartOfMonth(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-01-01 00:00:00"}, + {"2020-01-31 23:59:59", "2020-01-01 00:00:00"}, + {"2020-02-01 13:14:15", "2020-02-01 00:00:00"}, + {"2020-02-28", "2020-02-01 00:00:00"}, + {"2020-02-29", "2020-02-01 00:00:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).StartOfMonth().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_EndOfMonth(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-01-31 23:59:59"}, + {"2020-01-31 23:59:59", "2020-01-31 23:59:59"}, + {"2020-02-01 13:14:15", "2020-02-29 23:59:59"}, + {"2020-02-28", "2020-02-29 23:59:59"}, + {"2020-02-29", "2020-02-29 23:59:59"}, + } + + for _, v := range Tests { + output := Parse(v.input).EndOfMonth().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_StartOfWeek(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2019-12-30 00:00:00"}, + {"2020-01-31 23:59:59", "2020-01-27 00:00:00"}, + {"2020-02-01 13:14:15", "2020-01-27 00:00:00"}, + {"2020-02-28", "2020-02-24 00:00:00"}, + {"2020-02-29", "2020-02-24 00:00:00"}, + {"2020-10-04", "2020-09-28 00:00:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).StartOfWeek().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_EndOfWeek(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-01-05 23:59:59"}, + {"2020-01-31 23:59:59", "2020-02-02 23:59:59"}, + {"2020-02-01 13:14:15", "2020-02-02 23:59:59"}, + {"2020-02-28", "2020-03-01 23:59:59"}, + {"2020-02-29", "2020-03-01 23:59:59"}, + {"2020-10-04", "2020-10-04 23:59:59"}, + } + + for _, v := range Tests { + output := Parse(v.input).EndOfWeek().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_StartOfDay(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-01-01 00:00:00"}, + {"2020-01-31 23:59:59", "2020-01-31 00:00:00"}, + {"2020-02-01 13:14:15", "2020-02-01 00:00:00"}, + {"2020-02-28", "2020-02-28 00:00:00"}, + {"2020-02-29", "2020-02-29 00:00:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).StartOfDay().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_EndOfDay(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-01-01 23:59:59"}, + {"2020-01-31 23:59:59", "2020-01-31 23:59:59"}, + {"2020-02-01 13:14:15", "2020-02-01 23:59:59"}, + {"2020-02-28", "2020-02-28 23:59:59"}, + {"2020-02-29", "2020-02-29 23:59:59"}, + } + + for _, v := range Tests { + output := Parse(v.input).EndOfDay().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_StartOfHour(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-01-01 00:00:00"}, + {"2020-01-31 23:59:59", "2020-01-31 23:00:00"}, + {"2020-02-01 13:14:15", "2020-02-01 13:00:00"}, + {"2020-02-28", "2020-02-28 00:00:00"}, + {"2020-02-29", "2020-02-29 00:00:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).StartOfHour().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_EndOfHour(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-01-01 00:59:59"}, + {"2020-01-31 23:59:59", "2020-01-31 23:59:59"}, + {"2020-02-01 13:14:15", "2020-02-01 13:59:59"}, + {"2020-02-28", "2020-02-28 00:59:59"}, + {"2020-02-29", "2020-02-29 00:59:59"}, + } + + for _, v := range Tests { + output := Parse(v.input).EndOfHour().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_StartOfMinute(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-01-01 00:00:00"}, + {"2020-01-31 23:59:59", "2020-01-31 23:59:00"}, + {"2020-02-01 13:14:15", "2020-02-01 13:14:00"}, + {"2020-02-28", "2020-02-28 00:00:00"}, + {"2020-02-29", "2020-02-29 00:00:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).StartOfMinute().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_EndOfMinute(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00", "2020-01-01 00:00:59"}, + {"2020-01-31 23:59:59", "2020-01-31 23:59:59"}, + {"2020-02-01 13:14:15", "2020-02-01 13:14:59"}, + {"2020-02-28", "2020-02-28 00:00:59"}, + {"2020-02-29", "2020-02-29 00:00:59"}, + } + + for _, v := range Tests { + output := Parse(v.input).EndOfMinute().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_StartOfSecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00.123", "2020-01-01 00:00:00.0"}, + {"2020-01-31 23:59:59.123", "2020-01-31 23:59:59.0"}, + {"2020-02-01 13:14:15.123", "2020-02-01 13:14:15.0"}, + {"2020-02-28", "2020-02-28 00:00:00.0"}, + {"2020-02-29", "2020-02-29 00:00:00.0"}, + } + + for _, v := range Tests { + output := Parse(v.input).StartOfSecond().Format("Y-m-d H:i:s.u") + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_EndOfSecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 00:00:00.123", "2020-01-01 00:00:00.999"}, + {"2020-01-31 23:59:59.123", "2020-01-31 23:59:59.999"}, + {"2020-02-01 13:14:15.123", "2020-02-01 13:14:15.999"}, + {"2020-02-28", "2020-02-28 00:00:00.999"}, + {"2020-02-29", "2020-02-29 00:00:00.999"}, + } + + for _, v := range Tests { + output := Parse(v.input).EndOfSecond().Format("Y-m-d H:i:s.u") + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} diff --git a/parser.go b/parser.go new file mode 100755 index 0000000..f9113b2 --- /dev/null +++ b/parser.go @@ -0,0 +1,76 @@ +package carbon + +import ( + "strconv" + "strings" +) + +// Parse 将标准格式时间字符串解析成 Carbon 实例 +func (c Carbon) Parse(value string) Carbon { + if c.Error != nil { + return c + } + + layout := DateTimeFormat + + if value == "" || value == "0" || value == "0000-00-00 00:00:00" || value == "0000-00-00" || value == "00:00:00" { + return c + } + + if len(value) == 10 && strings.Count(value, "-") == 2 { + layout = DateFormat + } + + if strings.Index(value, "T") == 10 { + layout = RFC3339Format + } + + if _, err := strconv.ParseInt(value, 10, 64); err == nil { + switch len(value) { + case 8: + layout = ShortDateFormat + case 14: + layout = ShortDateTimeFormat + } + } + + tt, err := parseByLayout(value, layout) + c.Time = tt + c.Error = err + return c +} + +// Parse 将标准格式时间字符串解析成 Carbon 实例(默认时区) +func Parse(value string) Carbon { + return SetTimezone(Local).Parse(value) +} + +// ParseByFormat 将特殊格式时间字符串解析成 Carbon 实例 +func (c Carbon) ParseByFormat(value string, format string) Carbon { + if c.Error != nil { + return c + } + layout := format2layout(format) + return c.ParseByLayout(value, layout) +} + +// ParseByFormat 将特殊格式时间字符串解析成 Carbon 实例(默认时区) +func ParseByFormat(value string, format string) Carbon { + return SetTimezone(Local).ParseByFormat(value, format) +} + +// ParseByLayout 将布局时间字符串解析成 Carbon 实例 +func (c Carbon) ParseByLayout(value string, layout string) Carbon { + if c.Error != nil { + return c + } + tt, err := parseByLayout(value, layout) + c.Time = tt + c.Error = err + return c +} + +// ParseByLayout 将布局时间字符串解析成 Carbon 实例(默认时区) +func ParseByLayout(value string, layout string) Carbon { + return SetTimezone(Local).ParseByLayout(value, layout) +} diff --git a/parser_test.go b/parser_test.go new file mode 100755 index 0000000..e8c3554 --- /dev/null +++ b/parser_test.go @@ -0,0 +1,132 @@ +package carbon + +import ( + "fmt" + "testing" +) + +func TestCarbon_Parse(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"", ""}, + {"0", ""}, + {"0000-00-00", ""}, + {"0000-00-00 00:00:00", ""}, + {"2020-08-05 13:14:15", "2020-08-05 13:14:15"}, + {"20200805131415", "2020-08-05 13:14:15"}, + {"20200805", "2020-08-05 00:00:00"}, + {"2020-08-05", "2020-08-05 00:00:00"}, + {"2020-08-05T13:14:15+08:00", "2020-08-05 13:14:15"}, + {"12345678", ""}, // 异常情况 + } + + for _, v := range Tests { + output := Parse(v.input) + + if output.Error != nil { + fmt.Println("catch an exception in Parse():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input) + + if output.Error != nil { + fmt.Println("catch an exception in Parse():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) + } + } +} + +var ParseByFormatTests = []struct { + input string // 输入值 + format string // 输入参数 + output string // 期望输出值 +}{ + {"2020|08|05 13:14:15", "Y|m|d H:i:s", "2020-08-05 13:14:15"}, + {"It is 2020|08|05 13:14:15", "It is Y|m|d H:i:s", "2020-08-05 13:14:15"}, + {"今天是 2020年08月05日13时14分15秒", "今天是 Y年m月d日H时i分s秒", "2020-08-05 13:14:15"}, + {"12345678", "XXXX", ""}, // 异常情况 +} + +func TestCarbon_ParseByFormat1(t *testing.T) { + for _, v := range ParseByFormatTests { + output := ParseByFormat(v.input, v.format) + + if output.Error != nil { + fmt.Println("catch an exception in ParseByFormat():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) + } + } +} + +func TestCarbon_ParseByFormat2(t *testing.T) { + for _, v := range ParseByFormatTests { + output := SetTimezone("XXXX").ParseByFormat(v.input, v.format) + + if output.Error != nil { + fmt.Println("catch an exception in ParseByFormat():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) + } + } +} + +var ParseByLayoutTests = []struct { + input string // 输入值 + format string // 输入参数 + output string // 期望输出值 +}{ + {"2020|08|05 13:14:15", "2006|01|02 15:04:05", "2020-08-05 13:14:15"}, + {"It is 2020|08|05 13:14:15", "It is 2006|01|02 15:04:05", "2020-08-05 13:14:15"}, + {"今天是 2020年08月05日13时14分15秒", "今天是 2006年01月02日15时04分05秒", "2020-08-05 13:14:15"}, + {"12345678", "XXXX", ""}, // 异常情况 +} + +func TestCarbon_ParseByLayout1(t *testing.T) { + for _, v := range ParseByLayoutTests { + output := ParseByLayout(v.input, v.format) + + if output.Error != nil { + fmt.Println("catch an exception in ParseByLayout():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) + } + } +} + +func TestCarbon_ParseByLayout2(t *testing.T) { + for _, v := range ParseByLayoutTests { + output := SetTimezone("XXXX").ParseByLayout(v.input, v.format) + + if output.Error != nil { + fmt.Println("catch an exception in ParseByLayout():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) + } + } +} diff --git a/setter.go b/setter.go new file mode 100755 index 0000000..d388514 --- /dev/null +++ b/setter.go @@ -0,0 +1,87 @@ +package carbon + +import "time" + +// Timezone 设置时区 +func (c Carbon) SetTimezone(name string) Carbon { + loc, err := getLocationByTimezone(name) + c.Loc = loc + c.Error = err + return c +} + +// Timezone 设置时区 +func SetTimezone(name string) Carbon { + loc, err := getLocationByTimezone(name) + return Carbon{Loc: loc, Error: err, Lang: NewLanguage()} +} + +// SetLanguage 设置语言对象 +func (c Carbon) SetLanguage(lang *Language) Carbon { + if len(c.Lang.resources) == 0 { + c.Lang = lang + return c + } + for k, v := range lang.resources { + c.Lang.resources[k] = v + } + return c +} + +// SetLanguage 设置语言对象 +func SetLanguage(lang *Language) Carbon { + loc, _ := getLocationByTimezone(Local) + err := lang.SetLocale(lang.locale) + return Carbon{Loc: loc, Lang: lang, Error: err} +} + +// SetLocale 设置语言区域 +func (c Carbon) SetLocale(locale string) Carbon { + lang := NewLanguage() + c.Error = lang.SetLocale(locale) + c.Lang = lang + return c +} + +// SetLocale 设置语言区域 +func SetLocale(locale string) Carbon { + lang := NewLanguage() + err := lang.SetLocale(locale) + return Carbon{Lang: lang, Error: err} +} + +// SetYear 设置年 +func (c Carbon) SetYear(year int) Carbon { + c.Time = time.Date(year, c.Time.Month(), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) + return c +} + +// SetMonth 设置月 +func (c Carbon) SetMonth(month int) Carbon { + c.Time = time.Date(c.Time.Year(), time.Month(month), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) + return c +} + +// SetDay 设置日 +func (c Carbon) SetDay(day int) Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), day, c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) + return c +} + +// SetHour 设置时 +func (c Carbon) SetHour(hour int) Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), hour, c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) + return c +} + +// SetMinute 设置分 +func (c Carbon) SetMinute(minute int) Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), minute, c.Time.Second(), c.Time.Nanosecond(), c.Loc) + return c +} + +// SetSecond 设置秒 +func (c Carbon) SetSecond(second int) Carbon { + c.Time = time.Date(c.Time.Year(), c.Time.Month(), c.Time.Day(), c.Time.Hour(), c.Time.Minute(), second, c.Time.Nanosecond(), c.Loc) + return c +} diff --git a/setter_test.go b/setter_test.go new file mode 100755 index 0000000..14218ab --- /dev/null +++ b/setter_test.go @@ -0,0 +1,278 @@ +package carbon + +import ( + "fmt" + "testing" +) + +var TimezoneTests = []struct { + input string // 输入值 + timezone string // 输入参数 + output string // 期望输出值 +}{ + {"2020-08-05 13:14:15", PRC, "2020-08-05 13:14:15"}, + {"2020-08-05", Tokyo, "2020-08-05 01:00:00"}, + {"2020-08-05", "Hangzhou", "panic"}, // 异常情况 +} + +func TestCarbon_SetTimezone1(t *testing.T) { + for _, v := range TimezoneTests { + output := SetTimezone(v.timezone).Parse(v.input) + + if output.Error != nil { + fmt.Println("catch an exception in SetTimezone():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output.ToDateTimeString()) + } + } +} + +func TestCarbon_SetTimezone2(t *testing.T) { + for _, v := range TimezoneTests { + output := SetTimezone(PRC).SetTimezone(v.timezone).Parse(v.input) + + if output.Error != nil { + fmt.Println("catch an exception in SetTimezone():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output.ToDateTimeString()) + } + } +} + +var LocaleTests = []struct { + input string // 输入参数 + output string // 期望输出值 +}{ + {"en", "en"}, + {"zh-CN", "zh-CN"}, + {"XXXX", "panic"}, // 异常情况 +} + +func TestCarbon_SetLocale(t *testing.T) { + for _, v := range LocaleTests { + output := SetLocale(v.input) + + if output.Error != nil { + fmt.Println("catch an exception in SetLocale():", output.Error) + return + } + + if output.Locale() != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output.ToDateTimeString()) + } + } +} + +func TestCarbon_SetLanguage1(t *testing.T) { + lang := NewLanguage() + resources := map[string]string{ + "day": "%dd", + } + if lang.SetLocale("en") == nil { + lang.SetResources(resources) + } + + Tests := []struct { + input Carbon // 输入值 + output string // 期望输出值 + }{ + {Now(), "just now"}, + {Now().AddYears(1), "1 year from now"}, + {Now().SubYears(1), "1 year ago"}, + {Now().AddYears(10), "10 years from now"}, + {Now().SubYears(10), "10 years ago"}, + + {Now().AddMonths(1), "1 month from now"}, + {Now().SubMonths(1), "1 month ago"}, + {Now().AddMonths(10), "10 months from now"}, + {Now().SubMonths(10), "10 months ago"}, + + {Now().AddDays(1), "1d from now"}, + {Now().SubDays(1), "1d ago"}, + {Now().AddDays(10), "1 week from now"}, + {Now().SubDays(10), "1 week ago"}, + } + + for _, v := range Tests { + output := (v.input).SetLanguage(lang).DiffForHumans() + + if output != v.output { + t.Errorf("Input time %s, expected %s, but got %s", v.input.ToDateTimeString(), v.output, output) + } + } +} + +func TestCarbon_SetLanguage2(t *testing.T) { + lang := NewLanguage() + resources := map[string]string{ + "year": "1 yr|%d yrs", + "month": "1 mo|%d mos", + "week": "%dw", + "day": "%dd", + "hour": "%dh", + "minute": "%dm", + "second": "%ds", + "now": "just now", + "ago": "%s ago", + "from_now": "in %s", + "before": "%s before", + "after": "%s after", + } + lang.SetResources(resources) + + Tests := []struct { + input Carbon // 输入值 + output string // 期望输出值 + }{ + {Now(), "just now"}, + {Now().AddYears(1), "in 1 yr"}, + {Now().SubYears(1), "1 yr ago"}, + {Now().AddYears(10), "in 10 yrs"}, + {Now().SubYears(10), "10 yrs ago"}, + + {Now().AddMonths(1), "in 1 mo"}, + {Now().SubMonths(1), "1 mo ago"}, + {Now().AddMonths(10), "in 10 mos"}, + {Now().SubMonths(10), "10 mos ago"}, + + {Now().AddDays(1), "in 1d"}, + {Now().SubDays(1), "1d ago"}, + {Now().AddDays(10), "in 1w"}, + {Now().SubDays(10), "1w ago"}, + } + + for _, v := range Tests { + output := (v.input).SetLanguage(lang).DiffForHumans() + + if output != v.output { + t.Errorf("Input time %s, expected %s, but got %s", v.input.ToDateTimeString(), v.output, output) + } + } +} + +func TestCarbon_SetYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + year int // 输入参数 + output string // 期望输出值 + }{ + {"2020-01-01", 2019, "2019-01-01"}, + {"2020-01-31", 2019, "2019-01-31"}, + {"2020-02-01", 2019, "2019-02-01"}, + {"2020-02-28", 2019, "2019-02-28"}, + {"2020-02-29", 2019, "2019-03-01"}, + } + + for _, v := range Tests { + output := Parse(v.input).SetYear(v.year).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_SetMonth(t *testing.T) { + Tests := []struct { + input string // 输入值 + month int // 输入参数 + output string // 期望输出值 + }{ + {"2020-01-01", 2, "2020-02-01"}, + {"2020-01-30", 2, "2020-03-01"}, + {"2020-01-31", 2, "2020-03-02"}, + {"2020-08-05", 2, "2020-02-05"}, + } + + for _, v := range Tests { + output := Parse(v.input).SetMonth(v.month).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_SetDay(t *testing.T) { + Tests := []struct { + input string // 输入值 + day int // 输入参数 + output string // 期望输出值 + }{ + {"2020-01-01", 31, "2020-01-31"}, + {"2020-02-01", 31, "2020-03-02"}, + {"2020-02-28", 31, "2020-03-02"}, + {"2020-02-29", 31, "2020-03-02"}, + } + + for _, v := range Tests { + output := Parse(v.input).SetDay(v.day).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_SetHour(t *testing.T) { + Tests := []struct { + input string // 输入值 + hour int // 输入参数 + output string // 期望输出值 + }{ + {"2020-08-05 13:14:15", 10, "2020-08-05 10:14:15"}, + {"2020-08-05 13:14:15", 24, "2020-08-06 00:14:15"}, + } + + for _, v := range Tests { + output := Parse(v.input).SetHour(v.hour).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_SetMinute(t *testing.T) { + Tests := []struct { + input string // 输入值 + minute int // 输入参数 + output string // 期望输出值 + }{ + {"2020-08-05 13:14:15", 10, "2020-08-05 13:10:15"}, + {"2020-08-05 13:14:15", 60, "2020-08-05 14:00:15"}, + } + + for _, v := range Tests { + output := Parse(v.input).SetMinute(v.minute).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} + +func TestCarbon_SetSecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + second int // 输入参数 + output string // 期望输出值 + }{ + {"2020-08-05 13:14:15", 10, "2020-08-05 13:14:10"}, + {"2020-08-05 13:14:15", 60, "2020-08-05 13:15:00"}, + } + + for _, v := range Tests { + output := Parse(v.input).SetSecond(v.second).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s", v.input, v.output, output) + } + } +} diff --git a/traveler.go b/traveler.go new file mode 100755 index 0000000..e98e4de --- /dev/null +++ b/traveler.go @@ -0,0 +1,314 @@ +package carbon + +import "time" + +// AddDurations 按照持续时间字符串增加时间 +// 支持整数/浮点数和符号ns(纳秒)、us(微妙)、ms(毫秒)、s(秒)、m(分钟)、h(小时)的组合 +func (c Carbon) AddDuration(duration string) Carbon { + if c.Error != nil { + return c + } + td, err := parseByDuration(duration) + c.Time = c.Time.Add(td) + c.Error = err + return c +} + +// SubDurations 按照持续时间字符串减少时间 +// 支持整数/浮点数和符号ns(纳秒)、us(微妙)、ms(毫秒)、s(秒)、m(分钟)、h(小时)的组合 +func (c Carbon) SubDuration(duration string) Carbon { + return c.AddDuration("-" + duration) +} + +// AddCenturies N世纪后 +func (c Carbon) AddCenturies(centuries int) Carbon { + return c.AddYears(YearsPerCentury * centuries) +} + +// AddCenturiesNoOverflow N世纪后(月份不溢出) +func (c Carbon) AddCenturiesNoOverflow(centuries int) Carbon { + return c.AddYearsNoOverflow(centuries * YearsPerCentury) +} + +// AddCentury 1世纪后 +func (c Carbon) AddCentury() Carbon { + return c.AddCenturies(1) +} + +// AddCenturyNoOverflow 1世纪后(月份不溢出) +func (c Carbon) AddCenturyNoOverflow() Carbon { + return c.AddCenturiesNoOverflow(1) +} + +// SubCenturies N世纪前 +func (c Carbon) SubCenturies(centuries int) Carbon { + return c.SubYears(YearsPerCentury * centuries) +} + +// SubCenturiesNoOverflow N世纪前(月份不溢出) +func (c Carbon) SubCenturiesNoOverflow(centuries int) Carbon { + return c.SubYearsNoOverflow(centuries * YearsPerCentury) +} + +// SubCentury 1世纪前 +func (c Carbon) SubCentury() Carbon { + return c.SubCenturies(1) +} + +// SubCenturyNoOverflow 1世纪前(月份不溢出) +func (c Carbon) SubCenturyNoOverflow() Carbon { + return c.SubCenturiesNoOverflow(1) +} + +// AddYears N年后 +func (c Carbon) AddYears(years int) Carbon { + c.Time = c.Time.AddDate(years, 0, 0) + return c +} + +// AddYearsNoOverflow N年后(月份不溢出) +func (c Carbon) AddYearsNoOverflow(years int) Carbon { + year := c.Time.Year() + years + month := c.Time.Month() + day := c.Time.Day() + + // 获取N年后本月的最后一天 + last := time.Date(year, month, 1, c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc).AddDate(0, 1, -1) + + if day > last.Day() { + day = last.Day() + } + + c.Time = time.Date(last.Year(), last.Month(), day, c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) + return c +} + +// AddYear 1年后 +func (c Carbon) AddYear() Carbon { + return c.AddYears(1) +} + +// AddYearNoOverflow 1年后(月份不溢出) +func (c Carbon) AddYearNoOverflow() Carbon { + return c.AddYearsNoOverflow(1) +} + +// SubYears N年前 +func (c Carbon) SubYears(years int) Carbon { + return c.AddYears(-years) +} + +// SubYearsNoOverflow N年前(月份不溢出) +func (c Carbon) SubYearsNoOverflow(years int) Carbon { + return c.AddYearsNoOverflow(-years) +} + +// SubYear 1年前 +func (c Carbon) SubYear() Carbon { + return c.SubYears(1) +} + +// SubYearNoOverflow 1年前(月份不溢出) +func (c Carbon) SubYearNoOverflow() Carbon { + return c.SubYearsNoOverflow(1) +} + +// AddQuarters N季度后 +func (c Carbon) AddQuarters(quarters int) Carbon { + return c.AddMonths(quarters * MonthsPerQuarter) +} + +// AddQuartersNoOverflow N季度后(月份不溢出) +func (c Carbon) AddQuartersNoOverflow(quarters int) Carbon { + return c.AddMonthsNoOverflow(quarters * MonthsPerQuarter) +} + +// AddQuarter 1季度后 +func (c Carbon) AddQuarter() Carbon { + return c.AddQuarters(1) +} + +// NextQuarters 1季度后(月份不溢出) +func (c Carbon) AddQuarterNoOverflow() Carbon { + return c.AddQuartersNoOverflow(1) +} + +// SubQuarters N季度前 +func (c Carbon) SubQuarters(quarters int) Carbon { + return c.AddQuarters(-quarters) +} + +// SubQuartersNoOverflow N季度前(月份不溢出) +func (c Carbon) SubQuartersNoOverflow(quarters int) Carbon { + return c.AddMonthsNoOverflow(-quarters * MonthsPerQuarter) +} + +// SubQuarter 1季度前 +func (c Carbon) SubQuarter() Carbon { + return c.SubQuarters(1) +} + +// SubQuarterNoOverflow 1季度前(月份不溢出) +func (c Carbon) SubQuarterNoOverflow() Carbon { + return c.SubQuartersNoOverflow(1) +} + +// AddMonths N月后 +func (c Carbon) AddMonths(months int) Carbon { + c.Time = c.Time.AddDate(0, months, 0) + return c +} + +// AddMonthsNoOverflow N月后(月份不溢出) +func (c Carbon) AddMonthsNoOverflow(months int) Carbon { + year := c.Time.Year() + month := c.Time.Month() + time.Month(months) + day := c.Time.Day() + + // 获取N月后的最后一天 + last := time.Date(year, month, 1, c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc).AddDate(0, 1, -1) + + if day > last.Day() { + day = last.Day() + } + + c.Time = time.Date(last.Year(), last.Month(), day, c.Time.Hour(), c.Time.Minute(), c.Time.Second(), c.Time.Nanosecond(), c.Loc) + return c +} + +// AddMonth 1月后 +func (c Carbon) AddMonth() Carbon { + return c.AddMonths(1) +} + +// AddMonthNoOverflow 1月后(月份不溢出) +func (c Carbon) AddMonthNoOverflow() Carbon { + return c.AddMonthsNoOverflow(1) +} + +// SubMonths N月前 +func (c Carbon) SubMonths(months int) Carbon { + return c.AddMonths(-months) +} + +// SubMonthsNoOverflow N月前(月份不溢出) +func (c Carbon) SubMonthsNoOverflow(months int) Carbon { + return c.AddMonthsNoOverflow(-months) +} + +// SubMonth 1月前 +func (c Carbon) SubMonth() Carbon { + return c.SubMonths(1) +} + +// SubMonthNoOverflow 1月前(月份不溢出) +func (c Carbon) SubMonthNoOverflow() Carbon { + return c.SubMonthsNoOverflow(1) +} + +// AddWeeks N周后 +func (c Carbon) AddWeeks(weeks int) Carbon { + return c.AddDays(weeks * DaysPerWeek) +} + +// AddWeek 1天后 +func (c Carbon) AddWeek() Carbon { + return c.AddWeeks(1) +} + +// SubWeeks N周后 +func (c Carbon) SubWeeks(weeks int) Carbon { + return c.SubDays(weeks * DaysPerWeek) +} + +// SubWeek 1天后 +func (c Carbon) SubWeek() Carbon { + return c.SubWeeks(1) +} + +// AddDays N天后 +func (c Carbon) AddDays(days int) Carbon { + c.Time = c.Time.AddDate(0, 0, days) + return c +} + +// AddDay 1天后 +func (c Carbon) AddDay() Carbon { + return c.AddDays(1) +} + +// SubDays N天前 +func (c Carbon) SubDays(days int) Carbon { + return c.AddDays(-days) +} + +// SubDay 1天前 +func (c Carbon) SubDay() Carbon { + return c.SubDays(1) +} + +// AddHours N小时后 +func (c Carbon) AddHours(hours int) Carbon { + td := time.Duration(hours) * time.Hour + c.Time = c.Time.Add(td) + return c +} + +// AddHour 1小时后 +func (c Carbon) AddHour() Carbon { + return c.AddHours(1) +} + +// SubHours N小时前 +func (c Carbon) SubHours(hours int) Carbon { + return c.AddHours(-hours) +} + +// SubHour 1小时前 +func (c Carbon) SubHour() Carbon { + return c.SubHours(1) +} + +// AddMinutes N分钟后 +func (c Carbon) AddMinutes(minutes int) Carbon { + td := time.Duration(minutes) * time.Minute + c.Time = c.Time.Add(td) + return c +} + +// AddMinute 1分钟后 +func (c Carbon) AddMinute() Carbon { + return c.AddMinutes(1) +} + +// SubMinutes N分钟前 +func (c Carbon) SubMinutes(minutes int) Carbon { + return c.AddMinutes(-minutes) +} + +// SubMinute 1分钟前 +func (c Carbon) SubMinute() Carbon { + return c.SubMinutes(1) +} + +// AddSeconds N秒钟后 +func (c Carbon) AddSeconds(seconds int) Carbon { + td := time.Duration(seconds) * time.Second + c.Time = c.Time.Add(td) + return c +} + +// AddSecond 1秒钟后 +func (c Carbon) AddSecond() Carbon { + return c.AddSeconds(1) +} + +// SubSeconds N秒钟前 +func (c Carbon) SubSeconds(seconds int) Carbon { + return c.AddSeconds(-seconds) +} + +// SubSecond 1秒钟前 +func (c Carbon) SubSecond() Carbon { + return c.SubSeconds(1) +} diff --git a/traveler_test.go b/traveler_test.go new file mode 100755 index 0000000..92af2b6 --- /dev/null +++ b/traveler_test.go @@ -0,0 +1,1646 @@ +package carbon + +import ( + "fmt" + "testing" +) + +func TestCarbon_AddDuration(t *testing.T) { + Tests := []struct { + input string // 输入值 + duration string // 输入参数 + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", "10h", "2020-01-01 23:14:15"}, + {"2020-01-01 13:14:15", "10.5h", "2020-01-01 23:44:15"}, + + {"2020-01-01 13:14:15", "10m", "2020-01-01 13:24:15"}, + {"2020-01-01 13:14:15", "10.5m", "2020-01-01 13:24:45"}, + + {"2020-01-01 13:14:15", "10s", "2020-01-01 13:14:25"}, + {"2020-01-01 13:14:15", "10.5s", "2020-01-01 13:14:25"}, + + {"2020-01-01 13:14:15", "XXXX", ""}, // 异常情况 + } + + for _, v := range Tests { + output := Parse(v.input).AddDuration(v.duration) + + if output.Error != nil { + fmt.Println("catch an exception in AddDuration():", output.Error) + } else { + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) + } + } + } + + for _, v := range Tests { + output := SetTimezone("XXXX").Parse(v.input).AddDuration(v.duration) + + if output.Error != nil { + fmt.Println("catch an exception in AddDuration():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) + } + } +} + +func TestCarbon_SubDuration(t *testing.T) { + Tests := []struct { + input string // 输入值 + duration string // 输入参数 + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", "10h", "2020-01-01 03:14:15"}, + {"2020-01-01 13:14:15", "10.5h", "2020-01-01 02:44:15"}, + + {"2020-01-01 13:14:15", "10m", "2020-01-01 13:04:15"}, + {"2020-01-01 13:14:15", "10.5m", "2020-01-01 13:03:45"}, + + {"2020-01-01 13:14:15", "10s", "2020-01-01 13:14:05"}, + {"2020-01-01 13:14:15", "10.5s", "2020-01-01 13:14:04"}, + + {"2020-01-01 13:14:15 XXXX", "10h", ""}, // 异常情况 + {"2020-01-01 13:14:15", "10x", ""}, // 异常情况 + } + + for _, v := range Tests { + output := Parse(v.input).SubDuration(v.duration) + + if output.Error != nil { + fmt.Println("catch an exception in SubDuration():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) + } + } + + for _, v := range Tests { + output := SetTimezone("XXXX").Parse(v.input).SubDuration(v.duration) + + if output.Error != nil { + fmt.Println("catch an exception in SubDuration():", output.Error) + return + } + + if output.ToDateTimeString() != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output.ToDateTimeString()) + } + } +} + +func TestCarbon_AddCenturies(t *testing.T) { + type Test struct { + input string // 输入值 + centuries int // 输入参数 + output string // 期望输出值 + } + + Tests := []Test{ + {"2020-01-01", 3, "2320-01-01"}, + {"2020-01-31", 3, "2320-01-31"}, + {"2020-02-01", 3, "2320-02-01"}, + {"2020-02-28", 3, "2320-02-28"}, + {"2020-02-29", 3, "2320-02-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddCenturies(v.centuries).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddCenturies(v.centuries).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddCenturiesNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + centuries int // 输入参数 + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2320-01-01"}, + {"2020-01-31", 3, "2320-01-31"}, + {"2020-02-01", 3, "2320-02-01"}, + {"2020-02-28", 3, "2320-02-28"}, + {"2020-02-29", 3, "2320-02-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddCenturiesNoOverflow(v.centuries).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddCenturiesNoOverflow(v.centuries).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubCenturies(t *testing.T) { + type Test struct { + input string // 输入值 + centuries int // 输入参数 + output string // 期望输出值 + } + + Tests := []Test{ + {"2020-01-01", 3, "1720-01-01"}, + {"2020-01-31", 3, "1720-01-31"}, + {"2020-02-01", 3, "1720-02-01"}, + {"2020-02-28", 3, "1720-02-28"}, + {"2020-02-29", 3, "1720-02-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubCenturies(v.centuries).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubCenturies(v.centuries).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubCenturiesNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + centuries int + output string // 期望输出值 + }{ + {"2020-01-01", 3, "1720-01-01"}, + {"2020-01-31", 3, "1720-01-31"}, + {"2020-02-01", 3, "1720-02-01"}, + {"2020-02-28", 3, "1720-02-28"}, + {"2020-02-29", 3, "1720-02-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubCenturiesNoOverflow(v.centuries).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubCenturiesNoOverflow(v.centuries).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddCentury(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2120-01-01"}, + {"2020-01-31", "2120-01-31"}, + {"2020-02-01", "2120-02-01"}, + {"2020-02-28", "2120-02-28"}, + {"2020-02-29", "2120-02-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddCentury().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddCentury().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddCenturyNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2120-01-01"}, + {"2020-01-31", "2120-01-31"}, + {"2020-02-01", "2120-02-01"}, + {"2020-02-28", "2120-02-28"}, + {"2020-02-29", "2120-02-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddCenturyNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddCenturyNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubCentury(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "1920-01-01"}, + {"2020-01-31", "1920-01-31"}, + {"2020-02-01", "1920-02-01"}, + {"2020-02-28", "1920-02-28"}, + {"2020-02-29", "1920-02-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubCentury().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubCentury().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubCenturyNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "1920-01-01"}, + {"2020-01-31", "1920-01-31"}, + {"2020-02-01", "1920-02-01"}, + {"2020-02-28", "1920-02-28"}, + {"2020-02-29", "1920-02-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubCenturyNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Expected %s, but got %s", v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubCenturyNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddYears(t *testing.T) { + Tests := []struct { + input string // 输入值 + years int // 输入参数 + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2023-01-01"}, + {"2020-01-31", 3, "2023-01-31"}, + {"2020-02-01", 3, "2023-02-01"}, + {"2020-02-28", 3, "2023-02-28"}, + {"2020-02-29", 3, "2023-03-01"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddYears(v.years).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddYears(v.years).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddYearsNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + years int // 输入参数 + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2023-01-01"}, + {"2020-01-31", 3, "2023-01-31"}, + {"2020-02-01", 3, "2023-02-01"}, + {"2020-02-28", 3, "2023-02-28"}, + {"2020-02-29", 3, "2023-02-28"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddYearsNoOverflow(v.years).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddYearsNoOverflow(v.years).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubYears(t *testing.T) { + type Test struct { + input string // 输入值 + years int // 输入参数 + output string // 期望输出值 + } + + Tests := []Test{ + {"2020-01-01", 3, "2017-01-01"}, + {"2020-01-31", 3, "2017-01-31"}, + {"2020-02-01", 3, "2017-02-01"}, + {"2020-02-28", 3, "2017-02-28"}, + {"2020-02-29", 3, "2017-03-01"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubYears(v.years).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubYears(v.years).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubYearsNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + years int + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2017-01-01"}, + {"2020-01-31", 3, "2017-01-31"}, + {"2020-02-01", 3, "2017-02-01"}, + {"2020-02-28", 3, "2017-02-28"}, + {"2020-02-29", 3, "2017-02-28"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubYearsNoOverflow(v.years).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubYearsNoOverflow(v.years).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2021-01-01"}, + {"2020-01-31", "2021-01-31"}, + {"2020-02-01", "2021-02-01"}, + {"2020-02-28", "2021-02-28"}, + {"2020-02-29", "2021-03-01"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddYear().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddYear().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddYearNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2021-01-01"}, + {"2020-01-31", "2021-01-31"}, + {"2020-02-01", "2021-02-01"}, + {"2020-02-28", "2021-02-28"}, + {"2020-02-29", "2021-02-28"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddYearNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddYearNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubYear(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2019-01-01"}, + {"2020-01-31", "2019-01-31"}, + {"2020-02-01", "2019-02-01"}, + {"2020-02-28", "2019-02-28"}, + {"2020-02-29", "2019-03-01"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubYear().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubYear().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubYearNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2019-01-01"}, + {"2020-01-31", "2019-01-31"}, + {"2020-02-01", "2019-02-01"}, + {"2020-02-28", "2019-02-28"}, + {"2020-02-29", "2019-02-28"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubYearNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Expected %s, but got %s", v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubYearNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddQuarters(t *testing.T) { + Tests := []struct { + input string // 输入值 + quarters int + output string // 期望输出值 + }{ + {"2019-08-01", 2, "2020-02-01"}, + {"2019-08-31", 2, "2020-03-02"}, + {"2020-01-01", 2, "2020-07-01"}, + {"2020-02-28", 2, "2020-08-28"}, + {"2020-02-29", 2, "2020-08-29"}, + {"2020-08-31", 2, "2021-03-03"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddQuarters(v.quarters).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddQuarters(v.quarters).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddQuartersNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + quarters int + output string // 期望输出值 + }{ + {"2019-08-01", 2, "2020-02-01"}, + {"2019-08-31", 2, "2020-02-29"}, + {"2020-01-01", 2, "2020-07-01"}, + {"2020-02-28", 2, "2020-08-28"}, + {"2020-02-29", 2, "2020-08-29"}, + {"2020-08-31", 2, "2021-02-28"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddQuartersNoOverflow(v.quarters).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddQuartersNoOverflow(v.quarters).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubQuarters(t *testing.T) { + Tests := []struct { + input string // 输入值 + quarters int + output string // 期望输出值 + }{ + {"2019-08-01", 2, "2019-02-01"}, + {"2019-08-31", 2, "2019-03-03"}, + {"2020-01-01", 2, "2019-07-01"}, + {"2020-02-28", 2, "2019-08-28"}, + {"2020-02-29", 2, "2019-08-29"}, + {"2020-08-31", 2, "2020-03-02"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubQuarters(v.quarters).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubQuarters(v.quarters).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubQuartersNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + quarters int + output string // 期望输出值 + }{ + {"2019-08-01", 2, "2019-02-01"}, + {"2019-08-31", 2, "2019-02-28"}, + {"2020-01-01", 2, "2019-07-01"}, + {"2020-02-28", 2, "2019-08-28"}, + {"2020-02-29", 2, "2019-08-29"}, + {"2020-08-31", 2, "2020-02-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubQuartersNoOverflow(v.quarters).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubQuartersNoOverflow(v.quarters).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddQuarter(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2019-11-01", "2020-02-01"}, + {"2019-11-30", "2020-03-01"}, + {"2020-02-28", "2020-05-28"}, + {"2020-02-29", "2020-05-29"}, + {"2020-08-31", "2020-12-01"}, + {"2020-11-01", "2021-02-01"}, + {"2020-11-30", "2021-03-02"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddQuarter().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddQuarter().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddQuarterNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2019-11-01", "2020-02-01"}, + {"2019-11-30", "2020-02-29"}, + {"2020-02-28", "2020-05-28"}, + {"2020-02-29", "2020-05-29"}, + {"2020-08-31", "2020-11-30"}, + {"2020-11-01", "2021-02-01"}, + {"2020-11-30", "2021-02-28"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddQuarterNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddQuarterNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubQuarter(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2019-04-01", "2019-01-01"}, + {"2019-04-30", "2019-01-30"}, + {"2020-05-01", "2020-02-01"}, + {"2020-05-31", "2020-03-02"}, + {"2020-04-01", "2020-01-01"}, + {"2020-04-30", "2020-01-30"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubQuarter().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubQuarter().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubQuarterNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2019-04-01", "2019-01-01"}, + {"2019-04-30", "2019-01-30"}, + {"2020-05-01", "2020-02-01"}, + {"2020-05-31", "2020-02-29"}, + {"2020-04-01", "2020-01-01"}, + {"2020-04-30", "2020-01-30"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubQuarterNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubQuarterNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddMonths(t *testing.T) { + Tests := []struct { + input string // 输入值 + months int + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2020-04-01"}, + {"2020-01-31", 3, "2020-05-01"}, + {"2020-02-01", 3, "2020-05-01"}, + {"2020-02-28", 3, "2020-05-28"}, + {"2020-02-29", 3, "2020-05-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddMonths(v.months).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddMonths(v.months).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddMonthsNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + months int + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2020-04-01"}, + {"2020-01-31", 3, "2020-04-30"}, + {"2020-02-01", 3, "2020-05-01"}, + {"2020-02-28", 3, "2020-05-28"}, + {"2020-02-29", 3, "2020-05-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddMonthsNoOverflow(v.months).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddMonthsNoOverflow(v.months).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubMonths(t *testing.T) { + Tests := []struct { + input string // 输入值 + months int + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2019-10-01"}, + {"2020-01-31", 3, "2019-10-31"}, + {"2020-02-01", 3, "2019-11-01"}, + {"2020-02-28", 3, "2019-11-28"}, + {"2020-02-29", 3, "2019-11-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubMonths(v.months).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubMonths(v.months).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubMonthsNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + months int + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2019-10-01"}, + {"2020-01-31", 3, "2019-10-31"}, + {"2020-02-01", 3, "2019-11-01"}, + {"2020-02-28", 3, "2019-11-28"}, + {"2020-02-29", 3, "2019-11-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubMonthsNoOverflow(v.months).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubMonthsNoOverflow(v.months).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddMonth(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2020-02-01"}, + {"2020-01-31", "2020-03-02"}, + {"2020-02-01", "2020-03-01"}, + {"2020-02-28", "2020-03-28"}, + {"2020-02-29", "2020-03-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddMonth().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddMonth().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddMonthNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2020-02-01"}, + {"2020-01-31", "2020-02-29"}, + {"2020-02-01", "2020-03-01"}, + {"2020-02-28", "2020-03-28"}, + {"2020-02-29", "2020-03-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddMonthNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddMonthNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubMonth(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2019-12-01"}, + {"2020-01-31", "2019-12-31"}, + {"2020-02-01", "2020-01-01"}, + {"2020-02-28", "2020-01-28"}, + {"2020-02-29", "2020-01-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubMonth().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubMonth().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubMonthNoOverflow(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2019-12-01"}, + {"2020-01-31", "2019-12-31"}, + {"2020-02-01", "2020-01-01"}, + {"2020-02-28", "2020-01-28"}, + {"2020-02-29", "2020-01-29"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubMonthNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubMonthNoOverflow().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddWeeks(t *testing.T) { + Tests := []struct { + input string // 输入值 + weeks int + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2020-01-22"}, + {"2020-01-31", 3, "2020-02-21"}, + {"2020-02-01", 3, "2020-02-22"}, + {"2020-02-28", 3, "2020-03-20"}, + {"2020-02-29", 3, "2020-03-21"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddWeeks(v.weeks).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddWeeks(v.weeks).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubWeeks(t *testing.T) { + Tests := []struct { + input string // 输入值 + weeks int + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2019-12-11"}, + {"2020-01-31", 3, "2020-01-10"}, + {"2020-02-01", 3, "2020-01-11"}, + {"2020-02-28", 3, "2020-02-07"}, + {"2020-02-29", 3, "2020-02-08"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubWeeks(v.weeks).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubWeeks(v.weeks).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddWeek(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2020-01-08"}, + {"2020-01-31", "2020-02-07"}, + {"2020-02-01", "2020-02-08"}, + {"2020-02-28", "2020-03-06"}, + {"2020-02-29", "2020-03-07"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddWeek().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddWeek().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubWeek(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2019-12-25"}, + {"2020-01-31", "2020-01-24"}, + {"2020-02-01", "2020-01-25"}, + {"2020-02-28", "2020-02-21"}, + {"2020-02-29", "2020-02-22"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubWeek().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubWeek().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddDays(t *testing.T) { + Tests := []struct { + input string // 输入值 + days int + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2020-01-04"}, + {"2020-01-31", 3, "2020-02-03"}, + {"2020-02-01", 3, "2020-02-04"}, + {"2020-02-28", 3, "2020-03-02"}, + {"2020-02-29", 3, "2020-03-03"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddDays(v.days).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddDays(v.days).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubDays(t *testing.T) { + Tests := []struct { + input string // 输入值 + days int + output string // 期望输出值 + }{ + {"2020-01-01", 3, "2019-12-29"}, + {"2020-01-31", 3, "2020-01-28"}, + {"2020-02-01", 3, "2020-01-29"}, + {"2020-02-28", 3, "2020-02-25"}, + {"2020-02-29", 3, "2020-02-26"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubDays(v.days).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubDays(v.days).ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddDay(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2020-01-02"}, + {"2020-01-31", "2020-02-01"}, + {"2020-02-01", "2020-02-02"}, + {"2020-02-28", "2020-02-29"}, + {"2020-02-29", "2020-03-01"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddDay().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddDay().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubDay(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01", "2019-12-31"}, + {"2020-01-31", "2020-01-30"}, + {"2020-02-01", "2020-01-31"}, + {"2020-02-28", "2020-02-27"}, + {"2020-02-29", "2020-02-28"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubDay().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubDay().ToDateString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddHours(t *testing.T) { + Tests := []struct { + input string // 输入值 + hours int + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", 3, "2020-01-01 16:14:15"}, + {"2020-01-31 13:14:15", 3, "2020-01-31 16:14:15"}, + {"2020-02-01 13:14:15", 3, "2020-02-01 16:14:15"}, + {"2020-02-28 13:14:15", 3, "2020-02-28 16:14:15"}, + {"2020-02-29 13:14:15", 3, "2020-02-29 16:14:15"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddHours(v.hours).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddHours(v.hours).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubHours(t *testing.T) { + Tests := []struct { + input string // 输入值 + hours int + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", 3, "2020-01-01 10:14:15"}, + {"2020-01-31 13:14:15", 3, "2020-01-31 10:14:15"}, + {"2020-02-01 13:14:15", 3, "2020-02-01 10:14:15"}, + {"2020-02-28 13:14:15", 3, "2020-02-28 10:14:15"}, + {"2020-02-29 13:14:15", 3, "2020-02-29 10:14:15"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubHours(v.hours).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubHours(v.hours).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddHour(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", "2020-01-01 14:14:15"}, + {"2020-01-31 13:14:15", "2020-01-31 14:14:15"}, + {"2020-02-01 13:14:15", "2020-02-01 14:14:15"}, + {"2020-02-28 13:14:15", "2020-02-28 14:14:15"}, + {"2020-02-29 13:14:15", "2020-02-29 14:14:15"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddHour().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddHour().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubHour(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", "2020-01-01 12:14:15"}, + {"2020-01-31 13:14:15", "2020-01-31 12:14:15"}, + {"2020-02-01 13:14:15", "2020-02-01 12:14:15"}, + {"2020-02-28 13:14:15", "2020-02-28 12:14:15"}, + {"2020-02-29 13:14:15", "2020-02-29 12:14:15"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubHour().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubHour().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddMinutes(t *testing.T) { + Tests := []struct { + input string // 输入值 + minutes int + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", 3, "2020-01-01 13:17:15"}, + {"2020-01-31 13:14:15", 3, "2020-01-31 13:17:15"}, + {"2020-02-01 13:14:15", 3, "2020-02-01 13:17:15"}, + {"2020-02-28 13:14:15", 3, "2020-02-28 13:17:15"}, + {"2020-02-29 13:14:15", 3, "2020-02-29 13:17:15"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddMinutes(v.minutes).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddMinutes(v.minutes).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubMinutes(t *testing.T) { + Tests := []struct { + input string // 输入值 + minutes int + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", 3, "2020-01-01 13:11:15"}, + {"2020-01-31 13:14:15", 3, "2020-01-31 13:11:15"}, + {"2020-02-01 13:14:15", 3, "2020-02-01 13:11:15"}, + {"2020-02-28 13:14:15", 3, "2020-02-28 13:11:15"}, + {"2020-02-29 13:14:15", 3, "2020-02-29 13:11:15"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubMinutes(v.minutes).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubMinutes(v.minutes).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddMinute(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", "2020-01-01 13:15:15"}, + {"2020-01-31 13:14:15", "2020-01-31 13:15:15"}, + {"2020-02-01 13:14:15", "2020-02-01 13:15:15"}, + {"2020-02-28 13:14:15", "2020-02-28 13:15:15"}, + {"2020-02-29 13:14:15", "2020-02-29 13:15:15"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddMinute().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddMinute().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubMinute(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", "2020-01-01 13:13:15"}, + {"2020-01-31 13:14:15", "2020-01-31 13:13:15"}, + {"2020-02-01 13:14:15", "2020-02-01 13:13:15"}, + {"2020-02-28 13:14:15", "2020-02-28 13:13:15"}, + {"2020-02-29 13:14:15", "2020-02-29 13:13:15"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubMinute().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubMinute().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddSeconds(t *testing.T) { + Tests := []struct { + input string // 输入值 + seconds int + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", 3, "2020-01-01 13:14:18"}, + {"2020-01-31 13:14:15", 3, "2020-01-31 13:14:18"}, + {"2020-02-01 13:14:15", 3, "2020-02-01 13:14:18"}, + {"2020-02-28 13:14:15", 3, "2020-02-28 13:14:18"}, + {"2020-02-29 13:14:15", 3, "2020-02-29 13:14:18"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddSeconds(v.seconds).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddSeconds(v.seconds).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubSeconds(t *testing.T) { + Tests := []struct { + input string // 输入值 + seconds int + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", 3, "2020-01-01 13:14:12"}, + {"2020-01-31 13:14:15", 3, "2020-01-31 13:14:12"}, + {"2020-02-01 13:14:15", 3, "2020-02-01 13:14:12"}, + {"2020-02-28 13:14:15", 3, "2020-02-28 13:14:12"}, + {"2020-02-29 13:14:15", 3, "2020-02-29 13:14:12"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubSeconds(v.seconds).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubSeconds(v.seconds).ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_AddSecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", "2020-01-01 13:14:16"}, + {"2020-01-31 13:14:15", "2020-01-31 13:14:16"}, + {"2020-02-01 13:14:15", "2020-02-01 13:14:16"}, + {"2020-02-28 13:14:15", "2020-02-28 13:14:16"}, + {"2020-02-29 13:14:15", "2020-02-29 13:14:16"}, + } + + for _, v := range Tests { + output := Parse(v.input).AddSecond().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).AddSecond().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +} + +func TestCarbon_SubSecond(t *testing.T) { + Tests := []struct { + input string // 输入值 + output string // 期望输出值 + }{ + {"2020-01-01 13:14:15", "2020-01-01 13:14:14"}, + {"2020-01-31 13:14:15", "2020-01-31 13:14:14"}, + {"2020-02-01 13:14:15", "2020-02-01 13:14:14"}, + {"2020-02-28 13:14:15", "2020-02-28 13:14:14"}, + {"2020-02-29 13:14:15", "2020-02-29 13:14:14"}, + } + + for _, v := range Tests { + output := Parse(v.input).SubSecond().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } + + for _, v := range Tests { + output := SetTimezone(PRC).Parse(v.input).SubSecond().ToDateTimeString() + + if output != v.output { + t.Errorf("Input %s, expected %s, but got %s\n", v.input, v.output, output) + } + } +}