From d9ab04aa4742a64a92ca8fdec96549dbf645d788 Mon Sep 17 00:00:00 2001 From: Dustin Oprea Date: Wed, 6 Mar 2019 11:54:15 -0500 Subject: [PATCH] utility.go: Add ExifFullTimestampString - Added time examples. - Added comments. --- ifd_builder_test.go | 5 +++++ utility.go | 11 ++++++++++- utility_test.go | 48 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/ifd_builder_test.go b/ifd_builder_test.go index 78ca790..3038d6b 100644 --- a/ifd_builder_test.go +++ b/ifd_builder_test.go @@ -1760,6 +1760,11 @@ func ExampleBuilderTag_SetValue() { // Output: } +// ExampleIfdBuilder_SetStandardWithName establishes a chain of `IfdBuilder` +// structs from an existing chain of `Ifd` structs, navigates to the IB +// representing IFD0, updates the ProcessingSoftware tag to a different value, +// encodes down to a new EXIF block, reparses, and validates that the value for +// that tag is what we set it to. func ExampleIfdBuilder_SetStandardWithName() { filepath := path.Join(assetsPath, "NDM_8901.jpg") diff --git a/utility.go b/utility.go index 0e21d6c..f1355aa 100644 --- a/utility.go +++ b/utility.go @@ -67,7 +67,8 @@ func DumpBytesClauseToString(data []byte) string { return b.String() } -// ParseExifFullTimestamp parses dates like "2018:11:30 13:01:49". +// ParseExifFullTimestamp parses dates like "2018:11:30 13:01:49" into a UTC +// `time.Time` struct. func ParseExifFullTimestamp(fullTimestampPhrase string) (timestamp time.Time, err error) { defer func() { if state := recover(); state != nil { @@ -115,3 +116,11 @@ func ParseExifFullTimestamp(fullTimestampPhrase string) (timestamp time.Time, er timestamp = time.Date(int(year), time.Month(month), int(day), int(hour), int(minute), int(second), 0, time.UTC) return timestamp, nil } + +// ExifFullTimestampString produces a string like "2018:11:30 13:01:49" from a +// `time.Time` struct. It will attempt to convert to UTC first. +func ExifFullTimestampString(t time.Time) (fullTimestampPhrase string) { + t = t.UTC() + + return fmt.Sprintf("%04d:%02d:%02d %02d:%02d:%02d", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second()) +} diff --git a/utility_test.go b/utility_test.go index 7274c82..c786e88 100644 --- a/utility_test.go +++ b/utility_test.go @@ -3,8 +3,9 @@ package exif import ( "io/ioutil" - "testing" + "fmt" "os" + "testing" "time" "github.com/dsoprea/go-logging" @@ -19,7 +20,7 @@ func TestDumpBytes(t *testing.T) { originalStdout := os.Stdout os.Stdout = f - DumpBytes([]byte { 0x11, 0x22 }) + DumpBytes([]byte{0x11, 0x22}) os.Stdout = originalStdout @@ -43,7 +44,7 @@ func TestDumpBytesClause(t *testing.T) { originalStdout := os.Stdout os.Stdout = f - DumpBytesClause([]byte { 0x11, 0x22 }) + DumpBytesClause([]byte{0x11, 0x22}) os.Stdout = originalStdout @@ -59,7 +60,7 @@ func TestDumpBytesClause(t *testing.T) { } func TestDumpBytesToString(t *testing.T) { - s := DumpBytesToString([]byte { 0x12, 0x34, 0x56 }) + s := DumpBytesToString([]byte{0x12, 0x34, 0x56}) if s != "12 34 56" { t.Fatalf("result not expected") @@ -67,7 +68,7 @@ func TestDumpBytesToString(t *testing.T) { } func TestDumpBytesClauseToString(t *testing.T) { - s := DumpBytesClauseToString([]byte { 0x12, 0x34, 0x56 }) + s := DumpBytesClauseToString([]byte{0x12, 0x34, 0x56}) if s != "0x12, 0x34, 0x56" { t.Fatalf("result not expected") @@ -85,3 +86,40 @@ func TestParseExifFullTimestamp(t *testing.T) { t.Fatalf("time not formatted correctly: [%s] != [%s]", actual, expected) } } + +func TestExifFullTimestampString(t *testing.T) { + originalPhrase := "2018:11:30 13:01:49" + + timestamp, err := ParseExifFullTimestamp(originalPhrase) + log.PanicIf(err) + + restoredPhrase := ExifFullTimestampString(timestamp) + if restoredPhrase != originalPhrase { + t.Fatalf("Final phrase [%s] does not equal original phrase [%s]", restoredPhrase, originalPhrase) + } +} + +func ExampleParseExifFullTimestamp() { + originalPhrase := "2018:11:30 13:01:49" + + timestamp, err := ParseExifFullTimestamp(originalPhrase) + log.PanicIf(err) + + fmt.Printf("To Go timestamp: [%s]\n", timestamp.Format(time.RFC3339)) + + // Output: + // To Go timestamp: [2018-11-30T13:01:49Z] +} + +func ExampleExifFullTimestampString() { + originalPhrase := "2018:11:30 13:01:49" + + timestamp, err := ParseExifFullTimestamp(originalPhrase) + log.PanicIf(err) + + restoredPhrase := ExifFullTimestampString(timestamp) + fmt.Printf("To EXIF timestamp: [%s]\n", restoredPhrase) + + // Output: + // To EXIF timestamp: [2018:11:30 13:01:49] +}