Skip to content

proposal: time: also support 31 as day in time layout #45645

@akupila

Description

@akupila

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/day

The 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:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions