diff --git a/internal/piwigo/piwigotools/base64.go b/internal/base64/chunker.go
similarity index 69%
rename from internal/piwigo/piwigotools/base64.go
rename to internal/base64/chunker.go
index ff40a67..5ab8616 100644
--- a/internal/piwigo/piwigotools/base64.go
+++ b/internal/base64/chunker.go
@@ -1,8 +1,8 @@
-package piwigotools
+package base64
 
 import (
 	"bytes"
-	"encoding/base64"
+	b64 "encoding/base64"
 	"os"
 )
 
@@ -10,29 +10,29 @@ var CHUNK_SIZE int64 = 1 * 1024 * 1024
 var CHUNK_BUFF_SIZE int64 = 32 * 1024
 var CHUNK_BUFF_COUNT = CHUNK_SIZE / CHUNK_BUFF_SIZE
 
-type Base64Chunk struct {
+type Chunk struct {
 	Position int64
 	Size     int64
 	Buffer   bytes.Buffer
 }
 
-func Base64Chunker(filename string) (out chan *Base64Chunk, err error) {
+func Chunker(filename string) (chan *Chunk, error) {
 	f, err := os.Open(filename)
 	if err != nil {
-		return
+		return nil, err
 	}
 
-	out = make(chan *Base64Chunk, 8)
-	go func() {
+	out := make(chan *Chunk, 8)
+	chunker := func() {
 		b := make([]byte, CHUNK_BUFF_SIZE)
 		defer f.Close()
 		defer close(out)
 		ok := false
 		for position := int64(0); !ok; position += 1 {
-			bf := &Base64Chunk{
+			bf := &Chunk{
 				Position: position,
 			}
-			b64 := base64.NewEncoder(base64.StdEncoding, &bf.Buffer)
+			b64 := b64.NewEncoder(b64.StdEncoding, &bf.Buffer)
 			for i := int64(0); i < CHUNK_BUFF_COUNT; i++ {
 				n, _ := f.Read(b)
 				if n == 0 {
@@ -47,7 +47,9 @@ func Base64Chunker(filename string) (out chan *Base64Chunk, err error) {
 				out <- bf
 			}
 		}
-	}()
+	}
 
-	return
+	go chunker()
+
+	return out, nil
 }
diff --git a/internal/exif/extract.go b/internal/exif/extract.go
new file mode 100644
index 0000000..3b2acac
--- /dev/null
+++ b/internal/exif/extract.go
@@ -0,0 +1,56 @@
+package exif
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/barasher/go-exiftool"
+)
+
+type Info struct {
+	CreatedAt *time.Time
+}
+
+var (
+	CreateDateFormat = "2006:01:02 15:04:05-07:00"
+)
+
+func Extract(filename string) (*Info, error) {
+	et, err := exiftool.NewExiftool()
+	if err != nil {
+		return nil, err
+	}
+	defer et.Close()
+
+	var resp *Info = &Info{}
+	fileInfos := et.ExtractMetadata(filename)
+	for _, fileInfo := range fileInfos {
+		if fileInfo.Err != nil {
+			continue
+		}
+
+		var t time.Time
+		for k, v := range fileInfo.Fields {
+			switch k {
+			case "CreateDate":
+				offset, ok := fileInfo.Fields["OffsetTime"]
+				if !ok {
+					offset = "+00:00"
+				}
+				v := fmt.Sprintf("%s%s", v, offset)
+				t, err = time.Parse(CreateDateFormat, v)
+			case "CreationDate":
+				t, err = time.Parse(CreateDateFormat, fmt.Sprint(v))
+			default:
+				continue
+			}
+			if err != nil {
+				continue
+			}
+			if resp.CreatedAt == nil || resp.CreatedAt.After(t) {
+				resp.CreatedAt = &t
+			}
+		}
+	}
+	return resp, nil
+}
diff --git a/internal/piwigo/files.go b/internal/piwigo/files.go
index f5b4d61..15f5350 100644
--- a/internal/piwigo/files.go
+++ b/internal/piwigo/files.go
@@ -8,6 +8,8 @@ import (
 	"strings"
 	"sync"
 
+	"github.com/celogeek/piwigo-cli/internal/base64"
+	"github.com/celogeek/piwigo-cli/internal/exif"
 	"github.com/celogeek/piwigo-cli/internal/piwigo/piwigotools"
 	"golang.org/x/text/unicode/norm"
 )
@@ -57,7 +59,7 @@ func (p *Piwigo) Upload(file *piwigotools.FileToUpload, stat *piwigotools.FileTo
 		return
 	}
 	wg := &sync.WaitGroup{}
-	chunks, err := piwigotools.Base64Chunker(file.FullPath())
+	chunks, err := base64.Chunker(file.FullPath())
 	if err != nil {
 		stat.Error("Base64Chunker", file.FullPath(), err)
 		return
@@ -75,14 +77,15 @@ func (p *Piwigo) Upload(file *piwigotools.FileToUpload, stat *piwigotools.FileTo
 
 	// lock this process for committing the file
 
-	exif, _ := piwigotools.Exif(file.FullPath())
 	var resp *FileUploadResult
 	data := &url.Values{}
 	data.Set("original_sum", file.MD5())
 	data.Set("original_filename", file.Name)
 	data.Set("check_uniqueness", "true")
-	if exif != nil && exif.CreatedAt != nil {
-		data.Set("date_creation", exif.CreatedAt.String())
+
+	info, _ := exif.Extract(file.FullPath())
+	if info != nil && info.CreatedAt != nil {
+		data.Set("date_creation", piwigotools.TimeResult(*info.CreatedAt).String())
 	}
 	if file.CategoryId > 0 {
 		data.Set("categories", fmt.Sprint(file.CategoryId))
@@ -114,7 +117,7 @@ func (p *Piwigo) Upload(file *piwigotools.FileToUpload, stat *piwigotools.FileTo
 	stat.Done()
 }
 
-func (p *Piwigo) UploadChunk(file *piwigotools.FileToUpload, chunks chan *piwigotools.Base64Chunk, wg *sync.WaitGroup, stat *piwigotools.FileToUploadStat, ok *bool) {
+func (p *Piwigo) UploadChunk(file *piwigotools.FileToUpload, chunks chan *base64.Chunk, wg *sync.WaitGroup, stat *piwigotools.FileToUploadStat, ok *bool) {
 	defer wg.Done()
 	for chunk := range chunks {
 		var err error
diff --git a/internal/piwigo/piwigotools/exif.go b/internal/piwigo/piwigotools/exif.go
deleted file mode 100644
index 472c025..0000000
--- a/internal/piwigo/piwigotools/exif.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package piwigotools
-
-import (
-	"fmt"
-	"time"
-
-	"github.com/barasher/go-exiftool"
-)
-
-type ExifResult struct {
-	CreatedAt *TimeResult
-}
-
-func Exif(filename string) (*ExifResult, error) {
-	et, err := exiftool.NewExiftool()
-	if err != nil {
-		return nil, err
-	}
-	defer et.Close()
-
-	resp := &ExifResult{}
-	fileInfos := et.ExtractMetadata(filename)
-	for _, fileInfo := range fileInfos {
-		if fileInfo.Err != nil {
-			fmt.Printf("Error concerning %v: %v\n", fileInfo.File, fileInfo.Err)
-			continue
-		}
-
-		for k, v := range fileInfo.Fields {
-			switch k {
-			case "CreateDate", "CreationDate":
-				switch v := v.(type) {
-				case string:
-					t, err := time.Parse("2006:01:02 15:04:05-07:00", v)
-					if err == nil {
-						if resp.CreatedAt == nil || time.Time(*resp.CreatedAt).After(t) {
-							r := TimeResult(t)
-							resp.CreatedAt = &r
-						}
-					}
-				}
-			}
-		}
-	}
-	return resp, nil
-}