Skip to content

IsoWeek class

iso_week_date.isoweek.IsoWeek

Bases: BaseIsoWeek

Represents ISO Week date in the YYYY-WNN format.

The class implements methods and functionalities to work directly with iso week format and avoid moving back and forth between date, datetime and str objects.

Attributes:

Name Type Description
value_

iso-week string of format "YYYY-WNN" where:

  • YYYY is between 0001 and 9999
  • W is a literal character
  • NN is between 01 and 53
Source code in iso_week_date/isoweek.py
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
class IsoWeek(BaseIsoWeek):
    """Represents [ISO Week date](https://en.wikipedia.org/wiki/ISO_week_date) in the  _YYYY-WNN_ format.

    The class implements methods and functionalities to work directly with iso week format and avoid moving back and
    forth between `date`, `datetime` and `str` objects.

    Attributes:
        value_: iso-week string of format "YYYY-WNN" where:

            - YYYY is between 0001 and 9999
            - W is a literal character
            - NN is between 01 and 53
    """

    _pattern = ISOWEEK_PATTERN

    _format = ISOWEEK__FORMAT
    _date_format = ISOWEEK__DATE_FORMAT

    @property
    def days(self: Self) -> Tuple[date, ...]:
        """Returns tuple of days (as date) in the ISO week.

        Examples:
        ```py
        from iso_week_date import IsoWeek

        IsoWeek("2023-W01").days  # (date(2023, 1, 2), ..., date(2023, 1, 8))
        ```
        """
        return tuple(self.to_date(weekday) for weekday in range(1, 8))

    def nth(self: Self, n: int) -> date:
        """Returns Nth day of the week using the ISO weekday numbering convention (1=First, 2=Second, ..., 7=Last day).

        !!! info
            Weekday is not the same as the day of the week. The weekday is an integer between 1 and 7.

        Arguments:
            n: Day number between 1 and 7.

        Returns:
            `date` object representing the Nth day of the week.

        Raises:
            TypeError: If `n` is not an integer.
            ValueError: If `n` is not between 1 and 7.

        Examples:
        ```py
        from iso_week_date import IsoWeek

        IsoWeek("2023-W01").nth(1)  # date(2023, 1, 2)
        IsoWeek("2023-W01").nth(7)  # date(2023, 1, 8)
        ```
        """
        if not isinstance(n, int):
            msg = f"`n` must be an integer, found {type(n)}"
            raise TypeError(msg)
        if n not in range(1, 8):
            msg = f"`n` must be between 1 and 7, found {n}"
            raise ValueError(msg)

        return self.days[n - 1]

    def to_datetime(self: Self, weekday: int = 1) -> datetime:
        """Converts `IsoWeek` to `datetime` object with the given weekday.

        If no weekday is provided then the first day of the week is used.

        !!! info
            Weekday is not the same as the day of the week. The weekday is an integer between 1 and 7.

        Arguments:
            weekday: Weekday to use. It must be an integer between 1 and 7, where 1 is the first day of the week and 7
                is the last day of the week.

        Returns:
            `IsoWeek` value in `datetime` type with the given weekday.

        Raises:
            TypeError: If `weekday` is not an integer.
            ValueError: If `weekday` is not between 1 and 7.

        Examples:
        ```py
        from iso_week_date import IsoWeek

        IsoWeek("2023-W01").to_datetime()  # datetime.datetime(2023, 1, 2, 0, 0)
        IsoWeek("2023-W01").to_datetime(3)  # datetime.datetime(2023, 1, 4, 0, 0)
        ```
        """
        if not isinstance(weekday, int):
            msg = f"`weekday` must be an integer between 1 and 7, found {type(weekday)}"
            raise TypeError(msg)
        if weekday not in range(1, 8):
            msg = f"Invalid `weekday`. Weekday must be between 1 and 7, found {weekday}"
            raise ValueError(msg)

        return super()._to_datetime(f"{self.value_}-{weekday}")

    def to_date(self: Self, weekday: int = 1) -> date:
        """Converts `IsoWeek` to `date` object with the given `weekday`.

        If no weekday is provided then the first day of the week is used.

        !!! info
            Weekday is not the same as the day of the week. The weekday is an integer between 1 and 7.

        Arguments:
            weekday: Weekday to use. It must be an integer between 1 and 7, where 1 is the first day of the week and 7
                is the last day of the week.

        Returns:
            `IsoWeek` value in `date` type with the given weekday.

        Raises:
            TypeError: If `weekday` is not an integer.
            ValueError: If `weekday` is not between 1 and 7.

        Examples:
        ```py
        from iso_week_date import IsoWeek

        IsoWeek("2023-W01").to_date()  # datetime.date(2023, 1, 2)
        IsoWeek("2023-W01").to_date(3)  # datetime.date(2023, 1, 4)
        ```
        """
        return self.to_datetime(weekday).date()

    @overload
    def __add__(self: Self, other: Union[int, timedelta]) -> Self: ...  # pragma: no cover

    @overload
    def __add__(
        self: Self,
        other: Iterable[Union[int, timedelta]],
    ) -> Generator[Self, None, None]: ...  # pragma: no cover

    @overload
    def __add__(
        self: Self,
        other: Union[int, timedelta, Iterable[Union[int, timedelta]]],
    ) -> Union[Self, Generator[Self, None, None]]: ...  # pragma: no cover

    def __add__(
        self: Self,
        other: Union[int, timedelta, Iterable[Union[int, timedelta]]],
    ) -> Union[Self, Generator[Self, None, None]]:
        """Addition operation.

        It supports addition with the following types:

        - `int`: interpreted as number of weeks to be added to the `IsoWeek` value.
        - `timedelta`: converts `IsoWeek` to datetime (first day of week), adds `timedelta` and converts back to
            `IsoWeek` object.
        - `Iterable` of `int` and/or `timedelta`: adds each element of the iterable to the `IsoWeek` value and returns
            a generator of `IsoWeek` objects.

        Arguments:
            other: Object to add to `IsoWeek`.

        Returns:
            New `IsoWeek` or generator of `IsoWeek` object(s) with the result of the addition.

        Raises:
            TypeError: If `other` is not `int`, `timedelta` or `Iterable` of `int` and/or `timedelta`.

        Examples:
        ```py
        from datetime import timedelta
        from iso_week_date import IsoWeek

        IsoWeek("2023-W01") + 1  # IsoWeek("2023-W02")
        IsoWeek("2023-W01") + timedelta(weeks=2)  # IsoWeek("2023-W03")
        IsoWeek("2023-W01") + timedelta(hours=1234)  # IsoWeek("2023-W08")

        tuple(IsoWeek("2023-W01") + (1, 2, 3))  # (IsoWeek("2023-W02"), IsoWeek("2023-W03"), IsoWeek("2023-W04"))
        ```
        """
        if isinstance(other, int):
            return self.from_date(self.to_date() + timedelta(weeks=other))
        elif isinstance(other, timedelta):
            return self.from_datetime(self.to_datetime() + other)
        elif isinstance(other, Iterable) and all(isinstance(_other, (int, timedelta)) for _other in other):
            return (self + _other for _other in other)
        else:
            msg = (
                f"Cannot add type {type(other)} to `IsoWeek`. "
                "Addition is supported with `int` and `timedelta` types",
            )
            raise TypeError(msg)

    @overload
    def __sub__(self: Self, other: Union[int, timedelta]) -> Self: ...  # pragma: no cover

    @overload
    def __sub__(self: Self, other: Self) -> int: ...  # pragma: no cover

    @overload
    def __sub__(
        self: Self,
        other: Iterable[Union[int, timedelta]],
    ) -> Generator[Self, None, None]: ...  # pragma: no cover

    @overload
    def __sub__(self: Self, other: Iterable[Self]) -> Generator[int, None, None]: ...  # pragma: no cover

    @overload
    def __sub__(
        self: Self,
        other: Union[int, timedelta, Self, Iterable[Union[int, timedelta, Self]]],
    ) -> Union[int, Self, Generator[Union[int, Self], None, None]]: ...  # pragma: no cover

    def __sub__(
        self: Self,
        other: Union[int, timedelta, Self, Iterable[Union[int, timedelta, Self]]],
    ) -> Union[int, Self, Generator[Union[int, Self], None, None]]:
        """Subtraction operation.

        It supports subtraction with the following types:

        - `int`: interpreted as number of weeks to be subtracted to the `IsoWeek` value.
        - `timedelta`: converts `IsoWeek` to datetime (first day of week), subtract `timedelta` and converts back to
            `IsoWeek` object.
        - `IsoWeek`: will result in the difference between values in weeks (`int` type).
        - `Iterable` of `int`, `timedelta` and/or `IsoWeek`: subtracts each element of the iterable to the `IsoWeek`.

        Arguments:
            other: Object to subtract to `IsoWeek`.

        Returns:
            Results from the subtraction, can be `int`, `IsoWeek` or Generator of `int` and/or `IsoWeek` depending
                on the type of `other`.

        Raises:
            TypeError: If `other` is not `int`, `timedelta`, `IsoWeek` or `Iterable` of those types.

        Examples:
        ```py
        from datetime import timedelta
        from iso_week_date import IsoWeek

        IsoWeek("2023-W01") - 1  # IsoWeek("2022-W52")
        IsoWeek("2023-W01") - timedelta(weeks=2)  # IsoWeek("2022-W51")
        IsoWeek("2023-W01") - timedelta(hours=1234)  # IsoWeek("2023-W45")

        tuple(IsoWeek("2023-W01") - (1, 2, 3))
        # (IsoWeek("2022-W52"), IsoWeek("2022-W51"), IsoWeek("2022-W50"))

        IsoWeek("2023-W01") - IsoWeek("2022-W52")  # 1
        IsoWeek("2023-W01") - IsoWeek("2022-W51")  # 2
        ```
        """
        if isinstance(other, int):
            return self.from_date(self.to_date() - timedelta(weeks=other))
        if isinstance(other, timedelta):
            return self.from_datetime(self.to_datetime() - other)
        elif isinstance(other, IsoWeek) and self.offset_ == other.offset_:
            return (self.to_date() - other.to_date()).days // 7
        elif isinstance(other, Iterable) and all(isinstance(_other, (int, timedelta, IsoWeek)) for _other in other):
            return (self - _other for _other in other)
        else:
            msg = (
                f"Cannot subtract type {type(other)} to `IsoWeek`. "
                "Subtraction is supported with `int`, `timedelta` and `IsoWeek` types"
            )
            raise TypeError(msg)

    @overload
    def weeksout(
        self: Self,
        n_weeks: int,
        *,
        step: int = 1,
        as_str: Literal[True],
    ) -> Generator[str, None, None]: ...  # pragma: no cover

    @overload
    def weeksout(
        self: Self,
        n_weeks: int,
        *,
        step: int = 1,
        as_str: Literal[False],
    ) -> Generator[IsoWeek, None, None]: ...  # pragma: no cover

    @overload
    def weeksout(
        self: Self,
        n_weeks: int,
        *,
        step: int = 1,
        as_str: bool = True,
    ) -> Generator[Union[str, IsoWeek], None, None]: ...  # pragma: no cover

    def weeksout(
        self: Self,
        n_weeks: int,
        *,
        step: int = 1,
        as_str: bool = True,
    ) -> Generator[Union[str, IsoWeek], None, None]:
        """Generate range of `IsoWeek` (or `str`) from one to `n_weeks` ahead of current `value`, with given `step`.

        If `as_str` is flagged as `True`, it will return `str` values, otherwise it will return `IsoWeek` objects.

        Arguments:
            n_weeks: Number of weeks to be generated from current value.
            step: Step between weeks, must be positive integer.
            as_str: Whether to return str or IsoWeek object.

        Returns:
            Generator of `IsoWeek`s (or `str`s) from one week to `n_weeks` ahead of current `value` with given `step`.

        Raises:
            TypeError: If `n_weeks` and/or `step` is not int.
            ValueError: If `n_weeks` and/or `step` is not strictly positive.

        Examples:
        ```py
        from iso_week_date import IsoWeek

        iso = IsoWeek("2023-W01")

        tuple(iso.weeksout(4))  # ('2023-W02', '2023-W03', '2023-W04', '2023-W05')
        tuple(iso.weeksout(6, step=2))  # ('2023-W02', '2023-W04', '2023-W06')
        ```
        """
        if not isinstance(n_weeks, int):
            msg = f"`n_weeks` must be an integer, found {type(n_weeks)} type"
            raise TypeError(msg)

        if n_weeks <= 0:
            msg = f"`n_weeks` must be strictly positive, found {n_weeks}"
            raise ValueError(msg)

        start, end = (self + 1), (self + n_weeks)
        return self.range(start, end, step=step, inclusive="both", as_str=as_str)

    def __contains__(self: Self, other: Any) -> bool:  # noqa: ANN401
        """Checks if self contains `other`.

        Arguments:
            other: `IsoWeek`, `date`, `datetime` or `str`.

        Returns:
            `True` if self week contains other, `False` otherwise.

        Raises:
            TypeError: If other is not `IsoWeek`, `date`, `datetime` or `str`.

        Examples:
        ```python
        from datetime import date
        from iso_week_date import IsoWeek

        date(2023, 1, 1) in IsoWeek("2023-W01")  # False
        date(2023, 1, 2) in IsoWeek("2023-W01")  # True
        ```
        """
        if isinstance(other, (date, datetime, str, IsoWeek)):
            _other = self._cast(other)
            return self.__eq__(_other)
        else:
            msg = f"Cannot compare type `{type(other)}` with IsoWeek"
            raise TypeError(msg)

    @overload
    def contains(self: Self, other: Iterable[IsoWeek_T]) -> Tuple[bool]: ...  # pragma: no cover

    @overload
    def contains(self: Self, other: IsoWeek_T) -> bool: ...  # pragma: no cover

    @overload
    def contains(
        self: Self,
        other: Union[Any, Iterable[Any]],  # noqa: ANN401
    ) -> Union[bool, Tuple[bool, ...]]: ...  # pragma: no cover

    def contains(self: Self, other: Union[Any, Iterable[Any]]) -> Union[bool, Tuple[bool, ...]]:
        """Checks if self contains `other`. `other` can be a single value or an iterable of values.

        In case of an iterable, the method returns a tuple of boolean values.

        Arguments:
            other: `IsoWeek`, `date`, `datetime` or `str`, or an iterable of those types.

        Returns:
            Boolean or iterable of booleans, where each boolean indicates whether self contains the corresponding value
                in the iterable.

        Raises:
            TypeError: If other is not IsoWeek, date, datetime or str, or an iterable of those types.

        Examples:
        ```python
        from datetime import date
        from iso_week_date import IsoWeek

        IsoWeek("2023-W01").contains([date(2023, 1, 1), date(2023, 1, 2)])
        # (False, True)
        ```
        """
        if isinstance(other, (date, datetime, str, IsoWeek)):
            return other in self
        elif isinstance(other, Iterable):
            return tuple(_other in self for _other in other)
        else:
            msg = f"Cannot compare type `{type(other)}` with `IsoWeek`"
            raise TypeError(msg)

days: Tuple[date, ...] property

Returns tuple of days (as date) in the ISO week.

Examples:

from iso_week_date import IsoWeek

IsoWeek("2023-W01").days  # (date(2023, 1, 2), ..., date(2023, 1, 8))

__add__(other)

Addition operation.

It supports addition with the following types:

  • int: interpreted as number of weeks to be added to the IsoWeek value.
  • timedelta: converts IsoWeek to datetime (first day of week), adds timedelta and converts back to IsoWeek object.
  • Iterable of int and/or timedelta: adds each element of the iterable to the IsoWeek value and returns a generator of IsoWeek objects.

Parameters:

Name Type Description Default
other Union[int, timedelta, Iterable[Union[int, timedelta]]]

Object to add to IsoWeek.

required

Returns:

Type Description
Union[Self, Generator[Self, None, None]]

New IsoWeek or generator of IsoWeek object(s) with the result of the addition.

Raises:

Type Description
TypeError

If other is not int, timedelta or Iterable of int and/or timedelta.

Examples:

from datetime import timedelta
from iso_week_date import IsoWeek

IsoWeek("2023-W01") + 1  # IsoWeek("2023-W02")
IsoWeek("2023-W01") + timedelta(weeks=2)  # IsoWeek("2023-W03")
IsoWeek("2023-W01") + timedelta(hours=1234)  # IsoWeek("2023-W08")

tuple(IsoWeek("2023-W01") + (1, 2, 3))  # (IsoWeek("2023-W02"), IsoWeek("2023-W03"), IsoWeek("2023-W04"))

Source code in iso_week_date/isoweek.py
def __add__(
    self: Self,
    other: Union[int, timedelta, Iterable[Union[int, timedelta]]],
) -> Union[Self, Generator[Self, None, None]]:
    """Addition operation.

    It supports addition with the following types:

    - `int`: interpreted as number of weeks to be added to the `IsoWeek` value.
    - `timedelta`: converts `IsoWeek` to datetime (first day of week), adds `timedelta` and converts back to
        `IsoWeek` object.
    - `Iterable` of `int` and/or `timedelta`: adds each element of the iterable to the `IsoWeek` value and returns
        a generator of `IsoWeek` objects.

    Arguments:
        other: Object to add to `IsoWeek`.

    Returns:
        New `IsoWeek` or generator of `IsoWeek` object(s) with the result of the addition.

    Raises:
        TypeError: If `other` is not `int`, `timedelta` or `Iterable` of `int` and/or `timedelta`.

    Examples:
    ```py
    from datetime import timedelta
    from iso_week_date import IsoWeek

    IsoWeek("2023-W01") + 1  # IsoWeek("2023-W02")
    IsoWeek("2023-W01") + timedelta(weeks=2)  # IsoWeek("2023-W03")
    IsoWeek("2023-W01") + timedelta(hours=1234)  # IsoWeek("2023-W08")

    tuple(IsoWeek("2023-W01") + (1, 2, 3))  # (IsoWeek("2023-W02"), IsoWeek("2023-W03"), IsoWeek("2023-W04"))
    ```
    """
    if isinstance(other, int):
        return self.from_date(self.to_date() + timedelta(weeks=other))
    elif isinstance(other, timedelta):
        return self.from_datetime(self.to_datetime() + other)
    elif isinstance(other, Iterable) and all(isinstance(_other, (int, timedelta)) for _other in other):
        return (self + _other for _other in other)
    else:
        msg = (
            f"Cannot add type {type(other)} to `IsoWeek`. "
            "Addition is supported with `int` and `timedelta` types",
        )
        raise TypeError(msg)

__contains__(other)

Checks if self contains other.

Parameters:

Name Type Description Default
other Any

IsoWeek, date, datetime or str.

required

Returns:

Type Description
bool

True if self week contains other, False otherwise.

Raises:

Type Description
TypeError

If other is not IsoWeek, date, datetime or str.

Examples:

from datetime import date
from iso_week_date import IsoWeek

date(2023, 1, 1) in IsoWeek("2023-W01")  # False
date(2023, 1, 2) in IsoWeek("2023-W01")  # True

Source code in iso_week_date/isoweek.py
def __contains__(self: Self, other: Any) -> bool:  # noqa: ANN401
    """Checks if self contains `other`.

    Arguments:
        other: `IsoWeek`, `date`, `datetime` or `str`.

    Returns:
        `True` if self week contains other, `False` otherwise.

    Raises:
        TypeError: If other is not `IsoWeek`, `date`, `datetime` or `str`.

    Examples:
    ```python
    from datetime import date
    from iso_week_date import IsoWeek

    date(2023, 1, 1) in IsoWeek("2023-W01")  # False
    date(2023, 1, 2) in IsoWeek("2023-W01")  # True
    ```
    """
    if isinstance(other, (date, datetime, str, IsoWeek)):
        _other = self._cast(other)
        return self.__eq__(_other)
    else:
        msg = f"Cannot compare type `{type(other)}` with IsoWeek"
        raise TypeError(msg)

__sub__(other)

Subtraction operation.

It supports subtraction with the following types:

  • int: interpreted as number of weeks to be subtracted to the IsoWeek value.
  • timedelta: converts IsoWeek to datetime (first day of week), subtract timedelta and converts back to IsoWeek object.
  • IsoWeek: will result in the difference between values in weeks (int type).
  • Iterable of int, timedelta and/or IsoWeek: subtracts each element of the iterable to the IsoWeek.

Parameters:

Name Type Description Default
other Union[int, timedelta, Self, Iterable[Union[int, timedelta, Self]]]

Object to subtract to IsoWeek.

required

Returns:

Type Description
Union[int, Self, Generator[Union[int, Self], None, None]]

Results from the subtraction, can be int, IsoWeek or Generator of int and/or IsoWeek depending on the type of other.

Raises:

Type Description
TypeError

If other is not int, timedelta, IsoWeek or Iterable of those types.

Examples:

from datetime import timedelta
from iso_week_date import IsoWeek

IsoWeek("2023-W01") - 1  # IsoWeek("2022-W52")
IsoWeek("2023-W01") - timedelta(weeks=2)  # IsoWeek("2022-W51")
IsoWeek("2023-W01") - timedelta(hours=1234)  # IsoWeek("2023-W45")

tuple(IsoWeek("2023-W01") - (1, 2, 3))
# (IsoWeek("2022-W52"), IsoWeek("2022-W51"), IsoWeek("2022-W50"))

IsoWeek("2023-W01") - IsoWeek("2022-W52")  # 1
IsoWeek("2023-W01") - IsoWeek("2022-W51")  # 2

Source code in iso_week_date/isoweek.py
def __sub__(
    self: Self,
    other: Union[int, timedelta, Self, Iterable[Union[int, timedelta, Self]]],
) -> Union[int, Self, Generator[Union[int, Self], None, None]]:
    """Subtraction operation.

    It supports subtraction with the following types:

    - `int`: interpreted as number of weeks to be subtracted to the `IsoWeek` value.
    - `timedelta`: converts `IsoWeek` to datetime (first day of week), subtract `timedelta` and converts back to
        `IsoWeek` object.
    - `IsoWeek`: will result in the difference between values in weeks (`int` type).
    - `Iterable` of `int`, `timedelta` and/or `IsoWeek`: subtracts each element of the iterable to the `IsoWeek`.

    Arguments:
        other: Object to subtract to `IsoWeek`.

    Returns:
        Results from the subtraction, can be `int`, `IsoWeek` or Generator of `int` and/or `IsoWeek` depending
            on the type of `other`.

    Raises:
        TypeError: If `other` is not `int`, `timedelta`, `IsoWeek` or `Iterable` of those types.

    Examples:
    ```py
    from datetime import timedelta
    from iso_week_date import IsoWeek

    IsoWeek("2023-W01") - 1  # IsoWeek("2022-W52")
    IsoWeek("2023-W01") - timedelta(weeks=2)  # IsoWeek("2022-W51")
    IsoWeek("2023-W01") - timedelta(hours=1234)  # IsoWeek("2023-W45")

    tuple(IsoWeek("2023-W01") - (1, 2, 3))
    # (IsoWeek("2022-W52"), IsoWeek("2022-W51"), IsoWeek("2022-W50"))

    IsoWeek("2023-W01") - IsoWeek("2022-W52")  # 1
    IsoWeek("2023-W01") - IsoWeek("2022-W51")  # 2
    ```
    """
    if isinstance(other, int):
        return self.from_date(self.to_date() - timedelta(weeks=other))
    if isinstance(other, timedelta):
        return self.from_datetime(self.to_datetime() - other)
    elif isinstance(other, IsoWeek) and self.offset_ == other.offset_:
        return (self.to_date() - other.to_date()).days // 7
    elif isinstance(other, Iterable) and all(isinstance(_other, (int, timedelta, IsoWeek)) for _other in other):
        return (self - _other for _other in other)
    else:
        msg = (
            f"Cannot subtract type {type(other)} to `IsoWeek`. "
            "Subtraction is supported with `int`, `timedelta` and `IsoWeek` types"
        )
        raise TypeError(msg)

contains(other)

Checks if self contains other. other can be a single value or an iterable of values.

In case of an iterable, the method returns a tuple of boolean values.

Parameters:

Name Type Description Default
other Union[Any, Iterable[Any]]

IsoWeek, date, datetime or str, or an iterable of those types.

required

Returns:

Type Description
Union[bool, Tuple[bool, ...]]

Boolean or iterable of booleans, where each boolean indicates whether self contains the corresponding value in the iterable.

Raises:

Type Description
TypeError

If other is not IsoWeek, date, datetime or str, or an iterable of those types.

Examples:

from datetime import date
from iso_week_date import IsoWeek

IsoWeek("2023-W01").contains([date(2023, 1, 1), date(2023, 1, 2)])
# (False, True)

Source code in iso_week_date/isoweek.py
def contains(self: Self, other: Union[Any, Iterable[Any]]) -> Union[bool, Tuple[bool, ...]]:
    """Checks if self contains `other`. `other` can be a single value or an iterable of values.

    In case of an iterable, the method returns a tuple of boolean values.

    Arguments:
        other: `IsoWeek`, `date`, `datetime` or `str`, or an iterable of those types.

    Returns:
        Boolean or iterable of booleans, where each boolean indicates whether self contains the corresponding value
            in the iterable.

    Raises:
        TypeError: If other is not IsoWeek, date, datetime or str, or an iterable of those types.

    Examples:
    ```python
    from datetime import date
    from iso_week_date import IsoWeek

    IsoWeek("2023-W01").contains([date(2023, 1, 1), date(2023, 1, 2)])
    # (False, True)
    ```
    """
    if isinstance(other, (date, datetime, str, IsoWeek)):
        return other in self
    elif isinstance(other, Iterable):
        return tuple(_other in self for _other in other)
    else:
        msg = f"Cannot compare type `{type(other)}` with `IsoWeek`"
        raise TypeError(msg)

nth(n)

Returns Nth day of the week using the ISO weekday numbering convention (1=First, 2=Second, ..., 7=Last day).

Info

Weekday is not the same as the day of the week. The weekday is an integer between 1 and 7.

Parameters:

Name Type Description Default
n int

Day number between 1 and 7.

required

Returns:

Type Description
date

date object representing the Nth day of the week.

Raises:

Type Description
TypeError

If n is not an integer.

ValueError

If n is not between 1 and 7.

Examples:

from iso_week_date import IsoWeek

IsoWeek("2023-W01").nth(1)  # date(2023, 1, 2)
IsoWeek("2023-W01").nth(7)  # date(2023, 1, 8)

Source code in iso_week_date/isoweek.py
def nth(self: Self, n: int) -> date:
    """Returns Nth day of the week using the ISO weekday numbering convention (1=First, 2=Second, ..., 7=Last day).

    !!! info
        Weekday is not the same as the day of the week. The weekday is an integer between 1 and 7.

    Arguments:
        n: Day number between 1 and 7.

    Returns:
        `date` object representing the Nth day of the week.

    Raises:
        TypeError: If `n` is not an integer.
        ValueError: If `n` is not between 1 and 7.

    Examples:
    ```py
    from iso_week_date import IsoWeek

    IsoWeek("2023-W01").nth(1)  # date(2023, 1, 2)
    IsoWeek("2023-W01").nth(7)  # date(2023, 1, 8)
    ```
    """
    if not isinstance(n, int):
        msg = f"`n` must be an integer, found {type(n)}"
        raise TypeError(msg)
    if n not in range(1, 8):
        msg = f"`n` must be between 1 and 7, found {n}"
        raise ValueError(msg)

    return self.days[n - 1]

to_date(weekday=1)

Converts IsoWeek to date object with the given weekday.

If no weekday is provided then the first day of the week is used.

Info

Weekday is not the same as the day of the week. The weekday is an integer between 1 and 7.

Parameters:

Name Type Description Default
weekday int

Weekday to use. It must be an integer between 1 and 7, where 1 is the first day of the week and 7 is the last day of the week.

1

Returns:

Type Description
date

IsoWeek value in date type with the given weekday.

Raises:

Type Description
TypeError

If weekday is not an integer.

ValueError

If weekday is not between 1 and 7.

Examples:

from iso_week_date import IsoWeek

IsoWeek("2023-W01").to_date()  # datetime.date(2023, 1, 2)
IsoWeek("2023-W01").to_date(3)  # datetime.date(2023, 1, 4)

Source code in iso_week_date/isoweek.py
def to_date(self: Self, weekday: int = 1) -> date:
    """Converts `IsoWeek` to `date` object with the given `weekday`.

    If no weekday is provided then the first day of the week is used.

    !!! info
        Weekday is not the same as the day of the week. The weekday is an integer between 1 and 7.

    Arguments:
        weekday: Weekday to use. It must be an integer between 1 and 7, where 1 is the first day of the week and 7
            is the last day of the week.

    Returns:
        `IsoWeek` value in `date` type with the given weekday.

    Raises:
        TypeError: If `weekday` is not an integer.
        ValueError: If `weekday` is not between 1 and 7.

    Examples:
    ```py
    from iso_week_date import IsoWeek

    IsoWeek("2023-W01").to_date()  # datetime.date(2023, 1, 2)
    IsoWeek("2023-W01").to_date(3)  # datetime.date(2023, 1, 4)
    ```
    """
    return self.to_datetime(weekday).date()

to_datetime(weekday=1)

Converts IsoWeek to datetime object with the given weekday.

If no weekday is provided then the first day of the week is used.

Info

Weekday is not the same as the day of the week. The weekday is an integer between 1 and 7.

Parameters:

Name Type Description Default
weekday int

Weekday to use. It must be an integer between 1 and 7, where 1 is the first day of the week and 7 is the last day of the week.

1

Returns:

Type Description
datetime

IsoWeek value in datetime type with the given weekday.

Raises:

Type Description
TypeError

If weekday is not an integer.

ValueError

If weekday is not between 1 and 7.

Examples:

from iso_week_date import IsoWeek

IsoWeek("2023-W01").to_datetime()  # datetime.datetime(2023, 1, 2, 0, 0)
IsoWeek("2023-W01").to_datetime(3)  # datetime.datetime(2023, 1, 4, 0, 0)

Source code in iso_week_date/isoweek.py
def to_datetime(self: Self, weekday: int = 1) -> datetime:
    """Converts `IsoWeek` to `datetime` object with the given weekday.

    If no weekday is provided then the first day of the week is used.

    !!! info
        Weekday is not the same as the day of the week. The weekday is an integer between 1 and 7.

    Arguments:
        weekday: Weekday to use. It must be an integer between 1 and 7, where 1 is the first day of the week and 7
            is the last day of the week.

    Returns:
        `IsoWeek` value in `datetime` type with the given weekday.

    Raises:
        TypeError: If `weekday` is not an integer.
        ValueError: If `weekday` is not between 1 and 7.

    Examples:
    ```py
    from iso_week_date import IsoWeek

    IsoWeek("2023-W01").to_datetime()  # datetime.datetime(2023, 1, 2, 0, 0)
    IsoWeek("2023-W01").to_datetime(3)  # datetime.datetime(2023, 1, 4, 0, 0)
    ```
    """
    if not isinstance(weekday, int):
        msg = f"`weekday` must be an integer between 1 and 7, found {type(weekday)}"
        raise TypeError(msg)
    if weekday not in range(1, 8):
        msg = f"Invalid `weekday`. Weekday must be between 1 and 7, found {weekday}"
        raise ValueError(msg)

    return super()._to_datetime(f"{self.value_}-{weekday}")

weeksout(n_weeks, *, step=1, as_str=True)

Generate range of IsoWeek (or str) from one to n_weeks ahead of current value, with given step.

If as_str is flagged as True, it will return str values, otherwise it will return IsoWeek objects.

Parameters:

Name Type Description Default
n_weeks int

Number of weeks to be generated from current value.

required
step int

Step between weeks, must be positive integer.

1
as_str bool

Whether to return str or IsoWeek object.

True

Returns:

Type Description
None

Generator of IsoWeeks (or strs) from one week to n_weeks ahead of current value with given step.

Raises:

Type Description
TypeError

If n_weeks and/or step is not int.

ValueError

If n_weeks and/or step is not strictly positive.

Examples:

from iso_week_date import IsoWeek

iso = IsoWeek("2023-W01")

tuple(iso.weeksout(4))  # ('2023-W02', '2023-W03', '2023-W04', '2023-W05')
tuple(iso.weeksout(6, step=2))  # ('2023-W02', '2023-W04', '2023-W06')

Source code in iso_week_date/isoweek.py
def weeksout(
    self: Self,
    n_weeks: int,
    *,
    step: int = 1,
    as_str: bool = True,
) -> Generator[Union[str, IsoWeek], None, None]:
    """Generate range of `IsoWeek` (or `str`) from one to `n_weeks` ahead of current `value`, with given `step`.

    If `as_str` is flagged as `True`, it will return `str` values, otherwise it will return `IsoWeek` objects.

    Arguments:
        n_weeks: Number of weeks to be generated from current value.
        step: Step between weeks, must be positive integer.
        as_str: Whether to return str or IsoWeek object.

    Returns:
        Generator of `IsoWeek`s (or `str`s) from one week to `n_weeks` ahead of current `value` with given `step`.

    Raises:
        TypeError: If `n_weeks` and/or `step` is not int.
        ValueError: If `n_weeks` and/or `step` is not strictly positive.

    Examples:
    ```py
    from iso_week_date import IsoWeek

    iso = IsoWeek("2023-W01")

    tuple(iso.weeksout(4))  # ('2023-W02', '2023-W03', '2023-W04', '2023-W05')
    tuple(iso.weeksout(6, step=2))  # ('2023-W02', '2023-W04', '2023-W06')
    ```
    """
    if not isinstance(n_weeks, int):
        msg = f"`n_weeks` must be an integer, found {type(n_weeks)} type"
        raise TypeError(msg)

    if n_weeks <= 0:
        msg = f"`n_weeks` must be strictly positive, found {n_weeks}"
        raise ValueError(msg)

    start, end = (self + 1), (self + n_weeks)
    return self.range(start, end, step=step, inclusive="both", as_str=as_str)