-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
I propose adding 31 as an alternative to the day in the time layout string. There have been proposals/issues before discussing the go time layout, but I haven't seen this before.
The main rationale is that the current January 2nd format is not obvious, as 01 and 02 are easy to mix up. This is even more the case outside of the US, where it's common to format dates as YYYY-MM-DD or DD-MM-YYYY.
Consider the following:
a := time.Now().Format("2006-01-02")
b := time.Now().Format("2006-01-31")I think the latter (b) produces more readable code because there is no ambiguity in what the output will be. It is immediately obvious to the reader which one is the month and which one is the day.
This is even more clear when the year is "disconnected" from the day/month:
time.Now().Format("01/02 2006") // Is this day/month or month/day?
time.Now().Format("02/01 2006") // Or do we want this?
time.Now().Format("01/31 2006") // Can only be month/dayThe same of course applies to parsing dates:
a, err := time.Parse("2006-01-02 15:04:05", str)
b, err := time.Parse("2006-01-31 15:04:05", str)I'm not proposing to change the existing format, just to also support 31 for formatting/parsing the day.
This does add another way of doing the same thing, which could be seen as a negative. However, I think it does improve readability (especially outside the US), so I hope this proposal can be considered.
Why 31
While any number after 12 (except 15 because of 24h hour) would work, I believe 31 is an "even" and recognizable number when it comes to calendar dates. January happens to have 31 days so the new reference date is also a valid real-world date.
Another option would be 20, which is a "reverse" of the current zero prefixed day 02. 20 has the downside that it can be confused with 8pm in a 24h clock.
Padding
Defining padding is not possible here. I think it should format with a leading zeros because 31 has two digits and based on my anecdotal evidence, it's more common to have a leading zero. If formatting a date without leading zero is important, the existing 2 or _2 can still be used.
Backwards compatibility
As far as I can tell, this change is backward compatible. The only case where I can think of this causing different behavior from before is if 31 is used in the layout string, but this would have caused unexpected results as 3 and 1 would already be replaced with the 12h hour and month.
Implementation
Currently 3 is parsed as the 12h clock hour. The change would continue parsing the date to see if it is followed by a 1. Believe this would just mean adding the following here:
-case '3':
+case '3': // 31, 3
+ if len(layout) >= i+2 && layout[i+1] == '1' {
+ return layout[0:i], stdZeroDay, layout[i+2:]
+ }
return layout[0:i], stdHour12, layout[i+1:]Similar proposals:
- Strftime or YYYY-MM-DD hh:mm:ss alternative time formatting #40287 - Add "YYYY-MM-DD hh:mm:ss"
- proposal: time: use big-endian/ISO reference time #25572 - Change to "2001-02-03 16:05:06-0700"
- time: Go should support Dec 31, 23:59:05, 1999 as an alternative format date #9696 - Add "Dec 31, 23:59:05, 1999"
- Implement strftime #444, need time.Strftime #8390, Add an interface to strftime to the time package #25294 - "%Y-%m-%d %H:%M:%S" (strftime)