kristw commented on a change in pull request #5785: Handle "ambiguous durations"
URL:
https://github.com/apache/incubator-superset/pull/5785#discussion_r214379954
##########
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];
Review comment:
If this is a constant, please declare outside the class. Perhaps choose a
bit more descriptive name or add comment what `first` means?
----------------------------------------------------------------
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:
[email protected]
With regards,
Apache Git Services
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]