Skip to content

Commit 2c77d88

Browse files
author
Kim Ngo
committed
Add unix epoch timestamp transform
1 parent ed55cc7 commit 2c77d88

3 files changed

Lines changed: 58 additions & 6 deletions

File tree

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ syntax. **Note**: this operation is done in-place. If you want to preserve the
227227
original string(s), pair the transform with `shift`. This transform also
228228
supports the `$now` operator for `inputFormat`, which will set the current
229229
timestamp at the specified path, formatted according to the `outputFormat`.
230+
`$unix` is supported for both input and output formats as a Unix time, the
231+
number of seconds elapsed since January 1, 1970 UTC as an integer string.
230232
```javascript
231233
{
232234
"operation": "timestamp",
@@ -237,7 +239,11 @@ timestamp at the specified path, formatted according to the `outputFormat`.
237239
"nowTimestamp": {
238240
"inputFormat": "$now",
239241
"outputFormat": "2006-01-02T15:04:05-0700"
240-
}
242+
},
243+
"epochTimestamp": {
244+
"inputFormat": "2006-01-02T15:04:05-0700",
245+
"outputFormat": "$unix"
246+
}
241247
}
242248

243249
```

transform/timestamp.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import (
1313
// This is necessary for testing purposes
1414
var now = time.Now
1515

16+
const unixFormat = "$unix"
17+
1618
// Timestamp parses and formats timestamp strings using the golang syntax
1719
func Timestamp(spec *Config, data []byte) ([]byte, error) {
1820
for k, v := range *spec.Spec {
@@ -96,10 +98,29 @@ func Timestamp(spec *Config, data []byte) ([]byte, error) {
9698

9799
// parseAndFormatValue generates a properly formatted timestamp
98100
func parseAndFormatValue(inputFormat, outputFormat, unformattedItem string) (string, error) {
99-
parsedItem, err := time.Parse(inputFormat, unformattedItem)
100-
if err != nil {
101-
return "", err
101+
var (
102+
parsedItem time.Time
103+
formattedItem string
104+
err error
105+
)
106+
107+
if inputFormat == unixFormat {
108+
i, err := strconv.ParseInt(unformattedItem, 10, 64)
109+
if err != nil {
110+
return "", err
111+
}
112+
parsedItem = time.Unix(i, 0)
113+
} else {
114+
parsedItem, err = time.Parse(inputFormat, unformattedItem)
115+
if err != nil {
116+
return "", err
117+
}
118+
}
119+
120+
if outputFormat == unixFormat {
121+
formattedItem = strconv.FormatInt(parsedItem.Unix(), 10)
122+
} else {
123+
formattedItem = parsedItem.Format(outputFormat)
102124
}
103-
formattedItem := strings.Join([]string{"\"", parsedItem.Format(outputFormat), "\""}, "")
104-
return formattedItem, nil
125+
return strings.Join([]string{"\"", formattedItem, "\""}, ""), nil
105126
}

transform/timestamp_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ func TestParseAndFormatValue(t *testing.T) {
169169
{time.UnixDate, "\"Fri Jul 21 08:15:27 +0100 2017\""},
170170
{time.RFC3339, "\"2017-07-21T08:15:27+01:00\""},
171171
{time.StampNano, "\"Jul 21 08:15:27.000000000\""},
172+
{"$unix", "\"1500621327\""},
172173
}
173174
for _, testItem := range parseAndFormatTests {
174175
actual, _ := parseAndFormatValue(inputFormat, testItem.outputFormat, inputTimestamp)
@@ -179,3 +180,27 @@ func TestParseAndFormatValue(t *testing.T) {
179180
}
180181
}
181182
}
183+
184+
func TestParseAndFormatValueOutputUnix(t *testing.T) {
185+
parseAndFormatTests := []struct {
186+
inputFormat string
187+
inputTimestamp string
188+
expectedOutput string
189+
}{
190+
// test against a sampling of common formats
191+
{"2006-01-02T15:04:05-0700", "2017-07-21T08:15:27+0100", "\"1500621327\""},
192+
{"January _2, 2006", "July 21, 2017", "\"1500595200\""},
193+
{time.ANSIC, "Fri Jul 21 08:15:27 2017", "\"1500624927\""},
194+
{time.UnixDate, "Fri Jul 21 08:15:27 GMT 2017", "\"1500624927\""},
195+
{time.RFC3339, "2017-07-21T08:15:27+01:00", "\"1500621327\""},
196+
{"$unix", "1500621327", "\"1500621327\""},
197+
}
198+
for _, testItem := range parseAndFormatTests {
199+
actual, _ := parseAndFormatValue(testItem.inputFormat, "$unix", testItem.inputTimestamp)
200+
if actual != testItem.expectedOutput {
201+
t.Error("Error data does not match expectation.", testItem.inputFormat)
202+
t.Log("Expected: ", testItem.expectedOutput)
203+
t.Log("Actual: ", actual)
204+
}
205+
}
206+
}

0 commit comments

Comments
 (0)