Skip to content

Commit

Permalink
Implement timePrecisionParser (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
hrkskov committed Jun 17, 2023
1 parent e0a3604 commit 6a475dd
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
41 changes: 39 additions & 2 deletions internal/function_time_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package internal

import (
"fmt"
"regexp"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -1349,8 +1350,44 @@ func timeZoneRFC3339Formatter(t *time.Time) ([]rune, error) {
return []rune(t.Format("-07:00")), nil
}

func timePrecisionParser(precision int, target []rune, t *time.Time) (int, error) {
return 0, fmt.Errorf("unimplemented time precision matcher")
var timePrecisionMatcher = regexp.MustCompile(`[0-9]{2}\.?[0-9]*`)

func timePrecisionParser(precision int, text []rune, t *time.Time) (int, error) {
const maxNanosecondsLength = 9
extracted := timePrecisionMatcher.FindString(string(text))
if len(extracted) == 0 {
return 0, fmt.Errorf("failed to parse seconds.nanoseconds for %s", string(text))
}
fmtLen := len(extracted)
splitted := strings.Split(extracted, ".")
seconds := splitted[0]
nanoseconds := strconv.Itoa(t.Nanosecond())
if len(splitted) == 2 {
nanoseconds = splitted[1]
if len(nanoseconds) > precision {
nanoseconds = nanoseconds[:precision]
}
nanoseconds = nanoseconds + strings.Repeat("0", maxNanosecondsLength-len(nanoseconds))
}
s, err := strconv.ParseInt(seconds, 10, 64)
if err != nil {
return 0, fmt.Errorf("failed to parse seconds parameter for %s: %w", string(text), err)
}
n, err := strconv.ParseInt(nanoseconds, 10, 64)
if err != nil {
return 0, fmt.Errorf("failed to parse nanoseconds parameter for %s: %w", string(text), err)
}
*t = time.Date(
int(t.Year()),
t.Month(),
int(t.Day()),
int(t.Hour()),
int(t.Minute()),
int(s),
int(n),
t.Location(),
)
return fmtLen, nil
}

func timePrecisionFormatter(precision int, t *time.Time) ([]rune, error) {
Expand Down
7 changes: 6 additions & 1 deletion query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4067,6 +4067,11 @@ SELECT date, EXTRACT(ISOYEAR FROM date), EXTRACT(YEAR FROM date), EXTRACT(MONTH
query: `SELECT PARSE_TIMESTAMP("%Y-%m-%d %H:%M:%S%Ez", "2020-06-02 23:58:40+09:00")`,
expectedRows: [][]interface{}{{createTimestampFormatFromString("2020-06-02 14:58:40+00")}},
},
{
name: "parse timestamp with %Y-%m-%d %H:%M:%E*S%Ez",
query: `SELECT PARSE_TIMESTAMP("%Y-%m-%d %H:%M:%E*S%Ez", "2020-06-02 23:58:40.123+09:00")`,
expectedRows: [][]interface{}{{createTimestampFormatFromString("2020-06-02 14:58:40.123+00")}},
},
{
name: "parse timestamp ( the year element is in different locations )",
query: `SELECT PARSE_TIMESTAMP("%a %b %e %Y %I:%M:%S", "Thu Dec 25 07:30:00 2008")`,
Expand Down Expand Up @@ -5056,6 +5061,6 @@ func createTimestampFormatFromTime(t time.Time) string {
}

func createTimestampFormatFromString(v string) string {
t, _ := time.Parse("2006-01-02 15:04:05+00", v)
t, _ := time.Parse("2006-01-02 15:04:05.999999+00", v)
return createTimestampFormatFromTime(t)
}

0 comments on commit 6a475dd

Please sign in to comment.