-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented date.parse and date.format procedures
Also added e2e tests for them.
- Loading branch information
Showing
14 changed files
with
172 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
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,6 @@ | ||
query: > | ||
CALL date.format(74976, "h", "%Y/%m/%d %H:%M:%S %Z", "Mexico/BajaNorte") YIELD formatted | ||
RETURN formatted | ||
output: | ||
- formatted: "1978/07/21 17:00:00 PDT" |
Empty file.
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,6 @@ | ||
query: > | ||
CALL date.format(74976002900, "ms", "%Y/%m/%d %H:%M:%S %Z", "Australia/Broken_Hill") YIELD formatted | ||
RETURN formatted | ||
output: | ||
- formatted: "1972/05/18 04:10:02 ACST" |
Empty file.
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,6 @@ | ||
query: > | ||
CALL date.format(7491, "d", "%Y/%m/%d %H:%M:%S %z", "Brazil/DeNoronha") YIELD formatted | ||
RETURN formatted | ||
output: | ||
- formatted: "1990/07/05 22:00:00 -0200" |
Empty file.
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,6 @@ | ||
query: > | ||
CALL date.parse("2023/08/03 14:30:00", "h", "%Y/%m/%d %H:%M:%S", "Europe/Zagreb") YIELD parsed | ||
RETURN parsed | ||
output: | ||
- parsed: 469740 |
Empty file.
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,6 @@ | ||
query: > | ||
CALL date.parse("21 June, 2018", "d", "%d %B, %Y", "US/Samoa") YIELD parsed | ||
RETURN parsed | ||
output: | ||
- parsed: 17703 |
Empty file.
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,6 @@ | ||
query: > | ||
CALL date.parse("14-Feb-1985 01:02:03", "s", "%d-%b-%Y %H:%M:%S", "Pacific/Chatham") YIELD parsed | ||
RETURN parsed | ||
output: | ||
- parsed: 477141423 |
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,124 @@ | ||
import mgp | ||
import pytz | ||
import datetime | ||
|
||
from mage.date.constants import Conversion, Epoch | ||
|
||
|
||
def getOffset(timezone, date): | ||
offset = pytz.timezone(timezone).utcoffset(date) | ||
if offset.days == 1: | ||
return ( | ||
datetime.timedelta( | ||
minutes=offset.seconds // Conversion.SECONDS_IN_MINUTE | ||
+ Conversion.HOURS_IN_DAY * Conversion.MINUTES_IN_HOUR | ||
), | ||
False, | ||
) | ||
elif offset.days == -1: | ||
return ( | ||
datetime.timedelta( | ||
minutes=Conversion.HOURS_IN_DAY * Conversion.MINUTES_IN_HOUR | ||
- offset.seconds // Conversion.SECONDS_IN_MINUTE | ||
), | ||
True, | ||
) | ||
return ( | ||
datetime.timedelta(minutes=offset.seconds // Conversion.SECONDS_IN_MINUTE), | ||
False, | ||
) | ||
|
||
|
||
@mgp.read_proc | ||
def parse( | ||
time: str, | ||
unit: str = "ms", | ||
format: str = "%Y-%m-%d %H:%M:%S", | ||
timezone: str = "UTC", | ||
) -> mgp.Record(parsed=int): | ||
first_date = Epoch.UNIX_EPOCH | ||
input_date = datetime.datetime.strptime(time, format) | ||
|
||
if timezone not in pytz.all_timezones: | ||
raise Exception( | ||
"Timezone doesn't exist. Check documentation to see available timezones." | ||
) | ||
|
||
offset, add = getOffset(timezone, input_date) | ||
tz_input = input_date + offset if add else input_date - offset | ||
|
||
time_since = tz_input - first_date | ||
|
||
if unit == "ms": | ||
parsed = ( | ||
time_since.days | ||
* Conversion.HOURS_IN_DAY | ||
* Conversion.MINUTES_IN_HOUR | ||
* Conversion.SECONDS_IN_MINUTE | ||
* Conversion.MILLISECONDS_IN_SECOND | ||
+ time_since.seconds * Conversion.MILLISECONDS_IN_SECOND | ||
) | ||
elif unit == "s": | ||
parsed = ( | ||
time_since.days | ||
* Conversion.HOURS_IN_DAY | ||
* Conversion.MINUTES_IN_HOUR | ||
* Conversion.SECONDS_IN_MINUTE | ||
+ time_since.seconds | ||
) | ||
elif unit == "m": | ||
parsed = ( | ||
time_since.days * Conversion.HOURS_IN_DAY * Conversion.MINUTES_IN_HOUR | ||
+ time_since.seconds // Conversion.SECONDS_IN_MINUTE | ||
) | ||
elif unit == "h": | ||
parsed = ( | ||
time_since.days * Conversion.HOURS_IN_DAY | ||
+ time_since.seconds | ||
// Conversion.SECONDS_IN_MINUTE | ||
// Conversion.MINUTES_IN_HOUR | ||
) | ||
elif unit == "d": | ||
parsed = time_since.days | ||
else: | ||
raise Exception( | ||
"Unit doesn't exist. Check documentation to see available units." | ||
) | ||
|
||
return mgp.Record(parsed=parsed) | ||
|
||
|
||
@mgp.read_proc | ||
def format( | ||
time: int, | ||
unit: str = "ms", | ||
format: str = "%Y-%m-%d %H:%M:%S %Z", | ||
timezone: str = "UTC", | ||
) -> mgp.Record(formatted=str): | ||
first_date = Epoch.UNIX_EPOCH | ||
|
||
if unit == "ms": | ||
new_date = first_date + datetime.timedelta(milliseconds=time) | ||
elif unit == "s": | ||
new_date = first_date + datetime.timedelta(seconds=time) | ||
elif unit == "m": | ||
new_date = first_date + datetime.timedelta(minutes=time) | ||
elif unit == "h": | ||
new_date = first_date + datetime.timedelta(hours=time) | ||
elif unit == "d": | ||
new_date = first_date + datetime.timedelta(days=time) | ||
else: | ||
raise Exception( | ||
"Unit doesn't exist. Check documentation to see available units." | ||
) | ||
|
||
if timezone not in pytz.all_timezones: | ||
raise Exception( | ||
"Timezone doesn't exist. Check documentation to see available timezones." | ||
) | ||
offset, subtract = getOffset(timezone, new_date) | ||
tz_new = new_date - offset if subtract else new_date + offset | ||
|
||
return mgp.Record( | ||
formatted=pytz.timezone(timezone).localize(tz_new).strftime(format) | ||
) |
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,12 @@ | ||
import datetime | ||
|
||
|
||
class Conversion(int): | ||
MINUTES_IN_HOUR = 60 | ||
SECONDS_IN_MINUTE = 60 | ||
MILLISECONDS_IN_SECOND = 1000 | ||
HOURS_IN_DAY = 24 | ||
|
||
|
||
class Epoch(datetime.datetime): | ||
UNIX_EPOCH = datetime.datetime(1970, 1, 1, 0, 0, 0) |