Skip to main content

Time-aware list slicing with datetime and calendar-period bounds

Project description

tals — Time-Aware List Slicer

tals makes time-based slicing as natural as ordinary indexing. It extends Python's [start:end] syntax with datetime and calendar-period bounds, and works on any list of objects — it only needs to know which attribute holds the timestamp.

from tals import slice_objects

# Last 7 days
slice_objects(entries, "-7d:", "created_at", reference_dt)

# This calendar month, excluding the last entry
slice_objects(entries, "0M:-1", "created_at", reference_dt)

# February only
slice_objects(entries, "-1M:0M", "created_at", reference_dt)

Installation

pip install tals

Overview

tals extends Python's familiar [start:end] slice syntax with two additional bound types:

  • Time-delta bounds — relative to a reference datetime: -7d, +2h, -30m
  • Calendar-period bounds — snapped to period boundaries: 0M, -1W, 0Y

The library has no domain knowledge. It works on any list of objects and only needs the name of the attribute that holds each object's timestamp.

API

def slice_objects(
    objects: list[Any],
    position: str,
    timestamp_key: str,
    reference_dt: datetime,
    week_start: int = 0,
) -> Any | list[Any]:
Parameter Description
objects List of arbitrary objects in any order
position Slice expression string (see syntax below)
timestamp_key Attribute name holding each object's datetime value
reference_dt The "now" anchor for all relative expressions — the library never calls datetime.now() itself
week_start First day of the week: 0 = Monday (default), 6 = Sunday

Return value: a single-index expression returns one object (or None if out of bounds); a slice expression returns a list (possibly empty).

The list is stable-sorted ascending by timestamp_key before slicing. All indices operate on this sorted list.

Syntax

[index]
[start:end]
[start:]
[:end]
[:]

Bound types

Form Description Example
0, 1, -1 Integer index — same semantics as Python [-1] → last object
-7d, +2h, -30m Time-delta — relative to reference_dt [-7d:] → last 7 days
0M, -1M, +1M Calendar month — start of the Nth month [0M:] → this month onward
0W, -1W Calendar week — start of the Nth week [-1W:0W] → last week
0Y, -1Y Calendar year — Jan 1 of the Nth year [0Y:] → this year onward

Period 0 is the period containing reference_dt; -1 is the previous period; +1 is the next.

Calendar bounds are not valid as a single index — they only make sense in a slice.

Inclusivity

All bounds follow Python's convention: start is inclusive, end is exclusive.

Expression Meaning
[-7d:] timestamp >= reference_dt − 7 days
[:-7d] timestamp < reference_dt − 7 days
[-1M:0M] timestamp >= start of last month and < start of this month

Mixed bounds

A slice can mix bound types. Time/calendar bounds are resolved to datetime thresholds first, the list is filtered, then integer bounds are applied to the filtered result.

# March entries, excluding the last one
slice_objects(entries, "0M:-1", "created_at", reference_dt)
# → filter to [Mar 1, Apr 1), then apply [:-1]

# From 7 days ago, drop the trailing entry
slice_objects(entries, "-7d:-1", "created_at", reference_dt)

Examples

Given four objects with a start attribute and reference_dt = 2026-03-10:

Object start
A 2026-01-10
B 2026-02-05
C 2026-03-01
D 2026-03-10
slice_objects(objs, "[-1]",     "start", ref)  # → D
slice_objects(objs, "[0]",      "start", ref)  # → A
slice_objects(objs, "[:]",      "start", ref)  # → [A, B, C, D]
slice_objects(objs, "[:-1]",    "start", ref)  # → [A, B, C]
slice_objects(objs, "[0M:]",    "start", ref)  # → [C, D]       (March)
slice_objects(objs, "[-1M:0M]", "start", ref)  # → [B]          (February)
slice_objects(objs, "[-1M:]",   "start", ref)  # → [B, C, D]    (Feb 1 onward)
slice_objects(objs, "[0Y:]",    "start", ref)  # → [A, B, C, D] (all of 2026)
slice_objects(objs, "[0M:-1]",  "start", ref)  # → [C]          (March, drop last)

Timezone handling

reference_dt and all object timestamps must be either all timezone-aware or all timezone-naive — mixing the two raises TypeError. Objects in different (but both aware) timezones are compared correctly by Python and are fully supported.

Calendar boundaries are computed in the timezone of reference_dt, so 0M on a UTC+02:00 reference resolves to midnight of the 1st in that timezone.

Out of scope

tals is a pure slicing primitive. The following are the caller's responsibility:

  • Pre-filtering — pass only the subset of objects that should be considered
  • Field extraction — read attributes from the returned objects
  • Fallback values — convert None or [] to domain-specific defaults

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tals-0.1.0.tar.gz (8.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tals-0.1.0-py3-none-any.whl (6.9 kB view details)

Uploaded Python 3

File details

Details for the file tals-0.1.0.tar.gz.

File metadata

  • Download URL: tals-0.1.0.tar.gz
  • Upload date:
  • Size: 8.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for tals-0.1.0.tar.gz
Algorithm Hash digest
SHA256 cd76cb98a08d7c25d0e6a22a64985d138a5957cdd3c5798204535cc85f7d033d
MD5 1d115d3f64f474a3fa544fca7c35a972
BLAKE2b-256 00fb4d1d69e773a3e37eeb77ab44e22d457674f814744dbf716329d842c01238

See more details on using hashes here.

File details

Details for the file tals-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: tals-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for tals-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dff5f5051dedf9c5d62a132e6c7ba54c712af4b18d362b988f3ae73d3ec587ee
MD5 7e727db56a4b53b2238226651ad9cd38
BLAKE2b-256 0368d9fcf813db7de9b4fc3d8bcc8c112a367eafd69e878489fb3d44555227f3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page