Add datetime.time
This commit is contained in:
parent
d7b90c1b3a
commit
f45362943d
|
@ -130,3 +130,8 @@ pub unsafe fn PyDateTime_Check(op: *mut PyObject) -> c_int {
|
|||
pub unsafe fn PyTZInfo_Check(op: *mut PyObject) -> c_int {
|
||||
PyObject_TypeCheck(op, PyDateTimeAPI.TZInfoType) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub unsafe fn PyTime_Check(op: *mut PyObject) -> c_int {
|
||||
PyObject_TypeCheck(op, PyDateTimeAPI.TimeType) as c_int
|
||||
}
|
||||
|
|
|
@ -54,6 +54,29 @@ impl PyDateTime {
|
|||
}
|
||||
}
|
||||
|
||||
// datetime.time
|
||||
pub struct PyTime(PyObject);
|
||||
pyobject_convert!(PyTime);
|
||||
pyobject_nativetype!(PyTime, PyDateTime_TimeType, PyTime_Check);
|
||||
|
||||
impl PyTime {
|
||||
pub fn new(py: Python, hour: u32, minute: u32, second: u32,
|
||||
microsecond: u32, tzinfo: &PyObject) -> PyResult<Py<PyTime>> {
|
||||
let h = hour as c_int;
|
||||
let m = minute as c_int;
|
||||
let s = second as c_int;
|
||||
let u = microsecond as c_int;
|
||||
let tzi = tzinfo.as_ptr();
|
||||
|
||||
unsafe {
|
||||
let ptr = PyDateTimeAPI.Time_FromTime.unwrap()(
|
||||
h, m, s, u, tzi, PyDateTimeAPI.TimeType
|
||||
);
|
||||
Py::from_owned_ptr_or_err(py, ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// datetime.tzinfo bindings
|
||||
pub struct PyTzInfo(PyObject);
|
||||
pyobject_convert!(PyTzInfo);
|
||||
|
|
|
@ -5,7 +5,7 @@ mod exc_impl;
|
|||
|
||||
pub use self::boolobject::PyBool;
|
||||
pub use self::bytearray::PyByteArray;
|
||||
pub use self::datetime::{PyDate,PyDateTime,PyTzInfo};
|
||||
pub use self::datetime::{PyDate,PyTime,PyDateTime,PyTzInfo};
|
||||
pub use self::dict::PyDict;
|
||||
pub use self::floatob::PyFloat;
|
||||
pub use self::iterator::PyIterator;
|
||||
|
|
|
@ -4,7 +4,7 @@ extern crate pyo3;
|
|||
use pyo3::{py, Py, Python, PyModule, PyResult};
|
||||
use pyo3::{ToPyObject};
|
||||
use pyo3::prelude::{PyObject};
|
||||
use pyo3::prelude::{PyDate, PyDateTime, PyTzInfo};
|
||||
use pyo3::prelude::{PyDate, PyTime, PyDateTime, PyTzInfo};
|
||||
|
||||
#[py::modinit(datetime)]
|
||||
fn init_mod(py: Python, m: &PyModule) -> PyResult<()> {
|
||||
|
@ -13,6 +13,17 @@ fn init_mod(py: Python, m: &PyModule) -> PyResult<()> {
|
|||
PyDate::new(py, year, month, day)
|
||||
}
|
||||
|
||||
#[pyfn(m, "make_time")]
|
||||
fn make_time(py: Python, hour: u32, minute: u32, second: u32,
|
||||
microsecond: u32, tzinfo: Option<&PyTzInfo>) -> PyResult<Py<PyTime>> {
|
||||
let tzi: PyObject = match tzinfo {
|
||||
Some(t) => t.to_object(py),
|
||||
None => py.None(),
|
||||
};
|
||||
|
||||
PyTime::new(py, hour, minute, second, microsecond, &tzi)
|
||||
}
|
||||
|
||||
#[pyfn(m, "make_datetime")]
|
||||
fn make_datetime(py: Python, year: u32, month: u32, day: u32,
|
||||
hour: u32, minute: u32, second: u32, microsecond: u32,
|
||||
|
|
|
@ -4,6 +4,8 @@ import datetime as pdt
|
|||
|
||||
import pytest
|
||||
|
||||
UTC = pdt.timezone.utc
|
||||
|
||||
|
||||
def test_date():
|
||||
assert rdt.make_date(2017, 9, 1) == pdt.date(2017, 9, 1)
|
||||
|
@ -14,15 +16,67 @@ def test_invalid_date_fails():
|
|||
rdt.make_date(2017, 2, 30)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('args, kwargs', [
|
||||
((0, 0, 0, 0, None), {}),
|
||||
((1, 12, 14, 124731), {}),
|
||||
((1, 12, 14, 124731), {'tzinfo': UTC}),
|
||||
])
|
||||
def test_time(args, kwargs):
|
||||
act = rdt.make_time(*args, **kwargs)
|
||||
exp = pdt.time(*args, **kwargs)
|
||||
|
||||
assert act == exp
|
||||
assert act.tzinfo is exp.tzinfo
|
||||
|
||||
|
||||
@pytest.mark.xfail
|
||||
@pytest.mark.parametrize('args', [
|
||||
(-1, 0, 0, 0),
|
||||
(0, -1, 0, 0),
|
||||
(0, 0, -1, 0),
|
||||
(0, 0, 0, -1),
|
||||
])
|
||||
def test_invalid_time_fails_xfail(args):
|
||||
with pytest.raises(ValueError):
|
||||
rdt.make_time(*args)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('args', [
|
||||
(24, 0, 0, 0),
|
||||
(25, 0, 0, 0),
|
||||
(0, 60, 0, 0),
|
||||
(0, 61, 0, 0),
|
||||
(0, 0, 60, 0),
|
||||
(0, 0, 61, 0),
|
||||
(0, 0, 0, 1000000)
|
||||
])
|
||||
def test_invalid_time_fails(args):
|
||||
with pytest.raises(ValueError):
|
||||
rdt.make_time(*args)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('args', [
|
||||
('0', 0, 0, 0),
|
||||
(0, '0', 0, 0),
|
||||
(0, 0, '0', 0),
|
||||
(0, 0, 0, '0'),
|
||||
(0, 0, 0, 0, 'UTC')
|
||||
])
|
||||
def test_time_typeerror(args):
|
||||
with pytest.raises(TypeError):
|
||||
rdt.make_time(*args)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('args, kwargs', [
|
||||
((2017, 9, 1, 12, 45, 30, 0), {}),
|
||||
((2017, 9, 1, 12, 45, 30, 0), {'tzinfo': pdt.timezone.utc}),
|
||||
((2017, 9, 1, 12, 45, 30, 0), {'tzinfo': UTC}),
|
||||
])
|
||||
def test_datetime(args, kwargs):
|
||||
act = rdt.make_datetime(*args, **kwargs)
|
||||
exp = pdt.datetime(*args, **kwargs)
|
||||
|
||||
assert act == exp
|
||||
assert act.tzinfo is exp.tzinfo
|
||||
|
||||
|
||||
def test_invalid_datetime_fails():
|
||||
|
|
Loading…
Reference in New Issue