This is an automated email from the ASF dual-hosted git repository.

klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/devlake.git


The following commit(s) were added to refs/heads/main by this push:
     new 43e4eb762 fix(core): parse timestamps with any number of 
fractional-second digits (#9186)
43e4eb762 is described below

commit 43e4eb76241cf022349abc5cdce9d0fa013c8a15
Author: breken <[email protected]>
AuthorDate: Sun Oct 4 10:06:01 2026 -0500

    fix(core): parse timestamps with any number of fractional-second digits 
(#9186)
    
    ConvertStringToTime and ConvertStringToTimeInLoc matched timestamps with a
    `+hh:mm` offset against fixed-width layouts (".000" and ".000000"). Any
    other precision failed: .NET's round-trip format (7 digits, e.g. PowerShell
    `Get-Date -Format o`), Go's RFC3339Nano (up to 9 digits, trailing zeros
    trimmed) and trimmed 4/5-digit values all returned a parse error.
    
    This parser backs the mapstructure decode hook, so a webhook deployment or
    incident posted with such a timestamp was rejected with 400 and never
    counted, and an Iso8601Time field in an extractor failed the subtask.
    
    Replace the two fixed-width entries with one entry that accepts any
    fraction length through the ".999999999" layout.
    
    Generated-by: Claude Code (Claude Opus 5.5)
    
    Co-authored-by: breken-ai <[email protected]>
---
 backend/core/models/common/iso8601time.go      | 11 +++++----
 backend/core/models/common/iso8601time_test.go | 31 ++++++++++++++++++++++++++
 2 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/backend/core/models/common/iso8601time.go 
b/backend/core/models/common/iso8601time.go
index a0570d009..00e032b0f 100644
--- a/backend/core/models/common/iso8601time.go
+++ b/backend/core/models/common/iso8601time.go
@@ -57,12 +57,11 @@ func init() {
                        Format:  "2006-01-02T15:04:05-0700",
                },
                {
-                       Matcher: 
regexp.MustCompile(`[\d]{6}[+-][\d]{2}:[\d]{2}$`),
-                       Format:  "2006-01-02T15:04:05.000000-07:00",
-               },
-               {
-                       Matcher: 
regexp.MustCompile(`[\d]{3}[+-][\d]{2}:[\d]{2}$`),
-                       Format:  "2006-01-02T15:04:05.000-07:00",
+                       // Fractional seconds of any length: Jira/GitLab use 3 
digits, Bitbucket
+                       // Cloud 6, .NET's round-trip format 7, and Go's 
RFC3339Nano up to 9 with
+                       // trailing zeros trimmed. The ".999999999" layout 
accepts all of them.
+                       Matcher: 
regexp.MustCompile(`\.[\d]+[+-][\d]{2}:[\d]{2}$`),
+                       Format:  "2006-01-02T15:04:05.999999999-07:00",
                },
                {
                        Matcher: regexp.MustCompile(`[+-][\d]{2}:[\d]{2}$`),
diff --git a/backend/core/models/common/iso8601time_test.go 
b/backend/core/models/common/iso8601time_test.go
index 84a33e893..3d3dcc640 100644
--- a/backend/core/models/common/iso8601time_test.go
+++ b/backend/core/models/common/iso8601time_test.go
@@ -157,6 +157,30 @@ func TestConvertStringToTime(t *testing.T) {
                        output: time.Date(2025, 9, 15, 8, 53, 36, 337932000, 
time.UTC),
                        err:    nil,
                },
+               {
+                       name:   "Valid time string with 7 fractional digits 
(.NET round-trip format)",
+                       input:  "2025-09-15T16:53:36.3379321+08:00",
+                       output: time.Date(2025, 9, 15, 8, 53, 36, 337932100, 
time.UTC),
+                       err:    nil,
+               },
+               {
+                       name:   "Valid time string with 9 fractional digits (Go 
RFC3339Nano)",
+                       input:  "2025-09-15T17:53:36.337932123+09:00",
+                       output: time.Date(2025, 9, 15, 8, 53, 36, 337932123, 
time.UTC),
+                       err:    nil,
+               },
+               {
+                       name:   "Valid time string with 4 fractional digits 
(trailing zeros trimmed)",
+                       input:  "2025-09-15T10:53:36.3379+02:00",
+                       output: time.Date(2025, 9, 15, 8, 53, 36, 337900000, 
time.UTC),
+                       err:    nil,
+               },
+               {
+                       name:   "Valid time string with 1 fractional digit",
+                       input:  "2025-09-15T08:53:36.3+00:00",
+                       output: time.Date(2025, 9, 15, 8, 53, 36, 300000000, 
time.UTC),
+                       err:    nil,
+               },
                {
                        name:   "Invalid time string",
                        input:  "invalid",
@@ -311,6 +335,13 @@ func TestConvertStringToTimeInLoc(t *testing.T) {
                        output: time.Date(2023, 3, 1, 0, 0, 0, 0, loc),
                        err:    nil,
                },
+               {
+                       name:   "Valid time string with 7 fractional digits and 
location",
+                       input:  "2023-03-01T12:30:00.1234567+08:00",
+                       loc:    loc,
+                       output: time.Date(2023, 3, 1, 12, 30, 0, 123456700, 
loc),
+                       err:    nil,
+               },
                {
                        name:   "Invalid time string with location",
                        input:  "invalid",

Reply via email to