Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add datetime and time pickers #2715

Merged
merged 9 commits into from
Jun 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a couple of these headers here and below could be updated to match the existing ones.

# 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