Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode: preserve nanosecond precision when decoding time #626

Merged
merged 3 commits into from
Oct 18, 2021

Conversation

moorereason
Copy link
Contributor

Updates #613
Competitor to #621

localtime.go Outdated
}

// String returns RFC 3339 representation of d.
func (d LocalTime) String() string {
s := fmt.Sprintf("%02d:%02d:%02d", d.Hour, d.Minute, d.Second)
if d.Nanosecond == 0 {
if d.Nanosecond == 0 && d.Precision == 0 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for later: I'd expect this to be a || instead of a &&, so that when Precision is 0 the nanoseconds are not displayed. However this does create an issue where the zero-value of LocalTime is has the surprising behavior:

t := LocalTime{Nanosecond: 42}
t.String() => "00:00:00"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My primary use case was decoding. I was trying to allow for this scenario (which I failed to cover in this PR):

diff --git a/localtime_test.go b/localtime_test.go
index 089a8ba..9c9b681 100644
--- a/localtime_test.go
+++ b/localtime_test.go
@@ -41,6 +41,8 @@ func TestLocalTime_String(t *testing.T) {
        require.Equal(t, "20:12:01.000000002", d.String())
        d = toml.LocalTime{20, 12, 1, 0, 0}
        require.Equal(t, "20:12:01", d.String())
+       d = toml.LocalTime{20, 12, 1, 0, 9}
+       require.Equal(t, "20:12:01.000000000", d.String())
 }

 func TestLocalTime_MarshalText(t *testing.T) {
diff --git a/unmarshaler_test.go b/unmarshaler_test.go
index e7e44f7..0fddbbc 100644
--- a/unmarshaler_test.go
+++ b/unmarshaler_test.go
@@ -2038,6 +2038,11 @@ func TestLocalDateTime(t *testing.T) {
                input string
                prec  int
        }{
+               {
+                       desc:  "9 digits zero nanoseconds",
+                       input: "2006-01-02T15:04:05.000000000",
+                       prec:  9,
+               },
                {
                        desc:  "9 digits",
                        input: "2006-01-02T15:04:05.123456789",

I can push these test additions up if you want me to.

I hadn't completely thought through the case you offered. If the user plans to have custom LocalTime values, they will need to also set Precision in order for the String() output to be what's expected. Is this a use case we need to be concerned about? I assumed that most people will be using time.Time values in their app instead of toml.LocalTime.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went ahead and pushed up these additional test cases.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ended up going with a mix of both ideas by providing the minimum number of digits as precision when it is not specified d58efa3.

@pelletier pelletier merged commit a23850f into pelletier:v2 Oct 18, 2021
@pelletier pelletier changed the title decode: preserve nanosecond precision when decoding time Decode: preserve nanosecond precision when decoding time Oct 28, 2021
@pelletier pelletier added the feature Issue asking for a new feature in go-toml. label Oct 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Issue asking for a new feature in go-toml.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants