-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* update openeo-processes * bump 2023.9.1 * bump 2023.9.0 * add datetime processes * pre-commit hook
- Loading branch information
1 parent
1c52aa9
commit ac070ca
Showing
2 changed files
with
176 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
from typing import Optional | ||
|
||
import numpy as np | ||
|
||
__all__ = [ | ||
"date_between", | ||
"date_difference", | ||
"date_shift", | ||
] | ||
|
||
|
||
def datetime_from_str(date: str): | ||
daytime = np.datetime64(date) | ||
return daytime | ||
|
||
|
||
def date_between( | ||
x: str, min: str, max: str, exclude_max: bool = False | ||
) -> Optional[bool]: | ||
x = datetime_from_str(x) | ||
min = datetime_from_str(min) | ||
max = datetime_from_str(max) | ||
if exclude_max: | ||
return bool((x >= min) and (x < max)) | ||
else: | ||
return bool((x >= min) and (x <= max)) | ||
|
||
|
||
def date_difference(date1: str, date2: str, unit: Optional[str] = "second") -> float: | ||
date1 = datetime_from_str(date1) | ||
date2 = datetime_from_str(date2) | ||
units = { | ||
"millisecond": 1, | ||
"second": 1000, | ||
"minute": 1000 * 60, | ||
"hour": 1000 * 60 * 60, | ||
"day": 1000 * 60 * 60 * 24, | ||
"week": 1000 * 60 * 60 * 24 * 7, | ||
"month": "M", | ||
"year": "Y", | ||
} | ||
if unit in units: | ||
unit = units[unit] | ||
if unit in ["M", "Y"]: | ||
return float( | ||
( | ||
date2.astype(f"datetime64[{unit}]") | ||
- date1.astype(f"datetime64[{unit}]") | ||
).astype(float) | ||
) | ||
else: | ||
# we do this, so the examples are fulfilled: | ||
# date_difference(date1 = "2020-01-01T00:00:00.0Z", date2 = "2020-01-01T00:00:15.5Z") -> 15.5 | ||
return ( | ||
float( | ||
( | ||
date2.astype(f"datetime64[ms]") - date1.astype(f"datetime64[ms]") | ||
).astype(float) | ||
) | ||
/ unit | ||
) | ||
|
||
|
||
def date_shift(date: str, value: int, unit: str) -> str: | ||
if date.endswith("Z"): | ||
end = "Z" | ||
elif "+" in date: | ||
end = "+" + date.split("+")[-1] | ||
date = date.split("+")[0] | ||
else: | ||
end = "" | ||
units = { | ||
"millisecond": "ms", | ||
"second": "s", | ||
"minute": "m", | ||
"hour": "h", | ||
"day": "D", | ||
"week": "W", | ||
"month": "M", | ||
"year": "Y", | ||
} | ||
if unit in units: | ||
unit = units[unit] | ||
if unit in ["M", "Y"]: | ||
if len(date) > 7: | ||
date_M = np.datetime64(date, "M") | ||
day = ( | ||
int( | ||
(np.datetime64(date, "D") - date_M.astype("datetime64[D]")).astype( | ||
int | ||
) | ||
) | ||
+ 1 | ||
) | ||
if " " in date: | ||
time = "T" + date.split(" ")[-1] | ||
elif "T" in date: | ||
time = "T" + date.split("T")[-1] | ||
else: | ||
time = "" | ||
new_date = str(date_M + np.timedelta64(value, unit)) | ||
if day in [29, 30, 31]: | ||
for i in range(3): | ||
try: | ||
new_daytime = f"{new_date}-{day-i}" | ||
new_daytime_numpy = np.datetime64(new_daytime) | ||
result = f"{new_daytime}{time}" | ||
return result | ||
except: | ||
pass | ||
elif int(day) < 10: | ||
new_daytime = f"{new_date}-0{day}{time}" | ||
else: | ||
new_daytime = f"{new_date}-{day}T{time}" | ||
new_daytime_numpy = np.datetime64(new_daytime) | ||
return new_daytime | ||
|
||
date = datetime_from_str(date) | ||
return str(date_M + np.timedelta64(value, unit)) | ||
|
||
date = datetime_from_str(date) | ||
if unit in ["ms"]: | ||
result = str((date + np.timedelta64(value, unit)).astype(f"datetime64[{unit}]")) | ||
else: | ||
result = str((date + np.timedelta64(value, unit)).astype(date.dtype)) | ||
return result + end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
from openeo_processes_dask.process_implementations.dates import ( | ||
date_between, | ||
date_difference, | ||
date_shift, | ||
) | ||
|
||
|
||
def test_date_between(): | ||
assert not date_between(x="2020-01-01", min="2021-01-01", max="2022-01-01") | ||
|
||
|
||
def test_date_difference(): | ||
assert ( | ||
date_difference(date1="2020-01-01T00:00:00.0Z", date2="2020-01-01T00:00:15.5Z") | ||
== 15.5 | ||
) | ||
assert ( | ||
date_difference(date1="2020-01-01T00:00:00Z", date2="2020-01-01T01:00:00+01:00") | ||
== 0 | ||
) | ||
assert date_difference(date1="2020-01-02", date2="2020-01-01") == -86400 | ||
assert date_difference(date1="2020-01-02", date2="2020-01-01", unit="day") == -1 | ||
|
||
|
||
def test_date_shift(): | ||
month_shift = date_shift(date="2020-02-01T17:22:45Z", value=6, unit="month") | ||
assert month_shift == "2020-08-01T17:22:45Z" | ||
|
||
day_shift = date_shift(date="2021-03-31T00:00:00+02:00", value=-7, unit="day") | ||
assert day_shift == "2021-03-24T00:00:00+02:00" | ||
|
||
year_shift = date_shift(date="2020-02-29T17:22:45Z", value=1, unit="year") | ||
assert year_shift == "2021-02-28T17:22:45Z" | ||
|
||
month_shift = date_shift(date="2020-01-31", value=1, unit="month") | ||
assert month_shift == "2020-02-29" | ||
|
||
second_shift = date_shift(date="2016-12-31T23:59:59Z", value=1, unit="second") | ||
assert second_shift == "2017-01-01T00:00:00Z" | ||
|
||
millisecond_shift = date_shift( | ||
date="2018-12-31T17:22:45Z", value=1150, unit="millisecond" | ||
) | ||
assert millisecond_shift == "2018-12-31T17:22:46.150Z" | ||
|
||
hour_shift = date_shift(date="2018-01-01", value=25, unit="hour") | ||
assert hour_shift == "2018-01-02" | ||
|
||
hour_shift = date_shift(date="2018-01-01", value=-1, unit="hour") | ||
assert hour_shift == "2017-12-31" |