diff --git a/base/dsfs/compute_fields.go b/base/dsfs/compute_fields.go index aa3e205c3..46945ef42 100644 --- a/base/dsfs/compute_fields.go +++ b/base/dsfs/compute_fields.go @@ -168,8 +168,12 @@ func (cff *computeFieldsFile) handleRows(ctx context.Context) { } cff.Lock() - // assign timestamp early. saving process on large files can take many minutes - cff.ds.Commit.Timestamp = Timestamp() + if cff.ds.Commit.Timestamp.IsZero() { + // assign timestamp early. saving process on large files can take many minutes + cff.ds.Commit.Timestamp = Timestamp() + } else { + cff.ds.Commit.Timestamp = cff.ds.Commit.Timestamp.In(time.UTC) + } cff.acc = dsstats.NewAccumulator(st) cff.Unlock() diff --git a/base/dsfs/dataset.go b/base/dsfs/dataset.go index d6f07dca0..4b388932f 100644 --- a/base/dsfs/dataset.go +++ b/base/dsfs/dataset.go @@ -111,6 +111,8 @@ func DerefDataset(ctx context.Context, store qfs.Filesystem, ds *dataset.Dataset // SaveSwitches represents options for saving a dataset type SaveSwitches struct { + // Use a custom timestamp, defaults to time.Now if unset + Time time.Time // Replace is whether the save is a full replacement or a set of patches to previous Replace bool // Pin is whether the dataset should be pinned diff --git a/base/dsfs/dataset_test.go b/base/dsfs/dataset_test.go index 4226f2749..19c073a2f 100644 --- a/base/dsfs/dataset_test.go +++ b/base/dsfs/dataset_test.go @@ -112,7 +112,6 @@ func TestLoadDataset(t *testing.T) { continue } } - } func TestCreateDataset(t *testing.T) { @@ -297,6 +296,34 @@ func TestCreateDataset(t *testing.T) { // case: previous dataset isn't valid } +func TestDatasetSaveCustomTimestamp(t *testing.T) { + ctx := context.Background() + fs := qfs.NewMemFS() + privKey := testPeers.GetTestPeerInfo(10).PrivKey + + // use a custom timestamp in local zone. should be converted to UTC for saving + ts := time.Date(2100, 1, 2, 3, 4, 5, 6, time.Local) + + ds := &dataset.Dataset{ + Commit: &dataset.Commit{ + Timestamp: ts, + }, + Structure: &dataset.Structure{Format: "json", Schema: dataset.BaseSchemaArray}, + } + ds.SetBodyFile(qfs.NewMemfileBytes("/body.json", []byte(`[]`))) + + path, err := CreateDataset(ctx, fs, fs, ds, nil, privKey, SaveSwitches{}) + if err != nil { + t.Fatal(err) + } + + got, err := LoadDataset(ctx, fs, path) + + if !ts.In(time.UTC).Equal(got.Commit.Timestamp) { + t.Errorf("result timestamp mismatch.\nwant: %q\ngot: %q", ts.In(time.UTC), got.Commit.Timestamp) + } +} + // BaseTabularSchema is the base schema for tabular data // NOTE: Do not use if possible, prefer github.com/qri-io/dataset/tabular // TODO(dustmop): Possibly move this to tabular package diff --git a/cmd/testdata/movies/dataset.json b/cmd/testdata/movies/dataset.json index 4c663e4f8..e35d75a52 100644 --- a/cmd/testdata/movies/dataset.json +++ b/cmd/testdata/movies/dataset.json @@ -6,7 +6,6 @@ }, "commit": { "qri": "cm:0", - "timestamp": "2017-03-01T01:00:00.000Z", "title": "removing rows", "message": "removing rows for test purposes" }, diff --git a/repo/test/testdata/cities/input.dataset.json b/repo/test/testdata/cities/input.dataset.json index 42a8ecf42..b23a93bd9 100644 --- a/repo/test/testdata/cities/input.dataset.json +++ b/repo/test/testdata/cities/input.dataset.json @@ -2,7 +2,6 @@ "qri": "ds:0", "commit": { "qri": "cm:0", - "timestamp": "2017-01-01T01:00:00.000Z", "title": "initial commit" }, "meta": { diff --git a/repo/test/testdata/counter/input.dataset.json b/repo/test/testdata/counter/input.dataset.json index a352c68fd..95de81181 100644 --- a/repo/test/testdata/counter/input.dataset.json +++ b/repo/test/testdata/counter/input.dataset.json @@ -2,7 +2,6 @@ "qri": "ds:0", "commit": { "qri": "cm:0", - "timestamp": "2017-02-01T01:00:00.000Z", "title": "initial commit" }, "meta": { diff --git a/repo/test/testdata/craigslist/input.dataset.json b/repo/test/testdata/craigslist/input.dataset.json index f97cc322a..2784abb06 100755 --- a/repo/test/testdata/craigslist/input.dataset.json +++ b/repo/test/testdata/craigslist/input.dataset.json @@ -2,8 +2,7 @@ "qri": "ds:0", "commit" : { "qri" : "cm:0", - "title" : "initial commit", - "timestamp": "2017-04-01T01:00:00.000Z" + "title" : "initial commit" }, "structure": { "checksum": "QmPT7t4GQaBN4uxCdv3PD8A5vWaJ1ELCKCaZEjYYvUhe4W", diff --git a/repo/test/testdata/flourinated_compounds_in_fast_food_packaging/input.dataset.json b/repo/test/testdata/flourinated_compounds_in_fast_food_packaging/input.dataset.json index aa43f516d..b85487674 100644 --- a/repo/test/testdata/flourinated_compounds_in_fast_food_packaging/input.dataset.json +++ b/repo/test/testdata/flourinated_compounds_in_fast_food_packaging/input.dataset.json @@ -1,8 +1,7 @@ { "commit" : { "qri" : "cm:0", - "title" : "initial commit", - "timestamp": "2017-05-01T01:00:00.000Z" + "title" : "initial commit" }, "meta" : { "title" : "Fluorinated Compounds in U.S. Fast Food Packaging", diff --git a/repo/test/testdata/movies/input.dataset.json b/repo/test/testdata/movies/input.dataset.json index e4619f9cd..139a7a5fc 100644 --- a/repo/test/testdata/movies/input.dataset.json +++ b/repo/test/testdata/movies/input.dataset.json @@ -6,7 +6,6 @@ }, "commit": { "qri": "cm:0", - "timestamp": "2017-03-01T01:00:00.000Z", "title": "initial commit" }, "structure": { diff --git a/repo/test/testdata/sitemap/input.dataset.json b/repo/test/testdata/sitemap/input.dataset.json index 54ada4f38..438321eaa 100644 --- a/repo/test/testdata/sitemap/input.dataset.json +++ b/repo/test/testdata/sitemap/input.dataset.json @@ -7,7 +7,6 @@ }, "commit": { "qri": "cm:0", - "timestamp": "2017-06-01T01:00:00.000Z", "title": "initial commit" }, "structure": {