不含分隔符的分析日期时,“超出范围的月份”

Any ideas how to get golang to properly parse a date string such as 31916 I keep getting a month out of range error.

date, err := time.Parse("1206", "31916")
fmt.Println(date, err)

Of course I want to treat the month as 3 and not 31 like it's doing, but I'm not sure how to force it to stop at 3 for the month outside of adding separators to the format.

For example,

package main

import (
    "fmt"
    "time"
)

func parseDate(date string) (time.Time, error) {
    if len(date) == 5 {
        date = "0" + date
    }
    return time.Parse("010206", date)

}

func main() {
    date, err := parseDate("31916")
    fmt.Println(date, err)
    date, err = parseDate("031916")
    fmt.Println(date, err)
    date, err = parseDate("121916")
    fmt.Println(date, err)
}

Output:

2016-03-19 00:00:00 +0000 UTC <nil>
2016-03-19 00:00:00 +0000 UTC <nil>
2016-12-19 00:00:00 +0000 UTC <nil>

You can't. The layout you pass is not deterministic - there is no way for Go to know when the month ends and the day starts in your string - besides when one option fails and the other one does not (think of "11106" - is that 1\11\06 or 11\1\06?). Your best bet is to write a wrapper which makes the choice deterministic:

import (
  "time"
  "strconv"
)

func parseWeirdLayout(dateString string) (time.Time, error) {
  parsedString := ""
  if len(dateString) == 5 {
    month, err := strconv.Atoi(dateString[0:2])
    if err != nil {
      return time.Now(), err
    }
    if month < 1 || month > 12 {
      parsedString = "0" + dateString 
    } else {
      parsedString = dateString[:2] + "0" + dateString[2:]
    }
  } else if len(dateString) == 4 {
    parsedString = "0" + dateString[:1] + "0" + dateString[1:]
  }

  return time.Parse("010206", parsedString)
}

Test here: https://play.golang.org/p/u1QFPzehMj

Or simply use a different, deterministic layout, e.g. "010206".