增加对 U, V, X, Z 符号的解析支持

This commit is contained in:
Peleus 2023-12-26 22:12:48 +08:00
parent e2727ed5f7
commit 6b3822fa1b
4 changed files with 52 additions and 8 deletions

View File

@ -30,6 +30,11 @@ var formats = map[byte]string{
'T': "MST", // Zone: Timezone abbreviation. Eg: UTC, EST, MDT ...
'c': "2006-01-02T15:04:05-07:00", // Format: ISO 8601 date. Eg: 2004-02-12T15:19:21+00:00.
'r': "Thu, 21 Dec 2000 16:01:07 +0200", // Format: RFC 2822 formatted date. Eg: Thu, 21 Dec 2000 16:01:07 +0200.
'U': "timestamp", // Timestamp with second. Eg: 1699677240.
'V': "timestampMilli", // TimestampMilli with second. Eg: 1596604455666.
'X': "timestampMicro", // TimestampMicro with second. Eg: 1596604455666666.
'Z': "timestampNano", // TimestampNano with second. Eg: 1596604455666666666.
}
// common layout symbols

View File

@ -739,6 +739,14 @@ func (c Carbon) ToFormatString(format string, timezone ...string) string {
buffer.WriteString(c.ToMonthString())
case 'M': // short month, such as Jan
buffer.WriteString(c.ToShortMonthString())
case 'U': // timestamp with second, such as 1596604455
buffer.WriteString(strconv.FormatInt(c.Timestamp(), 10))
case 'V': // timestamp with millisecond, such as 1596604455000
buffer.WriteString(strconv.FormatInt(c.TimestampMilli(), 10))
case 'X': // timestamp with microsecond, such as 1596604455000000
buffer.WriteString(strconv.FormatInt(c.TimestampMicro(), 10))
case 'Z': // timestamp with nanoseconds, such as 1596604455000000000
buffer.WriteString(strconv.FormatInt(c.TimestampNano(), 10))
default: // common symbols
buffer.WriteString(c.ToStdTime().Format(layout))
}
@ -773,14 +781,6 @@ func (c Carbon) ToFormatString(format string, timezone ...string) string {
}
case 'G': // 24-hour format, no padding, ranging from 0-23
buffer.WriteString(strconv.Itoa(c.Hour()))
case 'U': // timestamp with second, such as 1596604455
buffer.WriteString(strconv.FormatInt(c.Timestamp(), 10))
case 'V': // timestamp with millisecond, such as 1596604455000
buffer.WriteString(strconv.FormatInt(c.TimestampMilli(), 10))
case 'X': // timestamp with microsecond, such as 1596604455000000
buffer.WriteString(strconv.FormatInt(c.TimestampMicro(), 10))
case 'Z': // timestamp with nanoseconds, such as 1596604455000000000
buffer.WriteString(strconv.FormatInt(c.TimestampNano(), 10))
case 'v': // current millisecond, such as 999
s := c.Layout(".999")
buffer.WriteString(strings.Trim(s, "."))

View File

@ -1,6 +1,7 @@
package carbon
import (
"strconv"
"time"
)
@ -66,6 +67,22 @@ func (c Carbon) ParseByLayout(value, layout string, timezone ...string) Carbon {
if value == "" || value == "0" || value == "0000-00-00 00:00:00" || value == "0000-00-00" || value == "00:00:00" {
return c
}
if layout == "timestamp" {
timestamp, _ := strconv.ParseInt(value, 10, 64)
return c.CreateFromTimestamp(timestamp)
}
if layout == "timestampMilli" {
timestamp, _ := strconv.ParseInt(value, 10, 64)
return c.CreateFromTimestampMilli(timestamp)
}
if layout == "timestampMicro" {
timestamp, _ := strconv.ParseInt(value, 10, 64)
return c.CreateFromTimestampMicro(timestamp)
}
if layout == "timestampNano" {
timestamp, _ := strconv.ParseInt(value, 10, 64)
return c.CreateFromTimestampNano(timestamp)
}
tt, err := time.ParseInLocation(layout, value, c.loc)
if err != nil {
c.Error = invalidLayoutError(value, layout)

View File

@ -204,3 +204,25 @@ func TestError_ParseByFormat(t *testing.T) {
assert.NotNil(t, ParseByFormat("2020-08-05", "Y-m-d", "xxx").Error, "It should catch an exception in ParseByFormat()")
assert.NotNil(t, ParseByFormat("xxx", "Y-m-d", PRC).Error, "It should catch an exception in ParseByFormat")
}
// https://github.com/golang-module/carbon/issues/206
func TestCarbon_Issue206(t *testing.T) {
assert := assert.New(t)
tests := []struct {
input string
format string
expected string
}{
0: {"1699677240", "U", "2023-11-11 12:34:00 +0800 CST"},
1: {"1699677240666", "V", "2023-11-11 12:34:00.666 +0800 CST"},
2: {"1699677240666666", "X", "2023-11-11 12:34:00.666666 +0800 CST"},
3: {"1699677240666666666", "Z", "2023-11-11 12:34:00.666666666 +0800 CST"},
}
for index, test := range tests {
c := ParseByFormat(test.input, test.format, PRC)
assert.Nil(c.Error)
assert.Equal(test.expected, c.ToString(), "Current test index is "+strconv.Itoa(index))
}
}