Skip to content

Commit

Permalink
Merge pull request #2715 from vidartf/datetime
Browse files Browse the repository at this point in the history
Add datetime and time pickers
  • Loading branch information
jtpio authored Jun 30, 2021
2 parents ba22d7d + d6681a6 commit bf56eb7
Show file tree
Hide file tree
Showing 22 changed files with 4,525 additions and 1,466 deletions.
2,870 changes: 1,460 additions & 1,410 deletions docs/source/examples/Widget List.ipynb

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions ipywidgets/widgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
from .widget_int import IntText, BoundedIntText, IntSlider, IntProgress, IntRangeSlider, Play, SliderStyle
from .widget_color import ColorPicker
from .widget_date import DatePicker
from .widget_datetime import DatetimePicker
from .widget_time import TimePicker
from .widget_output import Output
from .widget_selection import RadioButtons, ToggleButtons, ToggleButtonsStyle, Dropdown, Select, SelectionSlider, SelectMultiple, SelectionRangeSlider
from .widget_selectioncontainer import Tab, Accordion, Stacked
Expand Down
91 changes: 91 additions & 0 deletions ipywidgets/widgets/tests/test_datetime_serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/usr/bin/env python
# coding: utf-8

# Copyright (c) Vidar Tonaas Fauske.
# Distributed under the terms of the Modified BSD License.

import pytest

import datetime
import pytz

from traitlets import TraitError

from ..trait_types import (
time_to_json,
time_from_json,
datetime_to_json,
datetime_from_json,
)


def test_time_serialize_none():
assert time_to_json(None, None) == None


def test_time_serialize_value():
t = datetime.time(13, 37, 42, 7000)
assert time_to_json(t, None) == dict(
hours=13, minutes=37, seconds=42, milliseconds=7
)


def test_time_deserialize_none():
assert time_from_json(None, None) == None


def test_time_deserialize_value():
v = dict(hours=13, minutes=37, seconds=42, milliseconds=7)
assert time_from_json(v, None) == datetime.time(13, 37, 42, 7000)


def test_datetime_serialize_none():
assert datetime_to_json(None, None) == None


def test_datetime_serialize_value():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7000, pytz.utc)
assert datetime_to_json(t, None) == dict(
year=2002,
month=1, # Months are 0-based indices in JS
date=20,
hours=13,
minutes=37,
seconds=42,
milliseconds=7,
)


def test_datetime_serialize_non_utz():
# Non-existant timezone, so it wil never be the local one:
tz = pytz.FixedOffset(42)
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7000, tz)
assert datetime_to_json(t, None) == dict(
year=2002,
month=1, # Months are 0-based indices in JS
date=20,
hours=12,
minutes=55,
seconds=42,
milliseconds=7,
)


def test_datetime_deserialize_none():
assert datetime_from_json(None, None) == None


def test_datetime_deserialize_value():
tz = pytz.FixedOffset(42)
v = dict(
year=2002,
month=1, # Months are 0-based indices in JS
date=20,
hours=13,
minutes=37,
seconds=42,
milliseconds=7,
)
assert datetime_from_json(v, None) == datetime.datetime(
2002, 2, 20, 14, 19, 42, 7000, tz
)
111 changes: 111 additions & 0 deletions ipywidgets/widgets/tests/test_widget_datetime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/usr/bin/env python
# coding: utf-8

# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

import pytest

import datetime

import pytz
from traitlets import TraitError

from ..widget_datetime import DatetimePicker


def test_time_creation_blank():
w = DatetimePicker()
assert w.value is None


def test_time_creation_value():
t = datetime.datetime.now(pytz.utc)
w = DatetimePicker(value=t)
assert w.value is t


def test_time_validate_value_none():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc)
t_min = datetime.datetime(1442, 1, 1, tzinfo=pytz.utc)
t_max = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc)
w = DatetimePicker(value=t, min=t_min, max=t_max)
w.value = None
assert w.value is None


def test_time_validate_value_vs_min():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc)
t_min = datetime.datetime(2019, 1, 1, tzinfo=pytz.utc)
t_max = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc)
w = DatetimePicker(min=t_min, max=t_max)
w.value = t
assert w.value.year == 2019


def test_time_validate_value_vs_max():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc)
t_min = datetime.datetime(1664, 1, 1, tzinfo=pytz.utc)
t_max = datetime.datetime(1994, 1, 1, tzinfo=pytz.utc)
w = DatetimePicker(min=t_min, max=t_max)
w.value = t
assert w.value.year == 1994


def test_time_validate_min_vs_value():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc)
t_min = datetime.datetime(2019, 1, 1, tzinfo=pytz.utc)
t_max = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc)
w = DatetimePicker(value=t, max=t_max)
w.min = t_min
assert w.value.year == 2019


def test_time_validate_min_vs_max():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc)
t_min = datetime.datetime(2112, 1, 1, tzinfo=pytz.utc)
t_max = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc)
w = DatetimePicker(value=t, max=t_max)
with pytest.raises(TraitError):
w.min = t_min


def test_time_validate_max_vs_value():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc)
t_min = datetime.datetime(1664, 1, 1, tzinfo=pytz.utc)
t_max = datetime.datetime(1994, 1, 1, tzinfo=pytz.utc)
w = DatetimePicker(value=t, min=t_min)
w.max = t_max
assert w.value.year == 1994


def test_time_validate_max_vs_min():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc)
t_min = datetime.datetime(1664, 1, 1, tzinfo=pytz.utc)
t_max = datetime.datetime(1337, 1, 1, tzinfo=pytz.utc)
w = DatetimePicker(value=t, min=t_min)
with pytest.raises(TraitError):
w.max = t_max


def test_time_validate_naive():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=pytz.utc)
t_min = datetime.datetime(1442, 1, 1, tzinfo=pytz.utc)
t_max = datetime.datetime(2056, 1, 1, tzinfo=pytz.utc)

w = DatetimePicker(value=t, min=t_min, max=t_max)
with pytest.raises(TraitError):
w.max = t_max.replace(tzinfo=None)
with pytest.raises(TraitError):
w.min = t_min.replace(tzinfo=None)
with pytest.raises(TraitError):
w.value = t.replace(tzinfo=None)


def test_datetime_tzinfo():
tz = pytz.timezone('Australia/Sydney')
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=tz)
w = DatetimePicker(value=t)
assert w.value == t
# tzinfo only changes upon input from user
assert w.value.tzinfo == tz
95 changes: 95 additions & 0 deletions ipywidgets/widgets/tests/test_widget_naive_datetime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env python
# coding: utf-8

# Copyright (c) Vidar Tonaas Fauske.
# Distributed under the terms of the Modified BSD License.

import pytest

import datetime

import pytz
from traitlets import TraitError

from ..widget_datetime import NaiveDatetimePicker


def test_time_creation_blank():
w = NaiveDatetimePicker()
assert w.value is None


def test_time_creation_value():
t = datetime.datetime.today()
w = NaiveDatetimePicker(value=t)
assert w.value is t


def test_time_validate_value_none():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7)
t_min = datetime.datetime(1442, 1, 1)
t_max = datetime.datetime(2056, 1, 1)
w = NaiveDatetimePicker(value=t, min=t_min, max=t_max)
w.value = None
assert w.value is None


def test_time_validate_value_vs_min():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7)
t_min = datetime.datetime(2019, 1, 1)
t_max = datetime.datetime(2056, 1, 1)
w = NaiveDatetimePicker(min=t_min, max=t_max)
w.value = t
assert w.value.year == 2019


def test_time_validate_value_vs_max():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7)
t_min = datetime.datetime(1664, 1, 1)
t_max = datetime.datetime(1994, 1, 1)
w = NaiveDatetimePicker(min=t_min, max=t_max)
w.value = t
assert w.value.year == 1994


def test_time_validate_min_vs_value():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7)
t_min = datetime.datetime(2019, 1, 1)
t_max = datetime.datetime(2056, 1, 1)
w = NaiveDatetimePicker(value=t, max=t_max)
w.min = t_min
assert w.value.year == 2019


def test_time_validate_min_vs_max():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7)
t_min = datetime.datetime(2112, 1, 1)
t_max = datetime.datetime(2056, 1, 1)
w = NaiveDatetimePicker(value=t, max=t_max)
with pytest.raises(TraitError):
w.min = t_min


def test_time_validate_max_vs_value():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7)
t_min = datetime.datetime(1664, 1, 1)
t_max = datetime.datetime(1994, 1, 1)
w = NaiveDatetimePicker(value=t, min=t_min)
w.max = t_max
assert w.value.year == 1994


def test_time_validate_max_vs_min():
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7)
t_min = datetime.datetime(1664, 1, 1)
t_max = datetime.datetime(1337, 1, 1)
w = NaiveDatetimePicker(value=t, min=t_min)
with pytest.raises(TraitError):
w.max = t_max


def test_datetime_tzinfo():
tz = pytz.timezone('Australia/Sydney')
t = datetime.datetime(2002, 2, 20, 13, 37, 42, 7, tzinfo=tz)
with pytest.raises(TraitError):
w = NaiveDatetimePicker(value=t)
87 changes: 87 additions & 0 deletions ipywidgets/widgets/tests/test_widget_time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/usr/bin/env python
# coding: utf-8

# Copyright (c) Vidar Tonaas Fauske.
# Distributed under the terms of the Modified BSD License.

import pytest

import datetime

from traitlets import TraitError

from ..widget_time import TimePicker


def test_time_creation_blank():
w = TimePicker()
assert w.value is None


def test_time_creation_value():
t = datetime.time()
w = TimePicker(value=t)
assert w.value is t


def test_time_validate_value_none():
t = datetime.time(13, 37, 42, 7)
t_min = datetime.time(2)
t_max = datetime.time(22)
w = TimePicker(value=t, min=t_min, max=t_max)
w.value = None
assert w.value is None


def test_time_validate_value_vs_min():
t = datetime.time(13, 37, 42, 7)
t_min = datetime.time(14)
t_max = datetime.time(22)
w = TimePicker(min=t_min, max=t_max)
w.value = t
assert w.value.hour == 14


def test_time_validate_value_vs_max():
t = datetime.time(13, 37, 42, 7)
t_min = datetime.time(2)
t_max = datetime.time(12)
w = TimePicker(min=t_min, max=t_max)
w.value = t
assert w.value.hour == 12


def test_time_validate_min_vs_value():
t = datetime.time(13, 37, 42, 7)
t_min = datetime.time(14)
t_max = datetime.time(22)
w = TimePicker(value=t, max=t_max)
w.min = t_min
assert w.value.hour == 14


def test_time_validate_min_vs_max():
t = datetime.time(13, 37, 42, 7)
t_min = datetime.time(14)
t_max = datetime.time(12)
w = TimePicker(value=t, max=t_max)
with pytest.raises(TraitError):
w.min = t_min


def test_time_validate_max_vs_value():
t = datetime.time(13, 37, 42, 7)
t_min = datetime.time(2)
t_max = datetime.time(12)
w = TimePicker(value=t, min=t_min)
w.max = t_max
assert w.value.hour == 12


def test_time_validate_max_vs_min():
t = datetime.time(13, 37, 42, 7)
t_min = datetime.time(2)
t_max = datetime.time(1)
w = TimePicker(value=t, min=t_min)
with pytest.raises(TraitError):
w.max = t_max
Loading

0 comments on commit bf56eb7

Please sign in to comment.