changeset 4104:aececbc3d047 v4-preview20190726

Merged timezone branch back into default.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 26 Jul 2019 15:01:23 +0200
parents 7afe411eeb48 (current diff) ed66522a15a5 (diff)
children 6b70fdc09f9a 9f03eb3817d6
files
diffstat 11 files changed, 58 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/client/src/components/importoverview/ImportOverview.vue	Fri Jul 26 12:53:01 2019 +0200
+++ b/client/src/components/importoverview/ImportOverview.vue	Fri Jul 26 15:01:23 2019 +0200
@@ -343,8 +343,10 @@
       this.$store
         .dispatch("imports/getImports", {
           filter: this.filters,
-          from: format(this.startDate, "YYYY-MM-DDTHH:mm:ss.SSS"),
-          to: format(this.endDate, "YYYY-MM-DDTHH:mm:ss.SSS"),
+          from: encodeURIComponent(
+            format(this.startDate, "YYYY-MM-DDTHH:mm:ssZ")
+          ),
+          to: encodeURIComponent(format(this.endDate, "YYYY-MM-DDTHH:mm:ssZ")),
           query: this.searchQuery
         })
         .then(() => {
--- a/client/src/store/fairwayavailability.js	Fri Jul 26 12:53:01 2019 +0200
+++ b/client/src/store/fairwayavailability.js	Fri Jul 26 15:01:23 2019 +0200
@@ -18,7 +18,9 @@
 import {
   format,
   subYears,
+  startOfDay,
   startOfMonth,
+  endOfDay,
   endOfMonth,
   startOfYear,
   endOfYear,
@@ -238,11 +240,13 @@
         } else if (type == TYPES.SECTION || type == TYPES.STRETCH) {
           additionalParams = `&depthbreaks=${depthLimit1},${depthLimit2}&widthbreaks=${widthLimit1},${widthLimit2}`;
         }
-        const start = encodeURIComponent("00:00:00+00:00");
-        const end = encodeURIComponent("23:59:59+00:00");
         const URL = `data/${endpoint}/fairway-depth/${encodeURIComponent(
           name
-        )}?from=${from}T${start}&to=${to}T${end}&mode=${frequency}&los=${LOS}${additionalParams}`;
+        )}?from=${encodeURIComponent(
+          format(startOfDay(from), "YYYY-MM-DDTHH:mm:ssZ")
+        )}&to=${encodeURIComponent(
+          format(endOfDay(to), "YYYY-MM-DDTHH:mm:ssZ")
+        )}&mode=${frequency}&los=${LOS}${additionalParams}`;
         HTTP.get(URL, {
           headers: { "X-Gemma-Auth": localStorage.getItem("token") }
         })
@@ -278,8 +282,6 @@
           ? feature.properties.name
           : feature.get("objnam");
         [from, to] = getIntervallBorders(from, to, frequency);
-        const start = encodeURIComponent("00:00:00+00:00");
-        const end = encodeURIComponent("23:59:59+00:00");
         let additionalParams = "";
         let endpoint = type || TYPES.BOTTLENECK;
         if (type === TYPES.BOTTLENECK) {
@@ -292,7 +294,11 @@
         }
         const URL = `data/${endpoint}/availability/${encodeURIComponent(
           name
-        )}?from=${from}T${start}&to=${to}T${end}&mode=${frequency}&los=${LOS}${additionalParams}`;
+        )}?from=${encodeURIComponent(
+          format(startOfDay(from), "YYYY-MM-DDTHH:mm:ssZ")
+        )}&to=${encodeURIComponent(
+          format(endOfDay(to), "YYYY-MM-DDTHH:mm:ssZ")
+        )}&mode=${frequency}&los=${LOS}${additionalParams}`;
         HTTP.get(URL, {
           headers: { "X-Gemma-Auth": localStorage.getItem("token") }
         })
--- a/client/src/store/gauges.js	Fri Jul 26 12:53:01 2019 +0200
+++ b/client/src/store/gauges.js	Fri Jul 26 15:01:23 2019 +0200
@@ -138,10 +138,13 @@
     loadWaterlevels({ state, commit }) {
       return new Promise((resolve, reject) => {
         HTTP.get(
-          `/data/waterlevels/${state.selectedGaugeISRS}?from=${format(
-            startOfDay(state.dateFrom),
-            "YYYY-MM-DDTHH:mm:ss.SSS"
-          )}&to=${format(endOfDay(state.dateTo), "YYYY-MM-DDTHH:mm:ss.SSS")}`,
+          `/data/waterlevels/${
+            state.selectedGaugeISRS
+          }?from=${encodeURIComponent(
+            format(startOfDay(state.dateFrom), "YYYY-MM-DDTHH:mm:ssZ")
+          )}&to=${encodeURIComponent(
+            format(endOfDay(state.dateTo), "YYYY-MM-DDTHH:mm:ssZ")
+          )}`,
           {
             headers: { "X-Gemma-Auth": localStorage.getItem("token") }
           }
--- a/pkg/common/time.go	Fri Jul 26 12:53:01 2019 +0200
+++ b/pkg/common/time.go	Fri Jul 26 15:01:23 2019 +0200
@@ -23,13 +23,22 @@
 	// time.RFC3339 equals "simplified ISO format as defined by ECMA-262"
 	//   https://tc39.github.io/ecma262/#sec-date-time-string-format
 	// and "SHOULD be used in new protocols on the Internet." (RFC section 5.6)
-	TimeFormat = time.RFC3339
-	DateFormat = "2006-01-02"
+	TimeFormat           = time.RFC3339
+	TimeFormatMicro      = "2006-01-02T15:04:05.999Z07:00"
+	TimeFormatMicroLocal = "2006-01-02T15:04:05.000"
+	DateFormat           = "2006-01-02"
 )
 
 // TimeParser is a list of time formats.
 type TimeParser []string
 
+var ParseTime = TimeParser{
+	TimeFormat,
+	TimeFormatMicro,
+	TimeFormatMicroLocal,
+	DateFormat,
+}.Parse
+
 var utc0 = time.Unix(0, 0)
 
 // Parse tries to parse a given string by the entries of the layout
--- a/pkg/controllers/gauges.go	Fri Jul 26 12:53:01 2019 +0200
+++ b/pkg/controllers/gauges.go	Fri Jul 26 15:01:23 2019 +0200
@@ -588,7 +588,7 @@
 
 	var when time.Time
 	if w := req.FormValue("when"); w != "" {
-		if when, err = time.Parse(models.ImportTimeFormat, w); err != nil {
+		if when, err = common.ParseTime(w); err != nil {
 			err = JSONError{
 				Code:    http.StatusBadRequest,
 				Message: fmt.Sprintf("error: wrong time format: %v", err),
@@ -702,7 +702,7 @@
 	}
 
 	if from := req.FormValue("from"); from != "" {
-		fromTime, err := time.Parse(models.ImportTimeFormat, from)
+		fromTime, err := common.ParseTime(from)
 		if err != nil {
 			http.Error(
 				rw, fmt.Sprintf("error: Invalid from time: %v", err),
@@ -713,7 +713,7 @@
 	}
 
 	if to := req.FormValue("to"); to != "" {
-		toTime, err := time.Parse(models.ImportTimeFormat, to)
+		toTime, err := common.ParseTime(to)
 		if err != nil {
 			http.Error(
 				rw, fmt.Sprintf("error: Invalid from time: %v", err),
@@ -779,7 +779,7 @@
 			// Too late for an HTTP error code.
 			return
 		}
-		record[0] = measureDate.Format(models.ImportTimeFormat)
+		record[0] = measureDate.Format(common.TimeFormat)
 		record[1] = float64format(waterlevel)
 		record[2] = nullFloat64format(valueMin)
 		record[3] = nullFloat64format(valueMax)
--- a/pkg/controllers/importqueue.go	Fri Jul 26 12:53:01 2019 +0200
+++ b/pkg/controllers/importqueue.go	Fri Jul 26 15:01:23 2019 +0200
@@ -27,6 +27,7 @@
 	"github.com/gorilla/mux"
 
 	"gemma.intevation.de/gemma/pkg/auth"
+	"gemma.intevation.de/gemma/pkg/common"
 	"gemma.intevation.de/gemma/pkg/imports"
 	"gemma.intevation.de/gemma/pkg/models"
 )
@@ -136,7 +137,7 @@
 	}
 
 	if from := req.FormValue("from"); from != "" {
-		fromTime, err := time.Parse(models.ImportTimeFormat, from)
+		fromTime, err := common.ParseTime(from)
 		if err != nil {
 			return nil, nil, nil, err
 		}
@@ -147,7 +148,7 @@
 	}
 
 	if to := req.FormValue("to"); to != "" {
-		toTime, err := time.Parse(models.ImportTimeFormat, to)
+		toTime, err := common.ParseTime(to)
 		if err != nil {
 			return nil, nil, nil, err
 		}
@@ -224,7 +225,7 @@
 		log.Printf("warn: %v\n", err)
 		return nil
 	}
-	return &models.ImportTime{Time: when}
+	return &models.ImportTime{Time: when.UTC()}
 }
 
 func listImports(
@@ -287,7 +288,7 @@
 		if signer.Valid {
 			it.Signer = signer.String
 		}
-		it.Enqueued = models.ImportTime{Time: enqueued}
+		it.Enqueued = models.ImportTime{Time: enqueued.UTC()}
 		imports = append(imports, &it)
 	}
 
@@ -346,6 +347,7 @@
 	case err != nil:
 		return
 	}
+	enqueued = enqueued.UTC()
 
 	var sum interface{}
 	if summary.Valid {
@@ -367,9 +369,11 @@
 
 	for rows.Next() {
 		var entry models.ImportLogEntry
-		if err = rows.Scan(&entry.Time, &entry.Kind, &entry.Message); err != nil {
+		var t time.Time
+		if err = rows.Scan(&t, &entry.Kind, &entry.Message); err != nil {
 			return
 		}
+		entry.Time = models.ImportTime{t.UTC()}
 		entries = append(entries, &entry)
 	}
 
--- a/pkg/imports/queue.go	Fri Jul 26 12:53:01 2019 +0200
+++ b/pkg/imports/queue.go	Fri Jul 26 15:01:23 2019 +0200
@@ -362,6 +362,7 @@
 	if due.IsZero() {
 		due = time.Now()
 	}
+	due = due.UTC()
 
 	var tl sql.NullInt64
 	if trysLeft != nil {
--- a/pkg/models/import.go	Fri Jul 26 12:53:01 2019 +0200
+++ b/pkg/models/import.go	Fri Jul 26 15:01:23 2019 +0200
@@ -17,10 +17,10 @@
 	"encoding/json"
 	"errors"
 	"time"
+
+	"gemma.intevation.de/gemma/pkg/common"
 )
 
-const ImportTimeFormat = "2006-01-02T15:04:05.000"
-
 type (
 	ImportTime struct{ time.Time }
 
@@ -64,7 +64,7 @@
 }
 
 func (it ImportTime) MarshalJSON() ([]byte, error) {
-	return json.Marshal(it.Format(ImportTimeFormat))
+	return json.Marshal(it.Format(common.TimeFormatMicro))
 }
 
 func (it *ImportTime) Scan(x interface{}) error {
--- a/schema/gemma.sql	Fri Jul 26 12:53:01 2019 +0200
+++ b/schema/gemma.sql	Fri Jul 26 15:01:23 2019 +0200
@@ -826,8 +826,8 @@
         id         int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
         state      import_state NOT NULL DEFAULT 'queued',
         kind       varchar   NOT NULL,
-        enqueued   timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
-        due        timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+        enqueued   timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
+        due        timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
         retry_wait interval
             CHECK(retry_wait IS NULL
                 OR retry_wait >= interval '0 microseconds'),
@@ -850,7 +850,7 @@
     CREATE TABLE import_logs (
         import_id int NOT NULL REFERENCES imports(id)
             ON DELETE CASCADE,
-        time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+        time timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
         kind log_type NOT NULL DEFAULT 'info',
         msg TEXT NOT NULL
     )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/schema/updates/1010/01.timezones-imports.sql	Fri Jul 26 15:01:23 2019 +0200
@@ -0,0 +1,3 @@
+ALTER TABLE import.imports     ALTER COLUMN enqueued TYPE timestamp with time zone;
+ALTER TABLE import.imports     ALTER COLUMN due      TYPE timestamp with time zone;
+ALTER TABLE import.import_logs ALTER COLUMN time     TYPE timestamp with time zone;
--- a/schema/version.sql	Fri Jul 26 12:53:01 2019 +0200
+++ b/schema/version.sql	Fri Jul 26 15:01:23 2019 +0200
@@ -1,1 +1,1 @@
-INSERT INTO gemma_schema_version(version) VALUES (1009);
+INSERT INTO gemma_schema_version(version) VALUES (1010);