Skip to content

Commit

Permalink
Merge pull request #6 from mojoto/feat/from_to_py
Browse files Browse the repository at this point in the history
feat: add from to py
  • Loading branch information
Prodesire authored Oct 24, 2023
2 parents aea5ff0 + 269c0d3 commit ad57f76
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 5 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,13 @@ print(ordinal) # 738794
# Construct a Morrow from a proleptic Gregorian ordinal.
let m_10_1_ = Morrow.fromordinal(ordinal)
print(m_10_1_.__str__()) # 2023-10-01T00:00:00.000000

# Convert Morrow to python datetime
let py_dt = now.to_py()
print(dt.isoformat()) # 2023-10-01T20:10:25.188957

# Convert python datetime to Morrow
let m_from_py = Morrow.from_py(py_dt)
print(m_from_py.__str__()) # 2023-10-01T20:10:25.188957

```
52 changes: 47 additions & 5 deletions morrow/morrow.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ from ._libc import CTimeval, CTm
from .timezone import TimeZone
from .timedelta import TimeDelta
from .constants import _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH
from python.object import PythonObject
from python import Python


alias _DI400Y = 146097 # number of days in 400 years
Expand All @@ -21,7 +23,7 @@ struct Morrow:
var minute: Int
var second: Int
var microsecond: Int
var TimeZone: TimeZone
var tz: TimeZone

fn __init__(
inout self,
Expand All @@ -32,7 +34,7 @@ struct Morrow:
minute: Int = 0,
second: Int = 0,
microsecond: Int = 0,
TimeZone: TimeZone = TimeZone.none(),
tz: TimeZone = TimeZone.none(),
) raises:
self.year = year
self.month = month
Expand All @@ -41,7 +43,7 @@ struct Morrow:
self.minute = minute
self.second = second
self.microsecond = microsecond
self.TimeZone = TimeZone
self.tz = tz

@staticmethod
fn now() raises -> Self:
Expand Down Expand Up @@ -186,10 +188,12 @@ struct Morrow:
time_str = num2str(self.hour, 2)
else:
raise Error()
if self.TimeZone.is_none():
if self.tz.is_none():
return sep.join(date_str, time_str)
else:
return sep.join(date_str, time_str) + self.TimeZone.format()
return sep.join(date_str, time_str) + self.tz.format()



fn toordinal(self) raises -> Int:
"""Return proleptic Gregorian ordinal for the year, month and day.
Expand Down Expand Up @@ -286,3 +290,41 @@ struct Morrow:
days1 - days2, secs1 - secs2, self.microsecond - other.microsecond
)
return base

fn to_py(self) raises -> PythonObject:
# todo: add tz later
let dateimte = Python.import_module("datetime")
return dateimte.datetime(
self.year,
self.month,
self.day,
self.hour,
self.minute,
self.second,
self.microsecond,
)

@staticmethod
fn from_py(py_datetime: PythonObject) raises -> Morrow:
# Python.is_type not working, use __class__.__name__ instead
if py_datetime.__class__.__name__ == 'datetime':
return Morrow(
py_datetime.year.to_float64().to_int(),
py_datetime.month.to_float64().to_int(),
py_datetime.day.to_float64().to_int(),
py_datetime.hour.to_float64().to_int(),
py_datetime.minute.to_float64().to_int(),
py_datetime.second.to_float64().to_int(),
py_datetime.second.to_float64().to_int(),
)
elif py_datetime.__class__.__name__ == 'date':
return Morrow(
py_datetime.year.to_float64().to_int(),
py_datetime.month.to_float64().to_int(),
py_datetime.day.to_float64().to_int(),
)
else:
raise Error("invalid python object, only support py builtin datetime or date")



12 changes: 12 additions & 0 deletions test.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@ def test_timedelta():
)


def test_from_to_py():
print("Running test_from_to_py")
m = Morrow.now()
dt = m.to_py()
assert_datetime_equal(m, dt)

m2 = Morrow.from_py(dt)
assert_datetime_equal(m2, dt)


def main():
test_now()
test_utcnow()
Expand All @@ -157,3 +167,5 @@ def main():
test_time_zone()
test_strptime()
test_timedelta()
test_from_to_py()

0 comments on commit ad57f76

Please sign in to comment.