增加可选参数timezone以及对负数时间戳的支持

This commit is contained in:
gouguoyin 2021-07-23 10:56:39 +08:00
parent a8ee4f7fc8
commit 4534c6e365
2 changed files with 132 additions and 42 deletions

View File

@ -6,12 +6,20 @@ import (
)
// CreateFromTimestamp 从时间戳创建 Carbon 实例
func (c Carbon) CreateFromTimestamp(timestamp int64) Carbon {
ts := timestamp
if ts == 0 {
func (c Carbon) CreateFromTimestamp(timestamp int64, timezone ...string) Carbon {
if len(timezone) == 1 {
loc, err := getLocationByTimezone(timezone[0])
c.Loc = loc
c.Error = err
}
if c.Error != nil {
return c
}
switch len(strconv.FormatInt(timestamp, 10)) {
ts, count := timestamp, len(strconv.FormatInt(timestamp, 10))
if timestamp < 0 {
count -= 1
}
switch count {
case 10:
ts = timestamp
case 13:
@ -20,49 +28,71 @@ func (c Carbon) CreateFromTimestamp(timestamp int64) Carbon {
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 NewCarbon().CreateFromTimestamp(timestamp)
func CreateFromTimestamp(timestamp int64, timezone ...string) Carbon {
return NewCarbon().CreateFromTimestamp(timestamp, timezone...)
}
// CreateFromDateTime 从年月日时分秒创建 Carbon 实例
func (c Carbon) CreateFromDateTime(year int, month int, day int, hour int, minute int, second int) Carbon {
func (c Carbon) CreateFromDateTime(year int, month int, day int, hour int, minute int, second int, timezone ...string) Carbon {
if len(timezone) == 1 {
loc, err := getLocationByTimezone(timezone[0])
c.Loc = loc
c.Error = err
}
if c.Error != nil {
return c
}
c.Time = time.Date(year, time.Month(month), day, hour, minute, second, time.Now().Nanosecond(), c.Loc)
return c
}
// CreateFromDateTime 从年月日时分秒创建 Carbon 实例(默认时区)
func CreateFromDateTime(year int, month int, day int, hour int, minute int, second int) Carbon {
return NewCarbon().CreateFromDateTime(year, month, day, hour, minute, second)
// CreateFromDateTime 从年月日时分秒创建 Carbon 实例
func CreateFromDateTime(year int, month int, day int, hour int, minute int, second int, timezone ...string) Carbon {
return NewCarbon().CreateFromDateTime(year, month, day, hour, minute, second, timezone...)
}
// CreateFromDate 从年月日创建 Carbon 实例
func (c Carbon) CreateFromDate(year int, month int, day int) Carbon {
hour, minute, second := time.Now().Clock()
func (c Carbon) CreateFromDate(year int, month int, day int, timezone ...string) Carbon {
if len(timezone) == 1 {
loc, err := getLocationByTimezone(timezone[0])
c.Loc = loc
c.Error = err
}
if c.Error != nil {
return c
}
hour, minute, second := time.Now().In(c.Loc).Clock()
c.Time = time.Date(year, time.Month(month), day, hour, minute, second, time.Now().Nanosecond(), c.Loc)
return c
}
// CreateFromDate 从年月日创建 Carbon 实例(默认时区)
func CreateFromDate(year int, month int, day int) Carbon {
return NewCarbon().CreateFromDate(year, month, day)
// CreateFromDate 从年月日创建 Carbon 实例
func CreateFromDate(year int, month int, day int, timezone ...string) Carbon {
return NewCarbon().CreateFromDate(year, month, day, timezone...)
}
// CreateFromTime 从时分秒创建 Carbon 实例
func (c Carbon) CreateFromTime(hour int, minute int, second int) Carbon {
year, month, day := time.Now().Date()
func (c Carbon) CreateFromTime(hour int, minute int, second int, timezone ...string) Carbon {
if len(timezone) == 1 {
loc, err := getLocationByTimezone(timezone[0])
c.Loc = loc
c.Error = err
}
if c.Error != nil {
return c
}
year, month, day := time.Now().In(c.Loc).Date()
c.Time = time.Date(year, month, day, hour, minute, second, time.Now().Nanosecond(), c.Loc)
return c
}
// CreateFromTime 从时分秒创建 Carbon 实例(默认时区)
func CreateFromTime(hour int, minute int, second int) Carbon {
return NewCarbon().CreateFromTime(hour, minute, second)
// CreateFromTime 从时分秒创建 Carbon 实例
func CreateFromTime(hour int, minute int, second int, timezone ...string) Carbon {
return NewCarbon().CreateFromTime(hour, minute, second, timezone...)
}

View File

@ -13,21 +13,36 @@ func TestCarbon_CreateFromTimestamp(t *testing.T) {
tests := []struct {
id int // 测试id
timestamp int64 // 输入参数
output string // 期望输出
expected string // 期望
}{
{1, 0, ""},
{2, 123456, "1970-01-01 08:00:00"},
{3, 1577855655, "2020-01-01 13:14:15"},
{4, 1604074084682, "2020-10-31 00:08:04"},
{5, 1604074196366540, "2020-10-31 00:09:56"},
{6, 1604074298500312000, "2020-10-31 00:11:38"},
{1, -1, "1970-01-01 07:59:59"},
{2, 0, "1970-01-01 08:00:00"},
{4, 1577855655, "2020-01-01 13:14:15"},
{5, 1604074084682, "2020-10-31 00:08:04"},
{6, 1604074196366540, "2020-10-31 00:09:56"},
{7, 1604074298500312000, "2020-10-31 00:11:38"},
}
for _, test := range tests {
c := CreateFromTimestamp(test.timestamp)
c := SetTimezone(PRC).CreateFromTimestamp(test.timestamp)
assert.Nil(c.Error)
assert.Equal(c.ToDateTimeString(), test.output, "Current test id is "+strconv.Itoa(test.id))
assert.Equal(test.expected, c.ToDateTimeString(), "Current test id is "+strconv.Itoa(test.id))
}
for _, test := range tests {
c := CreateFromTimestamp(test.timestamp, PRC)
assert.Nil(c.Error)
assert.Equal(test.expected, c.ToDateTimeString(), "Current test id is "+strconv.Itoa(test.id))
}
}
func TestError_CreateFromTimestamp(t *testing.T) {
timestamp, timezone := int64(1577855655), "xxx"
c1 := SetTimezone(timezone).CreateFromTimestamp(timestamp)
assert.Equal(t, invalidTimezoneError(timezone), c1.Error, "Should catch an exception in CreateFromTimestamp()")
c2 := CreateFromTimestamp(timestamp, timezone)
assert.Equal(t, invalidTimezoneError(timezone), c2.Error, "Should catch an exception in CreateFromTimestamp()")
}
func TestCarbon_CreateFromDateTime(t *testing.T) {
@ -36,7 +51,7 @@ func TestCarbon_CreateFromDateTime(t *testing.T) {
tests := []struct {
id int // 测试id
year, month, day, hour, minute, second int // 输入参数
output string // 期望输出
expected string // 期望
}{
{1, 2020, 1, 1, 13, 14, 15, "2020-01-01 13:14:15"},
{2, 2020, 1, 31, 13, 14, 15, "2020-01-31 13:14:15"},
@ -46,20 +61,35 @@ func TestCarbon_CreateFromDateTime(t *testing.T) {
}
for _, test := range tests {
c := CreateFromDateTime(test.year, test.month, test.day, test.hour, test.minute, test.second)
c := SetTimezone(PRC).CreateFromDateTime(test.year, test.month, test.day, test.hour, test.minute, test.second)
assert.Nil(c.Error)
assert.Equal(c.ToDateTimeString(), test.output, "Current test id is "+strconv.Itoa(test.id))
assert.Equal(test.expected, c.ToDateTimeString(), "Current test id is "+strconv.Itoa(test.id))
}
for _, test := range tests {
c := CreateFromDateTime(test.year, test.month, test.day, test.hour, test.minute, test.second, PRC)
assert.Nil(c.Error)
assert.Equal(test.expected, c.ToDateTimeString(), "Current test id is "+strconv.Itoa(test.id))
}
}
func TestError_CreateFromDateTime(t *testing.T) {
year, month, day, hour, minute, second, timezone := 2020, 1, 1, 13, 14, 15, "xxx"
c1 := SetTimezone(timezone).CreateFromDateTime(year, month, day, hour, minute, second)
assert.Equal(t, invalidTimezoneError(timezone), c1.Error, "Should catch an exception in CreateFromDateTime()")
c2 := CreateFromDateTime(year, month, day, hour, minute, second, timezone)
assert.Equal(t, invalidTimezoneError(timezone), c2.Error, "Should catch an exception in CreateFromDateTime()")
}
func TestCarbon_CreateFromDate(t *testing.T) {
assert := assert.New(t)
clock := Now().ToTimeString()
clock := Now(PRC).ToTimeString()
tests := []struct {
id int // 测试id
year, month, day int // 输入参数
output string // 期望输出值
expected string // 期望
}{
{1, 2020, 1, 1, "2020-01-01 " + clock},
{2, 2020, 1, 31, "2020-01-31 " + clock},
@ -69,20 +99,35 @@ func TestCarbon_CreateFromDate(t *testing.T) {
}
for _, test := range tests {
c := CreateFromDate(test.year, test.month, test.day)
c := SetTimezone(PRC).CreateFromDate(test.year, test.month, test.day)
assert.Nil(c.Error)
assert.Equal(c.ToDateTimeString(), test.output, "Current test id is "+strconv.Itoa(test.id))
assert.Equal(test.expected, c.ToDateTimeString(), "Current test id is "+strconv.Itoa(test.id))
}
for _, test := range tests {
c := CreateFromDate(test.year, test.month, test.day, PRC)
assert.Nil(c.Error)
assert.Equal(test.expected, c.ToDateTimeString(), "Current test id is "+strconv.Itoa(test.id))
}
}
func TestError_CreateFromDate(t *testing.T) {
year, month, day, timezone := 13, 14, 15, "xxx"
c1 := SetTimezone(timezone).CreateFromDate(year, month, day)
assert.Equal(t, invalidTimezoneError(timezone), c1.Error, "Should catch an exception in CreateFromDate()")
c2 := CreateFromDate(year, month, day, timezone)
assert.Equal(t, invalidTimezoneError(timezone), c2.Error, "Should catch an exception in CreateFromDate()")
}
func TestCarbon_CreateFromTime(t *testing.T) {
assert := assert.New(t)
date := Now().ToDateString()
date := Now(PRC).ToDateString()
tests := []struct {
id int // 测试id
hour, minute, second int // 输入参数
output string // 期望输出值
expected string // 期望
}{
{1, 0, 0, 0, date + " 00:00:00"},
{2, 00, 00, 15, date + " 00:00:15"},
@ -91,8 +136,23 @@ func TestCarbon_CreateFromTime(t *testing.T) {
}
for _, test := range tests {
c := CreateFromTime(test.hour, test.minute, test.second)
c := SetTimezone(PRC).CreateFromTime(test.hour, test.minute, test.second)
assert.Nil(c.Error)
assert.Equal(c.ToDateTimeString(), test.output, "Current test id is "+strconv.Itoa(test.id))
assert.Equal(test.expected, c.ToDateTimeString(), "Current test id is "+strconv.Itoa(test.id))
}
for _, test := range tests {
c := CreateFromTime(test.hour, test.minute, test.second, PRC)
assert.Nil(c.Error)
assert.Equal(test.expected, c.ToDateTimeString(), "Current test id is "+strconv.Itoa(test.id))
}
}
func TestError_CreateFromTime(t *testing.T) {
hour, minute, second, timezone := 13, 14, 15, "xxx"
c1 := SetTimezone(timezone).CreateFromTime(hour, minute, second)
assert.Equal(t, invalidTimezoneError(timezone), c1.Error, "Should catch an exception in CreateFromTime()")
c2 := CreateFromTime(hour, minute, second, timezone)
assert.Equal(t, invalidTimezoneError(timezone), c2.Error, "Should catch an exception in CreateFromTime()")
}