Skip to content

Commit

Permalink
Implement date processes
Browse files Browse the repository at this point in the history
  • Loading branch information
m-mohr committed May 17, 2024
1 parent 7c2d804 commit 60f7c75
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/processes/date_between.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import GeeProcess from '../processgraph/process.js';

export default class date_shift extends GeeProcess {

executeSync(node) {
const date = node.getArgumentAsDateEE('date');
const value = node.getArgumentAsNumberEE('value');
const unit = node.getArgumentAsStringEE('unit');
return date.advance(value, unit);
}

}
94 changes: 94 additions & 0 deletions src/processes/date_between.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"id": "date_between",
"summary": "Between comparison for dates and times",
"description": "By default, this process checks whether `x` is later than or equal to `min` and before or equal to `max`.\n\nIf `exclude_max` is set to `true` the upper bound is excluded so that the process checks whether `x` is later than or equal to `min` and before `max`.\n\nLower and upper bounds are not allowed to be swapped. So `min` MUST be before or equal to `max` or otherwise the process always returns `false`.",
"categories": [
"comparison",
"date & time"
],
"experimental": true,
"parameters": [
{
"name": "x",
"description": "The value to check.",
"schema": [
{
"type": "string",
"format": "date-time",
"subtype": "date-time",
"description": "Date and time with a time zone."
},
{
"type": "string",
"format": "date",
"subtype": "date",
"description": "Date only, formatted as `YYYY-MM-DD`. The time zone is UTC. Missing time components are all 0."
}
]
},
{
"name": "min",
"description": "Lower boundary (inclusive) to check against.",
"schema": [
{
"type": "string",
"format": "date-time",
"subtype": "date-time",
"description": "Date and time with a time zone."
},
{
"type": "string",
"format": "date",
"subtype": "date",
"description": "Date only, formatted as `YYYY-MM-DD`. The time zone is UTC. Missing time components are all 0."
}
]
},
{
"name": "max",
"description": "Upper boundary (inclusive) to check against.",
"schema": [
{
"type": "string",
"format": "date-time",
"subtype": "date-time",
"description": "Date and time with a time zone."
},
{
"type": "string",
"format": "date",
"subtype": "date",
"description": "Date only, formatted as `YYYY-MM-DD`. The time zone is UTC. Missing time components are all 0."
}
]
},
{
"name": "exclude_max",
"description": "Exclude the upper boundary `max` if set to `true`. Defaults to `false`.",
"schema": {
"type": "boolean"
},
"default": false,
"optional": true
}
],
"returns": {
"description": "`true` if `x` is between the specified bounds, otherwise `false`.",
"schema": {
"type": [
"boolean",
"null"
]
}
},
"examples": [
{
"arguments": {
"x": "2020-01-01",
"min": "2021-01-01",
"max": "2022-01-01"
},
"returns": false
}
]
}
17 changes: 17 additions & 0 deletions src/processes/date_difference.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import GeeProcess from '../processgraph/process.js';
import If from './if.js';

export default class date_shift extends GeeProcess {

executeSync(node) {
// Convert to numerical timestamps in milliseconds
const x = node.getArgumentAsDateEE('x').millis();
const min = node.getArgumentAsDateEE('min').millis();
const max = node.getArgumentAsDateEE('max').millis();
// Check if the max values are included or excluded
const exclude_max = node.getArgumentAsNumberEE('exclude_max', false);
const upper = If.process(node.ee, exclude_max, x.lt(max), x.lte(max));
return min.lte(x).and(upper);
}

}
98 changes: 98 additions & 0 deletions src/processes/date_difference.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"id": "date_difference",
"summary": "Computes the difference between two time instants",
"description": "Computes the difference between two instants in time and returns the difference between them in the unit given.\n\nThe process converts the given dates into numerical timestamps and returns the result of subtracting the other date from the base date. If a given date doesn't include the time, the process assumes that the time component is `00:00:00Z` (i.e. midnight, in UTC). The millisecond part of the times are optional and default to `0` if not given. The process doesn't take daylight saving time (DST) into account as only dates and times in UTC (with potential numerical time zone modifier) are supported.",
"categories": [
"comparison",
"date & time"
],
"experimental": true,
"parameters": [
{
"name": "date1",
"description": "The base date, optionally with a time component.",
"schema": [
{
"type": "string",
"format": "date-time",
"subtype": "date-time"
},
{
"type": "string",
"format": "date",
"subtype": "date"
}
]
},
{
"name": "date2",
"description": "The other date, optionally with a time component.",
"schema": [
{
"type": "string",
"format": "date-time",
"subtype": "date-time"
},
{
"type": "string",
"format": "date",
"subtype": "date"
}
]
},
{
"name": "unit",
"description": "The unit for the returned value. The following units are available:\n\n- second - leap seconds are ignored in computations.\n- minute\n- hour\n- day\n- month\n- year",
"optional": true,
"default": "second",
"schema": {
"type": "string",
"enum": [
"second",
"minute",
"hour",
"day",
"month",
"year"
]
}
}
],
"returns": {
"description": "Returns the difference between date1 and date2 in the given unit (seconds by default), including a fractional part if required.\n\nFor comparison purposes this means:\n\n- If `date1` < `date2`, the returned value is positive.\n- If `date1` = `date2`, the returned value is 0.\n- If `date1` > `date2`, the returned value is negative.",
"schema": {
"type": "number"
}
},
"examples": [
{
"arguments": {
"date1": "2020-01-01T00:00:00.0Z",
"date2": "2020-01-01T00:00:15.5Z"
},
"returns": 15.5
},
{
"arguments": {
"date1": "2020-01-01T00:00:00Z",
"date2": "2020-01-01T01:00:00+01:00"
},
"returns": 0
},
{
"arguments": {
"date1": "2020-01-02",
"date2": "2020-01-01"
},
"returns": -86400
},
{
"arguments": {
"date1": "2020-01-02",
"date2": "2020-01-01",
"unit": "day"
},
"returns": -1
}
]
}
12 changes: 12 additions & 0 deletions src/processes/date_shift.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import GeeProcess from '../processgraph/process.js';

export default class date_shift extends GeeProcess {

executeSync(node) {
const date = node.getArgumentAsDateEE('date');
const value = node.getArgumentAsNumberEE('value');
const unit = node.getArgumentStringEE('unit');
return date.advance(value, unit);
}

}
126 changes: 126 additions & 0 deletions src/processes/date_shift.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
{
"id": "date_shift",
"summary": "Manipulates dates and times by addition or subtraction",
"description": "Based on a given date (and optionally time), calculates a new date (and time if given) by adding or subtracting a given temporal period.\n\nSome specifics about dates and times need to be taken into account:\n\n* This process doesn't have any effect on the time zone.\n* It doesn't take daylight saving time (DST) into account as only dates and times in UTC (with potential numerical time zone modifier) are supported.\n* Leap years are implemented in a way that computations handle them gracefully (see parameter `unit` for details).\n* Leap seconds are mostly ignored in manipulations as they don't follow a regular pattern. Leap seconds can be passed to the process, but will never be returned.",
"categories": [
"date & time"
],
"experimental": true,
"parameters": [
{
"name": "date",
"description": "The date (and optionally time) to manipulate.\n\nIf the given date doesn't include the time, the process assumes that the time component is `00:00:00Z` (i.e. midnight, in UTC). The millisecond part of the time is optional and defaults to `0` if not given.",
"schema": [
{
"type": "string",
"format": "date-time",
"subtype": "date-time"
},
{
"type": "string",
"format": "date",
"subtype": "date"
}
]
},
{
"name": "value",
"description": "The period of time in the unit given that is added (positive numbers) or subtracted (negative numbers). The value `0` doesn't have any effect.",
"schema": {
"type": "integer"
}
},
{
"name": "unit",
"description": "The unit for the value given. The following pre-defined units are available:\n\n- second: Seconds - leap seconds are ignored in computations.\n- minute: Minutes\n- hour: Hours\n- day: Days - changes only the the day part of a date\n- week: Weeks (equivalent to 7 days)\n- month: Months\n- year: Years\n\nManipulations with the unit `year`, `month`, `week` or `day` do never change the time. If any of the manipulations result in an invalid date or time, the corresponding part is rounded down to the next valid date or time respectively. For example, adding a month to `2020-01-31` would result in `2020-02-29`.",
"schema": {
"type": "string",
"enum": [
"second",
"minute",
"hour",
"day",
"week",
"month",
"year"
]
}
}
],
"returns": {
"description": "The manipulated date. If a time component was given in the parameter `date`, the time component is returned with the date.",
"schema": [
{
"type": "string",
"format": "date-time",
"subtype": "date-time"
},
{
"type": "string",
"format": "date",
"subtype": "date"
}
]
},
"examples": [
{
"arguments": {
"date": "2020-02-01T17:22:45Z",
"value": 6,
"unit": "month"
},
"returns": "2020-08-01T17:22:45Z"
},
{
"arguments": {
"date": "2021-03-31T00:00:00+02:00",
"value": -7,
"unit": "day"
},
"returns": "2021-03-24T00:00:00+02:00"
},
{
"description": "Adding a year to February 29th in a leap year will result in February 28th in the next (non-leap) year.",
"arguments": {
"date": "2020-02-29T17:22:45Z",
"value": 1,
"unit": "year"
},
"returns": "2021-02-28T17:22:45Z"
},
{
"description": "Adding a month to January 31th will result in February 29th in leap years.",
"arguments": {
"date": "2020-01-31",
"value": 1,
"unit": "month"
},
"returns": "2020-02-29"
},
{
"description": "The process skips over the leap second `2016-12-31T23:59:60Z`.",
"arguments": {
"date": "2016-12-31T23:59:59Z",
"value": 1,
"unit": "second"
},
"returns": "2017-01-01T00:00:00Z"
},
{
"arguments": {
"date": "2018-01-01",
"value": 25,
"unit": "hour"
},
"returns": "2018-01-02"
},
{
"arguments": {
"date": "2018-01-01",
"value": -1,
"unit": "hour"
},
"returns": "2017-12-31"
}
]
}
8 changes: 8 additions & 0 deletions src/processgraph/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ export default class GeeProcessGraphNode extends ProcessGraphNode {
return result;
}

getArgumentAsDateEE(name) {
const data = this.getArgument(name, null);
if (data === null) {
throw this.invalidArgument(name, 'No value provided');
}
return this.ee.Date(data);
}

getArgumentAsNumberEE(name, defaultValue = undefined) {
const data = this.getArgument(name, defaultValue);
const result = GeeTypes.toNumber(this.ee, data);
Expand Down

0 comments on commit 60f7c75

Please sign in to comment.