dromara / carbon

A simple, semantic and developer-friendly golang package for time
https://pkg.go.dev/github.com/golang-module/carbon/v2
MIT License
4.77k stars 238 forks source link

ParseByFormat fails to detect location Location #224

Closed twoojoo closed 7 months ago

twoojoo commented 7 months ago

Hello,

I encountered an issue with the following code:

I generate a datatime string with ToFormatString(), but when i use ParseByFormat() on that string to convert it back to carbon.Carbon it fails using the same format.

package main

import (
    "fmt"

    "github.com/golang-module/carbon/v2"
)

func main() {
    format := "Y-m-d - H:i:s - e"

    str := carbon.Now().ToFormatString(format, carbon.NewYork)

    dt := carbon.ParseByFormat(str, format)

        fmt.Println(dt.Error)
}

golang version: 1.21.6

carbon version: 2

time zone: CET

I expected to get:

<nil>

But I actually get:

cannot parse string "2024-03-03 - 03:56:49 - America/New_York" as carbon by format "Y-m-d - H:i:s - e", please make sure the value and format match

Thanks!

gouguoyin commented 7 months ago

ParseByFormat method only supports the following symbols

var formats = map[byte]string{
    'd': "02",      // Day:    Day of the month, 2 digits with leading zeros. Eg: 01 to 31.
    'D': "Mon",     // Day:    A textual representation of a day, three letters. Eg: Mon through Sun.
    'j': "2",       // Day:    Day of the month without leading zeros. Eg: 1 to 31.
    'l': "Monday",  // Day:    A full textual representation of the day of the week. Eg: Sunday through Saturday.
    'F': "January", // Month:  A full textual representation of a month, such as January or March. Eg: January through December.
    'm': "01",      // Month:  Numeric representation of a month, with leading zeros. Eg: 01 through 12.
    'M': "Jan",     // Month:  A short textual representation of a month, three letters. Eg: Jan through Dec.
    'n': "1",       // Month:  Numeric representation of a month, without leading zeros. Eg: 1 through 12.
    'Y': "2006",    // Year:   A full numeric representation of a year, 4 digits. Eg: 1999 or 2003.
    'y': "06",      // Year:   A two digit representation of a year. Eg: 99 or 03.
    'a': "pm",      // Time:   Lowercase morning or afternoon sign. Eg: am or pm.
    'A': "PM",      // Time:   Uppercase morning or afternoon sign. Eg: AM or PM.
    'g': "3",       // Time:   12-hour format of an hour without leading zeros. Eg: 1 through 12.
    'h': "03",      // Time:   12-hour format of an hour with leading zeros. Eg: 01 through 12.
    'H': "15",      // Time:   24-hour format of an hour with leading zeros. Eg: 00 through 23.
    'i': "04",      // Time:   Minutes with leading zeros. Eg: 00 to 59.
    's': "05",      // Time:   Seconds with leading zeros. Eg: 00 through 59.
    'O': "-0700",   // Zone:   Difference to Greenwich time (GMT) in hours. Eg: +0200.
    'P': "-07:00",  // Zone:   Difference to Greenwich time (GMT) with colon between hours and minutes. Eg: +02:00.
    'T': "MST",     // Zone:   Timezone abbreviation. Eg: UTC, EST, MDT ...

    '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.
}
gouguoyin commented 7 months ago

The recommended usage method is as follows

str := carbon.Now().ToFormatString("Y-m-d - H:i:s - e", carbon.NewYork)

fmt.Println(str) // 2024-03-03 - 07:50:47 - America/New_York

dt := carbon.ParseByFormat(str, "Y-m-d - H:i:s - \\A\\m\\e\\r\\i\\c\\a\\/\\N\\e\\w\\_\\Y\\o\\r\\k")

fmt.Println(dt.Error) // nil