Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 77 additions & 13 deletions date/carbon/carbon.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package carbon

import (
"fmt"
"strconv"
"time"

"github.com/Kretech/xgo/date"
"github.com/pkg/errors"
)

// Carbon
Expand All @@ -12,19 +15,32 @@ type Carbon struct {
}

// 假定多数情况下,一个进程给一个location就够了
var defaultLoc = time.Local
var currentLoc = time.Local

// 设置全局时区
func In(loc *time.Location) {
defaultLoc = loc
currentLoc = loc
time.Local = loc
}

func Now() *Carbon {
return &Carbon{time.Now()}
}

func Today() *Carbon {
return &Carbon{time.Time{}.Truncate(24 * Hour)}
}

func Yestoday() *Carbon {
return Today().Sub(Day)
}

func Tomorrow() *Carbon {
return Today().Add(Day)
}

func UnixOf(sec int64, nsec int64) *Carbon {
t := time.Unix(sec, nsec).In(defaultLoc)
t := time.Unix(sec, nsec)
return &Carbon{t}
}

Expand All @@ -33,21 +49,29 @@ func TimeOf(t time.Time) *Carbon {
}

// 解析时间文本
func StrOf(str string) *Carbon {
return Parse(str)
func strOf(str string) *Carbon {
return parse(str)
}

// todo
// alias to StrOf
func Parse(str string) *Carbon {
t := time.Now().In(defaultLoc)
func parse(str string) *Carbon {
t := time.Now().In(currentLoc)
return &Carbon{t}
}

// wrap of time.Parse but with the carbon layout
// 使用 Go time.Time 解析时间文本
func TParse(layout, value string) *Carbon {
t, _ := time.Parse(date.ToGoFormat(layout), value)
func ParseUTC(layout, value string) *Carbon {
return ParseIn(layout, value, UTC)
}

func ParseLocal(layout, value string) *Carbon {
return ParseIn(layout, value, time.Local)
}

func ParseIn(layout, value string, loc *time.Location) *Carbon {
t, _ := time.ParseInLocation(date.ToGoFormat(layout), value, loc)
return TimeOf(t)
}

Expand Down Expand Up @@ -75,7 +99,7 @@ func (c Carbon) Add(d time.Duration) *Carbon {
}

// 减去另一个时间:计算两个时间的差
func (c *Carbon) SubTime(t time.Time) time.Duration {
func (c *Carbon) Diff(t time.Time) time.Duration {
return c.Time().Sub(t)
}

Expand All @@ -88,7 +112,47 @@ func (c Carbon) Sub(d time.Duration) *Carbon {
// Format 格式化代码
// c.Format("Y-m-d H:i:s")
// @see http://php.net/manual/zh/function.date.php#refsect1-function.date-parameters
func (c *Carbon) Format(format string) string {
format = date.ToGoFormat(format)
return c.t.Format(format)
func (c *Carbon) Format(layout string) string {
layout = date.ToGoFormat(layout)
return c.t.Format(layout)
}

func (this *Carbon) Unix() int64 {
return this.t.Unix()
}

func (this *Carbon) UnixNano() int64 {
return this.t.UnixNano()
}

func (this *Carbon) Truncate(d time.Duration) *Carbon {
return TimeOf(this.t.Truncate(d))
}

func (c *Carbon) String() string {
return c.DatetimeString()
}

func (c *Carbon) DateString() string {
return c.Format("Y-m-d")
}

func (c *Carbon) DatetimeString() string {
return c.Format("Y-m-d H:i:s")
}

func (c *Carbon) UnmarshalJSON(b []byte) (err error) {
unix, err := strconv.Atoi(string(b))
if err != nil {
err = errors.WithMessage(err, `Carbon UnmarshalJSON`)
return
}

*c = *UnixOf(int64(unix), 0)

return
}

func (c *Carbon) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprint(c.Unix())), nil
}
57 changes: 54 additions & 3 deletions date/carbon/carbon_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package carbon

import (
"encoding/json"
"fmt"
"strconv"
"testing"
"time"

Expand All @@ -25,8 +28,8 @@ func TestUnixOf(t *testing.T) {
}

func TestParse(t *testing.T) {
Parse("2012-1-1 01:02:03")
Parse("+1 day")
parse("2012-1-1 01:02:03")
parse("+1 day")
}

func TestCarbon_Format(t *testing.T) {
Expand All @@ -49,7 +52,55 @@ func TestCarbon_In(t *testing.T) {
}

func TestCarbon_Sub(t *testing.T) {
t1 := TParse("Y-m-d H:i:s", "2018-01-02 09:00:00")
t1 := ParseUTC("Y-m-d H:i:s", "2018-01-02 09:00:00")
t2 := t1.Sub(time.Hour)
test.AssertEqual(t, t2.Format("Y-m-d H:i:s"), "2018-01-02 08:00:00")
}

func TestCarbon_MarshalJSO2N(t *testing.T) {

t0 := ParseUTC("Y-m-d H:i:s", "1970-01-01 00:00:00")
js, err := json.Marshal(t0)
test.AssertNil(t, err)

test.AssertEqual(t, string(js), `0`)

t1 := ParseUTC("Y-m-d H:i:s", "2018-01-02 01:00:00")
js, err = json.Marshal(t1)
test.AssertNil(t, err)

test.AssertEqual(t, string(js), `1514854800`)
}

func TestCarbon_MarshalJSON(t *testing.T) {
type args struct {
*time.Location
str string
unixStr string
}
tests := []struct {
name string
args args
}{
// TODO: Add test cases.
{``, args{UTC, `1970-01-01 00:00:00`, `0`}},
{``, args{Shanghai, `1970-01-01 08:00:00`, `0`}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := ParseIn(`Y-m-d H:i:s`, tt.args.str, tt.args.Location)
unixBytes, err := c.MarshalJSON()

test.AssertNil(t, err)
test.AssertEqual(t, string(unixBytes), tt.args.unixStr)

unix, _ := strconv.Atoi(tt.args.unixStr)
unix += 3600
unixStr := fmt.Sprint(unix)
var c2 Carbon
err = json.Unmarshal([]byte(unixStr), &c2)
test.AssertNil(t, err)
test.AssertEqual(t, c.Add(time.Hour).String(), c2.String())
})
}
}
1 change: 1 addition & 0 deletions date/carbon/location.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ package carbon
import "time"

var (
UTC = time.UTC
Shanghai, _ = time.LoadLocation("Asia/Shanghai")
)
2 changes: 2 additions & 0 deletions date/carbon/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Carbon

3 changes: 2 additions & 1 deletion date/date.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func TimeOffset(offset time.Duration) {
}

// ToGoFormat 把 Y-m-d 转成 Go 格式
// cache ?
func ToGoFormat(format string) string {
rule := []string{
`Y`, `2006`, // 年
Expand Down Expand Up @@ -80,7 +81,7 @@ func LocalFormat(format string, timestamp ...int64) string {
// @see http://php.net/manual/en/function.strtotime.php#example-2803
func StrToTime(expr string) int64 {
t := time.Now().Local()
//pattern := `\d+ [(year)|(month)|(day)|(hour)|(minute)|(second)]`
//pattern := `(\d+|[(last)|(next)]) [(year)|(month)|(day)|(hour)|(minute)|(second)|(Monday)]`

for i := 1; i < 10; i++ {

Expand Down