Skip to content

Commit 5763225

Browse files
committed
Adds support for hour, minute, second units in start_of()/end_of() methods.
1 parent 474f360 commit 5763225

File tree

4 files changed

+104
-1
lines changed

4 files changed

+104
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Added a `Time` class.
99
- Added a `remaining_days` property to the `Interval` class.
1010
- Added a `in_timestamp` property to the `Pendulum` class to retrieve the behavior of the now deprecated `timestamp` property.
11+
- `start_of()`/`end_of()` now supports `hour`, `minute` and `second` units.
1112

1213
### Changed
1314

@@ -30,6 +31,7 @@
3031
- Accuracy of `Period` instances properties has been improved.
3132
- Accuracy for microseconds when initializing a Pendulum instance in some timezones has been fixed.
3233
- Periods are now serializable with `pickle`.
34+
- Fixed `minute_()`, `second_()` and `microsecond_()` setters changing the hour unit.
3335

3436

3537
## [0.6.5] - 2016-10-31

pendulum/pendulum.py

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ class Pendulum(Date, datetime.datetime):
4444

4545
_TRANSITION_RULE = Timezone.POST_TRANSITION
4646

47+
_MODIFIERS_VALID_UNITS = [
48+
'second', 'minute', 'hour',
49+
'day', 'week', 'month', 'year',
50+
'decade', 'century'
51+
]
52+
4753
@classmethod
4854
def _safe_create_datetime_zone(cls, obj):
4955
"""
@@ -455,7 +461,7 @@ def microsecond_(self, microsecond):
455461
return self._setter(microsecond=microsecond)
456462

457463
def _setter(self, **kwargs):
458-
kwargs['tzinfo'] = None
464+
kwargs['tzinfo'] = True
459465

460466
return self._tz.convert(self.replace(**kwargs))
461467

@@ -1291,6 +1297,9 @@ def start_of(self, unit):
12911297
Returns a copy of the instance with the time reset
12921298
with the following rules:
12931299
1300+
* second: microsecond set to 0
1301+
* minute: second and microsecond set to 0
1302+
* hour: minute, second and microsecond set to 0
12941303
* day: time to 00:00:00
12951304
* week: date to first day of the week and time to 00:00:00
12961305
* month: date to first day of the month and time to 00:00:00
@@ -1313,6 +1322,9 @@ def end_of(self, unit):
13131322
Returns a copy of the instance with the time reset
13141323
with the following rules:
13151324
1325+
* second: microsecond set to 999999
1326+
* minute: second set to 59 and microsecond set to 999999
1327+
* hour: minute and second set to 59 and microsecond set to 999999
13161328
* day: time to 23:59:59.999999
13171329
* week: date to last day of the week and time to 23:59:59.999999
13181330
* month: date to last day of the month and time to 23:59:59.999999
@@ -1330,6 +1342,54 @@ def end_of(self, unit):
13301342

13311343
return getattr(self, '_end_of_%s' % unit)()
13321344

1345+
def _start_of_second(self):
1346+
"""
1347+
Reset microseconds to 0.
1348+
1349+
:rtype: Pendulum
1350+
"""
1351+
return self.microsecond_(0)
1352+
1353+
def _end_of_second(self):
1354+
"""
1355+
Set microseconds to 999999.
1356+
1357+
:rtype: Pendulum
1358+
"""
1359+
return self.microsecond_(999999)
1360+
1361+
def _start_of_minute(self):
1362+
"""
1363+
Reset seconds and microseconds to 0.
1364+
1365+
:rtype: Pendulum
1366+
"""
1367+
return self.replace(second=0, microsecond=0)
1368+
1369+
def _end_of_minute(self):
1370+
"""
1371+
Set seconds to 59 and microseconds to 999999.
1372+
1373+
:rtype: Pendulum
1374+
"""
1375+
return self.replace(second=59, microsecond=999999)
1376+
1377+
def _start_of_hour(self):
1378+
"""
1379+
Reset minutes, seconds and microseconds to 0.
1380+
1381+
:rtype: Pendulum
1382+
"""
1383+
return self.replace(minute=0, second=0, microsecond=0)
1384+
1385+
def _end_of_hour(self):
1386+
"""
1387+
Set minutes and seconds to 59 and microseconds to 999999.
1388+
1389+
:rtype: Pendulum
1390+
"""
1391+
return self.replace(minute=59, second=59, microsecond=999999)
1392+
13331393
def _start_of_day(self):
13341394
"""
13351395
Reset the time to 00:00:00

tests/pendulum_tests/test_fluent_setters.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ def test_fluid_microsecond_setter(self):
5858
self.assertEqual(987654, new.microsecond)
5959
self.assertEqual(123456, d.microsecond)
6060

61+
def test_fluid_setter_keeps_timezone(self):
62+
d = Pendulum.create(2016, 7, 2, 0, 41, 20, 123456, tz='Europe/Paris')
63+
new = d.microsecond_(987654)
64+
self.assertPendulum(new, 2016, 7, 2, 0, 41, 20, 987654)
65+
6166
def test_fluid_timezone_setter(self):
6267
d = Pendulum.create(2016, 7, 2, 0, 41, 20)
6368
new = d.timezone_('Europe/Paris')

tests/pendulum_tests/test_start_end_of.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,42 @@
77

88
class StartEndOfTest(AbstractTestCase):
99

10+
def test_start_of_second(self):
11+
d = Pendulum.now()
12+
new = d.start_of('second')
13+
self.assertIsInstanceOfPendulum(new)
14+
self.assertPendulum(new, d.year, d.month, d.day, d.hour, d.minute, d.second, 0)
15+
16+
def test_end_of_second(self):
17+
d = Pendulum.now()
18+
new = d.end_of('second')
19+
self.assertIsInstanceOfPendulum(new)
20+
self.assertPendulum(new, d.year, d.month, d.day, d.hour, d.minute, d.second, 999999)
21+
22+
def test_start_of_minute(self):
23+
d = Pendulum.now()
24+
new = d.start_of('minute')
25+
self.assertIsInstanceOfPendulum(new)
26+
self.assertPendulum(new, d.year, d.month, d.day, d.hour, d.minute, 0, 0)
27+
28+
def test_end_of_minute(self):
29+
d = Pendulum.now()
30+
new = d.end_of('minute')
31+
self.assertIsInstanceOfPendulum(new)
32+
self.assertPendulum(new, d.year, d.month, d.day, d.hour, d.minute, 59, 999999)
33+
34+
def test_start_of_hour(self):
35+
d = Pendulum.now()
36+
new = d.start_of('hour')
37+
self.assertIsInstanceOfPendulum(new)
38+
self.assertPendulum(new, d.year, d.month, d.day, d.hour, 0, 0, 0)
39+
40+
def test_end_of_hour(self):
41+
d = Pendulum.now()
42+
new = d.end_of('hour')
43+
self.assertIsInstanceOfPendulum(new)
44+
self.assertPendulum(new, d.year, d.month, d.day, d.hour, 59, 59, 999999)
45+
1046
def test_start_of_day(self):
1147
d = Pendulum.now()
1248
new = d.start_of('day')

0 commit comments

Comments
 (0)