v1.3.2按照功能拆分文件

This commit is contained in:
gouguoyin 2021-02-18 14:32:31 +08:00
parent a20554be6c
commit d3f0aec069
35 changed files with 7626 additions and 8859 deletions

View File

@ -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 formatToFormatString() abbreviated as Format()
// To string of layout formatFormat() 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 <a href="#format-sign-table">Format sign table</a>
##### 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

279
README.md
View File

@ -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
```
>更多格式化输出符号请查看附录 <a href="#格式化符号表">格式化符号表</a>
##### 时间设置
```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()等方法时先进行错误处理判断,除非你能确保传入参数无误
#### 附录
##### <a id="格式化符号表">格式化符号表</a>
| 符号 | 描述 | 长度 | 范围 | 示例 |

739
carbon.go
View File

@ -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
}

File diff suppressed because it is too large Load Diff

243
comparer.go Executable file
View File

@ -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
}

1357
comparer_test.go Executable file

File diff suppressed because it is too large Load Diff

View File

@ -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"
)

14
converter.go Executable file
View File

@ -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
}

40
converter_test.go Executable file
View File

@ -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)
}
}
}

File diff suppressed because it is too large Load Diff

65
creator.go Executable file
View File

@ -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)
}

124
creator_test.go Executable file
View File

@ -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)
}
}
}

223
difference.go Executable file
View File

@ -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
}

456
difference_test.go Executable file
View File

@ -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)
}
}
}

264
display.go Executable file
View File

@ -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': // 当前时区,如 UTCGMTAtlantic/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)
}

576
display_test.go Executable file
View File

@ -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)
}
}
}

832
final.go
View File

@ -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': // 当前时区,如 UTCGMTAtlantic/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
}

File diff suppressed because it is too large Load Diff

187
getter.go Executable file
View File

@ -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()
}

456
getter_test.go Executable file
View File

@ -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)
}
}
}

View File

@ -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
}

View File

@ -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"
}

14
lang/jp.json Executable file
View File

@ -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後"
}

View File

@ -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后"
}

View File

@ -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後"
}

View File

@ -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]
}

102
language_test.go Executable file
View File

@ -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)
}
}
}

98
modifier.go Executable file
View File

@ -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
}

301
modifier_test.go Executable file
View File

@ -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)
}
}
}

76
parser.go Executable file
View File

@ -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)
}

132
parser_test.go Executable file
View File

@ -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())
}
}
}

87
setter.go Executable file
View File

@ -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
}

278
setter_test.go Executable file
View File

@ -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)
}
}
}

314
traveler.go Executable file
View File

@ -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)
}

1646
traveler_test.go Executable file

File diff suppressed because it is too large Load Diff