You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by GitBox <gi...@apache.org> on 2018/08/31 15:01:07 UTC

[GitHub] kristw commented on a change in pull request #5785: Handle "ambiguous durations"

kristw commented on a change in pull request #5785: Handle "ambiguous durations"
URL: https://github.com/apache/incubator-superset/pull/5785#discussion_r214381190
 
 

 ##########
 File path: superset/assets/src/modules/time.js
 ##########
 @@ -1,38 +1,155 @@
 import parseIsoDuration from 'parse-iso-duration';
 
 
+export class IsoDuration {
+  /*
+   * Class that handles ambiguous durations like `P1M` or `P1Y`.
+   */
+
+  constructor(isoDuration) {
+    this.isoDuration = isoDuration;
+
+    // special cases not handled by parse-iso-duration
+    this.pattern = /P(\d+)(M|Y)/;
+
+    this.addTo = this.addTo.bind(this);
+    this.subtractFrom = this.subtractFrom.bind(this);
+    this.operateOn = this.operateOn.bind(this);
+    this.truncate = this.truncate.bind(this);
+    this.explode = this.explode.bind(this);
+  }
+
+  addTo(timestamp) {
+    const op = (a, b) => a + b;
+    return this.operateOn(op, timestamp);
+  }
+
+  subtractFrom(timestamp) {
+    const op = (a, b) => a - b;
+    return this.operateOn(op, timestamp);
+  }
+
+  operateOn(op, timestamp) {
+    try {
+      return op(timestamp, parseIsoDuration(this.isoDuration));
+    } catch (error) {
+      const match = this.pattern.exec(this.isoDuration);
+      if (match === null) {
+        throw error;
+      }
+      const n = parseInt(match[1], 10);  // how many months or years
+
+      const date = new Date(timestamp);
+      let year = date.getFullYear();
+      let month = date.getMonth();
+
+      if (match[2] === 'M') {
+        year = op(year, Math.floor(n / 12));
+        month = op(month, (n % 12));
+        if (month < 0 || month > 11) {
+          month = op(month, -12);
+          year = op(year, 1);
+        }
+      } else if (match[2] === 'Y') {
+        year = op(year, n);
+      } else {
+        throw error;  // should never happen
+      }
+      date.setFullYear(year);
+      date.setMonth(month);
+      return date.getTime();
+    }
+  }
+
+  explode(timestamp) {
+    // Return year, month, day, hour, minute, second, millisecond
+    const date = new Date(timestamp);
+    return [
+      date.getFullYear(),
+      date.getMonth() + 1,  // fuck Javascript
+      date.getDate(),
+      date.getHours(),
+      date.getMinutes(),
+      date.getSeconds(),
+      date.getMilliseconds(),
+    ];
+  }
+
+  truncate(timestamp) {
+    /*
+     * Truncate timestamp down to duration resolution.
+     *
+     *  > const duration = new IsoDuration('PT2H');  // 2 hours
+     *  > const date = new Date('2018-01-01 23:37:00').getTime();
+     *  > new Date(duration.truncate(date));
+     *  Mon Jan 01 2018 22:00:00 GMT
+     */
+    const lowerBound = this.subtractFrom(timestamp);
+    const explodedTimestamp = this.explode(timestamp);
+    const explodedLowerBound = this.explode(lowerBound);
+    let foundDifference = false;
+    const args = [];
+    const first = [1, 1, 1, 0, 0, 0, 0];
+    for (let i = 0; i < explodedTimestamp.length; i++) {
 
 Review comment:
   Avoid naming the variable `args` as it is usually used for the entire function `arguments`.
   
   Can also simplify the code
   
   ```
   const dateParts = explodedTimestamp.map((part, i) => 
     (explodedLowerBound[i] !== part) ? first[i] : part
   );
   return Date.UTC(...dateParts)
   ```

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org