-
-
Notifications
You must be signed in to change notification settings - Fork 0
get dt index for time unit #15
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
Changes from all commits
0e3e16b
3d68d1e
8a6b784
6c1fa4c
7ccdf38
07b0a64
b128213
9ea0b3b
26320bb
e391018
d77e04b
f292d4c
cbfe24d
e206aaf
6dc9467
ab3c583
360fd15
6407573
5e97d1b
6f8224e
0c31704
0174990
b11c55a
fed70bc
c842d6c
2a29deb
80d8f9c
744f35f
04ba81b
e1d30f3
dc5caa2
196cd37
7b8c486
3d94a19
47a1ea8
9aae40a
b36e7e0
9592bb7
6df07aa
627e11c
146359f
c24b639
e8c7efe
63d66b4
cce7bff
e348f65
d2c10e0
4e097a0
e969811
0dc930f
37dfafb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |
| from datetime import date, datetime, time, timedelta | ||
|
|
||
| from unit_of_time import Year, Quarter, Month, Week, Day, TimeunitKind, Timeunit | ||
| from itertools import islice | ||
|
|
||
|
|
||
| class Decade(TimeunitKind): | ||
|
|
@@ -19,26 +20,52 @@ def truncate(cls, dt): | |
| Returns: | ||
| date: The first day (January 1) of the decade in which `dt` falls. | ||
| """ | ||
| return date(10 * (dt.year // 10), 1, 1) | ||
| return date(max(10 * (dt.year // 10), 1), 1, 1) | ||
|
|
||
| @classmethod | ||
| def get_index_for_date(cls, dt): | ||
| """ | ||
| Return the zero-based decade index for the given date. | ||
|
|
||
| Parameters: | ||
| dt (date or datetime): The date for which to compute the decade index. | ||
|
|
||
| Returns: | ||
| int: The decade index equal to the calendar year divided by 10 using integer division (year // 10). | ||
| """ | ||
| return dt.year // 10 | ||
|
Comment on lines
+25
to
+36
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent indexing pattern with other time units.
This works for the current Apply this diff to align with the offset-based pattern: @classmethod
def get_index_for_date(cls, dt):
- return dt.year // 10
+ return (dt.year - date.min.year) // 10Note: You'll also need to implement @classmethod
def get_date_from_index(cls, idx):
return date((idx * 10) + date.min.year, 1, 1)🤖 Prompt for AI Agents |
||
|
|
||
| @classmethod | ||
| def get_date_from_index(cls, idx): | ||
| """ | ||
| Return the start date (January 1) of the decade represented by the given index. | ||
|
|
||
| Parameters: | ||
| idx (int): Decade index; the corresponding year is 10 * idx. | ||
|
|
||
| Returns: | ||
| datetime.date: January 1 of the year 10 * idx. | ||
| """ | ||
| return date(max(10 * idx, 1), 1, 1) | ||
|
|
||
| @classmethod | ||
| def last_day(cls, dt): | ||
| """ | ||
| Return the last day of the decade containing the given date. | ||
| Return the last date of the decade that contains the given date. | ||
|
|
||
| Parameters: | ||
| dt (date or datetime): The date for which to determine the last day of its decade. | ||
| dt (date | datetime): Date or datetime within the target decade. | ||
|
|
||
| Returns: | ||
| date: The last day of the decade as a date object. | ||
| date: The last day of that decade. | ||
| """ | ||
| dt = cls.truncate(dt) | ||
| return date(dt.year + 10, 1, 1) - timedelta(days=1) | ||
|
|
||
|
|
||
| TIME_UNITS = [Decade, Year, Quarter, Month, Week, Day] | ||
| START_DATE = date(1302, 7, 11) | ||
| END_DATE = date(2019, 11, 25) | ||
| START_DATE = date(902, 7, 11) | ||
| END_DATE = date(1019, 11, 25) | ||
|
|
||
|
|
||
| class TimeUnitTest(unittest.TestCase): | ||
|
|
@@ -99,6 +126,17 @@ def test_to_int(self): | |
| self.assertLess(tu, tu.next) | ||
| self.assertLessEqual(tu.previous, tu) | ||
| self.assertLessEqual(tu, tu.next) | ||
| idx = kind.get_index_for_date(tu.dt) | ||
| self.assertEqual( | ||
| idx, | ||
| kind.get_index_for_date(tu.next.dt) - 1, | ||
| ) | ||
| self.assertEqual(tu.dt, kind.get_date_from_index(idx)) | ||
| self.assertEqual(tu, kind[idx]) | ||
| if dt == tu.first_date: | ||
| for idx2, dt2 in enumerate(tu): | ||
| self.assertEqual(idx, kind.get_index_for_date(dt2)) | ||
| self.assertEqual(dt2, tu[idx2]) | ||
| self.assertGreater(tu, tu.previous) | ||
| self.assertGreater(tu.next, tu) | ||
| self.assertGreaterEqual(tu, tu.previous) | ||
|
|
@@ -109,6 +147,8 @@ def test_to_int(self): | |
| self.assertEqual(TimeunitKind.from_int(int(tu)), tu) | ||
| self.assertIn(dt, tu) | ||
| self.assertIn((dt, dt), tu) | ||
| with self.assertRaises(TypeError): | ||
| (dt, None) in tu | ||
| self.assertIn((tu.first_date, tu.last_date), tu) | ||
| with self.assertRaises(TypeError): | ||
| self.assertIn(1425, tu) | ||
|
|
@@ -151,8 +191,16 @@ def test_to_int(self): | |
| self.assertEqual(tu.previous.previous.previous, 3 << tu) | ||
| self.assertLess(tu.last_date, tu.next.first_date) | ||
| self.assertLess(tu.previous.last_date, tu.first_date) | ||
| self.assertEqual((tu.next.first_date - tu.last_date), timedelta(days=1)) | ||
| self.assertEqual((tu.first_date - tu.previous.last_date), timedelta(days=1)) | ||
| self.assertEqual( | ||
| (tu.next.first_date - tu.last_date), timedelta(days=1) | ||
| ) | ||
| self.assertEqual( | ||
| (tu.first_date - tu.previous.last_date), timedelta(days=1) | ||
| ) | ||
|
|
||
| def test_repr(self): | ||
| self.assertEqual("Week", repr(Week)) | ||
| self.assertEqual("Week[102123:105341:]", repr(Week[102123:105341:])) | ||
|
|
||
| def test_hierarchy(self): | ||
| """ | ||
|
|
@@ -166,6 +214,7 @@ def test_hierarchy(self): | |
| """ | ||
| for i, superkind in enumerate(TIME_UNITS, 1): | ||
| for kind in TIME_UNITS[i:]: | ||
| self.assertLess(superkind, kind) | ||
| for dt in self.date_range_yield(): | ||
| with self.subTest(superkind=superkind, kind=kind, dt=dt): | ||
| stu = superkind(dt) | ||
|
|
@@ -193,7 +242,10 @@ def test_kinds(self): | |
| self.assertEqual(kind, kind.kind_int) | ||
| self.assertEqual(kind.kind_int, kind) | ||
| self.assertEqual(d[kind], kind in seen) | ||
| self.assertEqual(kind.get_index_for_date(date.min), 0) | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| d[kind] = True | ||
| self.assertEqual(list(kind[10:110:10][5:9:2]), list(kind[60:100:20])) | ||
| self.assertEqual(list(islice(kind, 3)), list(kind[:3])) | ||
| self.assertNotIn(kind, seen) | ||
| seen.add(kind) | ||
| for kind2 in TIME_UNITS[i:]: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the “TimUnit” typo.
Line 119 refers to “TimUnit”; please fix to “Timeunit” to match the class name.
🤖 Prompt for AI Agents