polars-runtime-compat 1.34.0b2__cp39-abi3-manylinux_2_24_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of polars-runtime-compat might be problematic. Click here for more details.

Files changed (203) hide show
  1. _polars_runtime_compat/.gitkeep +0 -0
  2. _polars_runtime_compat/_polars_runtime_compat.abi3.so +0 -0
  3. polars/__init__.py +528 -0
  4. polars/_cpu_check.py +265 -0
  5. polars/_dependencies.py +355 -0
  6. polars/_plr.py +99 -0
  7. polars/_plr.pyi +2496 -0
  8. polars/_reexport.py +23 -0
  9. polars/_typing.py +478 -0
  10. polars/_utils/__init__.py +37 -0
  11. polars/_utils/async_.py +102 -0
  12. polars/_utils/cache.py +176 -0
  13. polars/_utils/cloud.py +40 -0
  14. polars/_utils/constants.py +29 -0
  15. polars/_utils/construction/__init__.py +46 -0
  16. polars/_utils/construction/dataframe.py +1397 -0
  17. polars/_utils/construction/other.py +72 -0
  18. polars/_utils/construction/series.py +560 -0
  19. polars/_utils/construction/utils.py +118 -0
  20. polars/_utils/convert.py +224 -0
  21. polars/_utils/deprecation.py +406 -0
  22. polars/_utils/getitem.py +457 -0
  23. polars/_utils/logging.py +11 -0
  24. polars/_utils/nest_asyncio.py +264 -0
  25. polars/_utils/parquet.py +15 -0
  26. polars/_utils/parse/__init__.py +12 -0
  27. polars/_utils/parse/expr.py +242 -0
  28. polars/_utils/polars_version.py +19 -0
  29. polars/_utils/pycapsule.py +53 -0
  30. polars/_utils/scan.py +27 -0
  31. polars/_utils/serde.py +63 -0
  32. polars/_utils/slice.py +215 -0
  33. polars/_utils/udfs.py +1251 -0
  34. polars/_utils/unstable.py +63 -0
  35. polars/_utils/various.py +782 -0
  36. polars/_utils/wrap.py +25 -0
  37. polars/api.py +370 -0
  38. polars/catalog/__init__.py +0 -0
  39. polars/catalog/unity/__init__.py +19 -0
  40. polars/catalog/unity/client.py +733 -0
  41. polars/catalog/unity/models.py +152 -0
  42. polars/config.py +1571 -0
  43. polars/convert/__init__.py +25 -0
  44. polars/convert/general.py +1046 -0
  45. polars/convert/normalize.py +261 -0
  46. polars/dataframe/__init__.py +5 -0
  47. polars/dataframe/_html.py +186 -0
  48. polars/dataframe/frame.py +12582 -0
  49. polars/dataframe/group_by.py +1067 -0
  50. polars/dataframe/plotting.py +257 -0
  51. polars/datatype_expr/__init__.py +5 -0
  52. polars/datatype_expr/array.py +56 -0
  53. polars/datatype_expr/datatype_expr.py +304 -0
  54. polars/datatype_expr/list.py +18 -0
  55. polars/datatype_expr/struct.py +69 -0
  56. polars/datatypes/__init__.py +122 -0
  57. polars/datatypes/_parse.py +195 -0
  58. polars/datatypes/_utils.py +48 -0
  59. polars/datatypes/classes.py +1213 -0
  60. polars/datatypes/constants.py +11 -0
  61. polars/datatypes/constructor.py +172 -0
  62. polars/datatypes/convert.py +366 -0
  63. polars/datatypes/group.py +130 -0
  64. polars/exceptions.py +230 -0
  65. polars/expr/__init__.py +7 -0
  66. polars/expr/array.py +964 -0
  67. polars/expr/binary.py +346 -0
  68. polars/expr/categorical.py +306 -0
  69. polars/expr/datetime.py +2620 -0
  70. polars/expr/expr.py +11272 -0
  71. polars/expr/list.py +1408 -0
  72. polars/expr/meta.py +444 -0
  73. polars/expr/name.py +321 -0
  74. polars/expr/string.py +3045 -0
  75. polars/expr/struct.py +357 -0
  76. polars/expr/whenthen.py +185 -0
  77. polars/functions/__init__.py +193 -0
  78. polars/functions/aggregation/__init__.py +33 -0
  79. polars/functions/aggregation/horizontal.py +298 -0
  80. polars/functions/aggregation/vertical.py +341 -0
  81. polars/functions/as_datatype.py +848 -0
  82. polars/functions/business.py +138 -0
  83. polars/functions/col.py +384 -0
  84. polars/functions/datatype.py +121 -0
  85. polars/functions/eager.py +524 -0
  86. polars/functions/escape_regex.py +29 -0
  87. polars/functions/lazy.py +2751 -0
  88. polars/functions/len.py +68 -0
  89. polars/functions/lit.py +210 -0
  90. polars/functions/random.py +22 -0
  91. polars/functions/range/__init__.py +19 -0
  92. polars/functions/range/_utils.py +15 -0
  93. polars/functions/range/date_range.py +303 -0
  94. polars/functions/range/datetime_range.py +370 -0
  95. polars/functions/range/int_range.py +348 -0
  96. polars/functions/range/linear_space.py +311 -0
  97. polars/functions/range/time_range.py +287 -0
  98. polars/functions/repeat.py +301 -0
  99. polars/functions/whenthen.py +353 -0
  100. polars/interchange/__init__.py +10 -0
  101. polars/interchange/buffer.py +77 -0
  102. polars/interchange/column.py +190 -0
  103. polars/interchange/dataframe.py +230 -0
  104. polars/interchange/from_dataframe.py +328 -0
  105. polars/interchange/protocol.py +303 -0
  106. polars/interchange/utils.py +170 -0
  107. polars/io/__init__.py +64 -0
  108. polars/io/_utils.py +317 -0
  109. polars/io/avro.py +49 -0
  110. polars/io/clipboard.py +36 -0
  111. polars/io/cloud/__init__.py +17 -0
  112. polars/io/cloud/_utils.py +80 -0
  113. polars/io/cloud/credential_provider/__init__.py +17 -0
  114. polars/io/cloud/credential_provider/_builder.py +520 -0
  115. polars/io/cloud/credential_provider/_providers.py +618 -0
  116. polars/io/csv/__init__.py +9 -0
  117. polars/io/csv/_utils.py +38 -0
  118. polars/io/csv/batched_reader.py +142 -0
  119. polars/io/csv/functions.py +1495 -0
  120. polars/io/database/__init__.py +6 -0
  121. polars/io/database/_arrow_registry.py +70 -0
  122. polars/io/database/_cursor_proxies.py +147 -0
  123. polars/io/database/_executor.py +578 -0
  124. polars/io/database/_inference.py +314 -0
  125. polars/io/database/_utils.py +144 -0
  126. polars/io/database/functions.py +516 -0
  127. polars/io/delta.py +499 -0
  128. polars/io/iceberg/__init__.py +3 -0
  129. polars/io/iceberg/_utils.py +697 -0
  130. polars/io/iceberg/dataset.py +556 -0
  131. polars/io/iceberg/functions.py +151 -0
  132. polars/io/ipc/__init__.py +8 -0
  133. polars/io/ipc/functions.py +514 -0
  134. polars/io/json/__init__.py +3 -0
  135. polars/io/json/read.py +101 -0
  136. polars/io/ndjson.py +332 -0
  137. polars/io/parquet/__init__.py +17 -0
  138. polars/io/parquet/field_overwrites.py +140 -0
  139. polars/io/parquet/functions.py +722 -0
  140. polars/io/partition.py +491 -0
  141. polars/io/plugins.py +187 -0
  142. polars/io/pyarrow_dataset/__init__.py +5 -0
  143. polars/io/pyarrow_dataset/anonymous_scan.py +109 -0
  144. polars/io/pyarrow_dataset/functions.py +79 -0
  145. polars/io/scan_options/__init__.py +5 -0
  146. polars/io/scan_options/_options.py +59 -0
  147. polars/io/scan_options/cast_options.py +126 -0
  148. polars/io/spreadsheet/__init__.py +6 -0
  149. polars/io/spreadsheet/_utils.py +52 -0
  150. polars/io/spreadsheet/_write_utils.py +647 -0
  151. polars/io/spreadsheet/functions.py +1323 -0
  152. polars/lazyframe/__init__.py +9 -0
  153. polars/lazyframe/engine_config.py +61 -0
  154. polars/lazyframe/frame.py +8564 -0
  155. polars/lazyframe/group_by.py +669 -0
  156. polars/lazyframe/in_process.py +42 -0
  157. polars/lazyframe/opt_flags.py +333 -0
  158. polars/meta/__init__.py +14 -0
  159. polars/meta/build.py +33 -0
  160. polars/meta/index_type.py +27 -0
  161. polars/meta/thread_pool.py +50 -0
  162. polars/meta/versions.py +120 -0
  163. polars/ml/__init__.py +0 -0
  164. polars/ml/torch.py +213 -0
  165. polars/ml/utilities.py +30 -0
  166. polars/plugins.py +155 -0
  167. polars/py.typed +0 -0
  168. polars/pyproject.toml +96 -0
  169. polars/schema.py +265 -0
  170. polars/selectors.py +3117 -0
  171. polars/series/__init__.py +5 -0
  172. polars/series/array.py +776 -0
  173. polars/series/binary.py +254 -0
  174. polars/series/categorical.py +246 -0
  175. polars/series/datetime.py +2275 -0
  176. polars/series/list.py +1087 -0
  177. polars/series/plotting.py +191 -0
  178. polars/series/series.py +9197 -0
  179. polars/series/string.py +2367 -0
  180. polars/series/struct.py +154 -0
  181. polars/series/utils.py +191 -0
  182. polars/sql/__init__.py +7 -0
  183. polars/sql/context.py +677 -0
  184. polars/sql/functions.py +139 -0
  185. polars/string_cache.py +185 -0
  186. polars/testing/__init__.py +13 -0
  187. polars/testing/asserts/__init__.py +9 -0
  188. polars/testing/asserts/frame.py +231 -0
  189. polars/testing/asserts/series.py +219 -0
  190. polars/testing/asserts/utils.py +12 -0
  191. polars/testing/parametric/__init__.py +33 -0
  192. polars/testing/parametric/profiles.py +107 -0
  193. polars/testing/parametric/strategies/__init__.py +22 -0
  194. polars/testing/parametric/strategies/_utils.py +14 -0
  195. polars/testing/parametric/strategies/core.py +615 -0
  196. polars/testing/parametric/strategies/data.py +452 -0
  197. polars/testing/parametric/strategies/dtype.py +436 -0
  198. polars/testing/parametric/strategies/legacy.py +169 -0
  199. polars/type_aliases.py +24 -0
  200. polars_runtime_compat-1.34.0b2.dist-info/METADATA +190 -0
  201. polars_runtime_compat-1.34.0b2.dist-info/RECORD +203 -0
  202. polars_runtime_compat-1.34.0b2.dist-info/WHEEL +4 -0
  203. polars_runtime_compat-1.34.0b2.dist-info/licenses/LICENSE +20 -0
@@ -0,0 +1,2620 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime as dt
4
+ from typing import TYPE_CHECKING
5
+
6
+ import polars._reexport as pl
7
+ from polars import functions as F
8
+ from polars._utils.convert import parse_as_duration_string
9
+ from polars._utils.deprecation import deprecate_nonkeyword_arguments, deprecated
10
+ from polars._utils.parse import parse_into_expression, parse_into_list_of_expressions
11
+ from polars._utils.unstable import unstable
12
+ from polars._utils.various import qualified_type_name
13
+ from polars._utils.wrap import wrap_expr
14
+ from polars.datatypes import DTYPE_TEMPORAL_UNITS, Date, Int32, Int64
15
+
16
+ if TYPE_CHECKING:
17
+ import sys
18
+ from collections.abc import Iterable
19
+
20
+ from polars import Expr
21
+ from polars._typing import (
22
+ Ambiguous,
23
+ EpochTimeUnit,
24
+ IntoExpr,
25
+ IntoExprColumn,
26
+ NonExistent,
27
+ Roll,
28
+ TimeUnit,
29
+ )
30
+
31
+ if sys.version_info >= (3, 13):
32
+ from warnings import deprecated
33
+ else:
34
+ from typing_extensions import deprecated # noqa: TC004
35
+
36
+
37
+ class ExprDateTimeNameSpace:
38
+ """Namespace for datetime related expressions."""
39
+
40
+ _accessor = "dt"
41
+
42
+ def __init__(self, expr: Expr) -> None:
43
+ self._pyexpr = expr._pyexpr
44
+
45
+ @unstable()
46
+ @deprecate_nonkeyword_arguments(allowed_args=["self", "n"], version="1.12.0")
47
+ def add_business_days(
48
+ self,
49
+ n: int | IntoExpr,
50
+ week_mask: Iterable[bool] = (True, True, True, True, True, False, False),
51
+ holidays: Iterable[dt.date] = (),
52
+ roll: Roll = "raise",
53
+ ) -> Expr:
54
+ """
55
+ Offset by `n` business days.
56
+
57
+ .. warning::
58
+ This functionality is considered **unstable**. It may be changed
59
+ at any point without it being considered a breaking change.
60
+
61
+ .. versionchanged:: 1.12.0
62
+ Parameters after `n` should now be passed as keyword arguments.
63
+
64
+ Parameters
65
+ ----------
66
+ n
67
+ Number of business days to offset by. Can be a single number of an
68
+ expression.
69
+ week_mask
70
+ Which days of the week to count. The default is Monday to Friday.
71
+ If you wanted to count only Monday to Thursday, you would pass
72
+ `(True, True, True, True, False, False, False)`.
73
+ holidays
74
+ Holidays to exclude from the count. The Python package
75
+ `python-holidays <https://github.com/vacanza/python-holidays>`_
76
+ may come in handy here. You can install it with ``pip install holidays``,
77
+ and then, to get all Dutch holidays for years 2020-2024:
78
+
79
+ .. code-block:: python
80
+
81
+ import holidays
82
+
83
+ my_holidays = holidays.country_holidays("NL", years=range(2020, 2025))
84
+
85
+ and pass `holidays=my_holidays` when you call `add_business_days`.
86
+ roll
87
+ What to do when the start date lands on a non-business day. Options are:
88
+
89
+ - `'raise'`: raise an error
90
+ - `'forward'`: move to the next business day
91
+ - `'backward'`: move to the previous business day
92
+
93
+ Returns
94
+ -------
95
+ Expr
96
+ Data type is preserved.
97
+
98
+ Examples
99
+ --------
100
+ >>> from datetime import date
101
+ >>> df = pl.DataFrame({"start": [date(2020, 1, 1), date(2020, 1, 2)]})
102
+ >>> df.with_columns(result=pl.col("start").dt.add_business_days(5))
103
+ shape: (2, 2)
104
+ ┌────────────┬────────────┐
105
+ │ start ┆ result │
106
+ │ --- ┆ --- │
107
+ │ date ┆ date │
108
+ ╞════════════╪════════════╡
109
+ │ 2020-01-01 ┆ 2020-01-08 │
110
+ │ 2020-01-02 ┆ 2020-01-09 │
111
+ └────────────┴────────────┘
112
+
113
+ You can pass a custom weekend - for example, if you only take Sunday off:
114
+
115
+ >>> week_mask = (True, True, True, True, True, True, False)
116
+ >>> df.with_columns(
117
+ ... result=pl.col("start").dt.add_business_days(5, week_mask=week_mask)
118
+ ... )
119
+ shape: (2, 2)
120
+ ┌────────────┬────────────┐
121
+ │ start ┆ result │
122
+ │ --- ┆ --- │
123
+ │ date ┆ date │
124
+ ╞════════════╪════════════╡
125
+ │ 2020-01-01 ┆ 2020-01-07 │
126
+ │ 2020-01-02 ┆ 2020-01-08 │
127
+ └────────────┴────────────┘
128
+
129
+ You can also pass a list of holidays:
130
+
131
+ >>> from datetime import date
132
+ >>> holidays = [date(2020, 1, 3), date(2020, 1, 6)]
133
+ >>> df.with_columns(
134
+ ... result=pl.col("start").dt.add_business_days(5, holidays=holidays)
135
+ ... )
136
+ shape: (2, 2)
137
+ ┌────────────┬────────────┐
138
+ │ start ┆ result │
139
+ │ --- ┆ --- │
140
+ │ date ┆ date │
141
+ ╞════════════╪════════════╡
142
+ │ 2020-01-01 ┆ 2020-01-10 │
143
+ │ 2020-01-02 ┆ 2020-01-13 │
144
+ └────────────┴────────────┘
145
+
146
+ Roll all dates forwards to the next business day:
147
+
148
+ >>> df = pl.DataFrame({"start": [date(2020, 1, 5), date(2020, 1, 6)]})
149
+ >>> df.with_columns(
150
+ ... rolled_forwards=pl.col("start").dt.add_business_days(0, roll="forward")
151
+ ... )
152
+ shape: (2, 2)
153
+ ┌────────────┬─────────────────┐
154
+ │ start ┆ rolled_forwards │
155
+ │ --- ┆ --- │
156
+ │ date ┆ date │
157
+ ╞════════════╪═════════════════╡
158
+ │ 2020-01-05 ┆ 2020-01-06 │
159
+ │ 2020-01-06 ┆ 2020-01-06 │
160
+ └────────────┴─────────────────┘
161
+ """
162
+ n_pyexpr = parse_into_expression(n)
163
+ unix_epoch = dt.date(1970, 1, 1)
164
+ return wrap_expr(
165
+ self._pyexpr.dt_add_business_days(
166
+ n_pyexpr,
167
+ list(week_mask),
168
+ [(holiday - unix_epoch).days for holiday in holidays],
169
+ roll,
170
+ )
171
+ )
172
+
173
+ def truncate(self, every: str | dt.timedelta | Expr) -> Expr:
174
+ """
175
+ Divide the date/datetime range into buckets.
176
+
177
+ Each date/datetime is mapped to the start of its bucket using the corresponding
178
+ local datetime. Note that:
179
+
180
+ - Weekly buckets start on Monday.
181
+ - All other buckets start on the Unix epoch (1970-01-01).
182
+ - Ambiguous results are localised using the DST offset of the original
183
+ timestamp - for example, truncating `'2022-11-06 01:30:00 CST'` by
184
+ `'1h'` results in `'2022-11-06 01:00:00 CST'`, whereas truncating
185
+ `'2022-11-06 01:30:00 CDT'` by `'1h'` results in
186
+ `'2022-11-06 01:00:00 CDT'`.
187
+
188
+ Parameters
189
+ ----------
190
+ every
191
+ The size of each bucket.
192
+
193
+ Notes
194
+ -----
195
+ The `every` argument is created with
196
+ the following string language:
197
+
198
+ - 1ns (1 nanosecond)
199
+ - 1us (1 microsecond)
200
+ - 1ms (1 millisecond)
201
+ - 1s (1 second)
202
+ - 1m (1 minute)
203
+ - 1h (1 hour)
204
+ - 1d (1 calendar day)
205
+ - 1w (1 calendar week)
206
+ - 1mo (1 calendar month)
207
+ - 1q (1 calendar quarter)
208
+ - 1y (1 calendar year)
209
+
210
+ By "calendar day", we mean the corresponding time on the next day (which may
211
+ not be 24 hours, due to daylight savings). Similarly for "calendar week",
212
+ "calendar month", "calendar quarter", and "calendar year".
213
+
214
+ Returns
215
+ -------
216
+ Expr
217
+ Expression of data type :class:`Date` or :class:`Datetime`.
218
+
219
+ Examples
220
+ --------
221
+ >>> from datetime import timedelta, datetime
222
+ >>> df = (
223
+ ... pl.datetime_range(
224
+ ... datetime(2001, 1, 1),
225
+ ... datetime(2001, 1, 2),
226
+ ... timedelta(minutes=225),
227
+ ... eager=True,
228
+ ... )
229
+ ... .alias("datetime")
230
+ ... .to_frame()
231
+ ... )
232
+ >>> df
233
+ shape: (7, 1)
234
+ ┌─────────────────────┐
235
+ │ datetime │
236
+ │ --- │
237
+ │ datetime[μs] │
238
+ ╞═════════════════════╡
239
+ │ 2001-01-01 00:00:00 │
240
+ │ 2001-01-01 03:45:00 │
241
+ │ 2001-01-01 07:30:00 │
242
+ │ 2001-01-01 11:15:00 │
243
+ │ 2001-01-01 15:00:00 │
244
+ │ 2001-01-01 18:45:00 │
245
+ │ 2001-01-01 22:30:00 │
246
+ └─────────────────────┘
247
+ >>> df.select(pl.col("datetime").dt.truncate("1h"))
248
+ shape: (7, 1)
249
+ ┌─────────────────────┐
250
+ │ datetime │
251
+ │ --- │
252
+ │ datetime[μs] │
253
+ ╞═════════════════════╡
254
+ │ 2001-01-01 00:00:00 │
255
+ │ 2001-01-01 03:00:00 │
256
+ │ 2001-01-01 07:00:00 │
257
+ │ 2001-01-01 11:00:00 │
258
+ │ 2001-01-01 15:00:00 │
259
+ │ 2001-01-01 18:00:00 │
260
+ │ 2001-01-01 22:00:00 │
261
+ └─────────────────────┘
262
+ >>> truncate_str = df.select(pl.col("datetime").dt.truncate("1h"))
263
+ >>> truncate_td = df.select(pl.col("datetime").dt.truncate(timedelta(hours=1)))
264
+ >>> truncate_str.equals(truncate_td)
265
+ True
266
+
267
+ >>> df = (
268
+ ... pl.datetime_range(
269
+ ... datetime(2001, 1, 1), datetime(2001, 1, 1, 1), "10m", eager=True
270
+ ... )
271
+ ... .alias("datetime")
272
+ ... .to_frame()
273
+ ... )
274
+ >>> df.select(
275
+ ... "datetime", pl.col("datetime").dt.truncate("30m").alias("truncate")
276
+ ... )
277
+ shape: (7, 2)
278
+ ┌─────────────────────┬─────────────────────┐
279
+ │ datetime ┆ truncate │
280
+ │ --- ┆ --- │
281
+ │ datetime[μs] ┆ datetime[μs] │
282
+ ╞═════════════════════╪═════════════════════╡
283
+ │ 2001-01-01 00:00:00 ┆ 2001-01-01 00:00:00 │
284
+ │ 2001-01-01 00:10:00 ┆ 2001-01-01 00:00:00 │
285
+ │ 2001-01-01 00:20:00 ┆ 2001-01-01 00:00:00 │
286
+ │ 2001-01-01 00:30:00 ┆ 2001-01-01 00:30:00 │
287
+ │ 2001-01-01 00:40:00 ┆ 2001-01-01 00:30:00 │
288
+ │ 2001-01-01 00:50:00 ┆ 2001-01-01 00:30:00 │
289
+ │ 2001-01-01 01:00:00 ┆ 2001-01-01 01:00:00 │
290
+ └─────────────────────┴─────────────────────┘
291
+ """
292
+ if isinstance(every, dt.timedelta):
293
+ every = parse_as_duration_string(every)
294
+ every_pyexpr = parse_into_expression(every, str_as_lit=True)
295
+ return wrap_expr(self._pyexpr.dt_truncate(every_pyexpr))
296
+
297
+ def round(self, every: str | dt.timedelta | IntoExprColumn) -> Expr:
298
+ """
299
+ Divide the date/datetime range into buckets.
300
+
301
+ - Each date/datetime in the first half of the interval
302
+ is mapped to the start of its bucket.
303
+ - Each date/datetime in the second half of the interval
304
+ is mapped to the end of its bucket.
305
+ - Half-way points are mapped to the start of their bucket.
306
+
307
+ Ambiguous results are localised using the DST offset of the original timestamp -
308
+ for example, rounding `'2022-11-06 01:20:00 CST'` by `'1h'` results in
309
+ `'2022-11-06 01:00:00 CST'`, whereas rounding `'2022-11-06 01:20:00 CDT'` by
310
+ `'1h'` results in `'2022-11-06 01:00:00 CDT'`.
311
+
312
+ Parameters
313
+ ----------
314
+ every
315
+ Every interval start and period length
316
+
317
+ Returns
318
+ -------
319
+ Expr
320
+ Expression of data type :class:`Date` or :class:`Datetime`.
321
+
322
+ Notes
323
+ -----
324
+ The `every` argument is created with
325
+ the following small string formatting language:
326
+
327
+ - 1ns (1 nanosecond)
328
+ - 1us (1 microsecond)
329
+ - 1ms (1 millisecond)
330
+ - 1s (1 second)
331
+ - 1m (1 minute)
332
+ - 1h (1 hour)
333
+ - 1d (1 calendar day)
334
+ - 1w (1 calendar week)
335
+ - 1mo (1 calendar month)
336
+ - 1q (1 calendar quarter)
337
+ - 1y (1 calendar year)
338
+
339
+ By "calendar day", we mean the corresponding time on the next day (which may
340
+ not be 24 hours, due to daylight savings). Similarly for "calendar week",
341
+ "calendar month", "calendar quarter", and "calendar year".
342
+
343
+ Examples
344
+ --------
345
+ >>> from datetime import timedelta, datetime
346
+ >>> df = (
347
+ ... pl.datetime_range(
348
+ ... datetime(2001, 1, 1),
349
+ ... datetime(2001, 1, 2),
350
+ ... timedelta(minutes=225),
351
+ ... eager=True,
352
+ ... )
353
+ ... .alias("datetime")
354
+ ... .to_frame()
355
+ ... )
356
+ >>> df.with_columns(pl.col("datetime").dt.round("1h").alias("round"))
357
+ shape: (7, 2)
358
+ ┌─────────────────────┬─────────────────────┐
359
+ │ datetime ┆ round │
360
+ │ --- ┆ --- │
361
+ │ datetime[μs] ┆ datetime[μs] │
362
+ ╞═════════════════════╪═════════════════════╡
363
+ │ 2001-01-01 00:00:00 ┆ 2001-01-01 00:00:00 │
364
+ │ 2001-01-01 03:45:00 ┆ 2001-01-01 04:00:00 │
365
+ │ 2001-01-01 07:30:00 ┆ 2001-01-01 08:00:00 │
366
+ │ 2001-01-01 11:15:00 ┆ 2001-01-01 11:00:00 │
367
+ │ 2001-01-01 15:00:00 ┆ 2001-01-01 15:00:00 │
368
+ │ 2001-01-01 18:45:00 ┆ 2001-01-01 19:00:00 │
369
+ │ 2001-01-01 22:30:00 ┆ 2001-01-01 23:00:00 │
370
+ └─────────────────────┴─────────────────────┘
371
+
372
+ >>> df = (
373
+ ... pl.datetime_range(
374
+ ... datetime(2001, 1, 1), datetime(2001, 1, 1, 1), "10m", eager=True
375
+ ... )
376
+ ... .alias("datetime")
377
+ ... .to_frame()
378
+ ... )
379
+ >>> df.with_columns(pl.col("datetime").dt.round("30m").alias("round"))
380
+ shape: (7, 2)
381
+ ┌─────────────────────┬─────────────────────┐
382
+ │ datetime ┆ round │
383
+ │ --- ┆ --- │
384
+ │ datetime[μs] ┆ datetime[μs] │
385
+ ╞═════════════════════╪═════════════════════╡
386
+ │ 2001-01-01 00:00:00 ┆ 2001-01-01 00:00:00 │
387
+ │ 2001-01-01 00:10:00 ┆ 2001-01-01 00:00:00 │
388
+ │ 2001-01-01 00:20:00 ┆ 2001-01-01 00:30:00 │
389
+ │ 2001-01-01 00:30:00 ┆ 2001-01-01 00:30:00 │
390
+ │ 2001-01-01 00:40:00 ┆ 2001-01-01 00:30:00 │
391
+ │ 2001-01-01 00:50:00 ┆ 2001-01-01 01:00:00 │
392
+ │ 2001-01-01 01:00:00 ┆ 2001-01-01 01:00:00 │
393
+ └─────────────────────┴─────────────────────┘
394
+ """
395
+ if isinstance(every, dt.timedelta):
396
+ every = parse_as_duration_string(every)
397
+ every_pyexpr = parse_into_expression(every, str_as_lit=True)
398
+ return wrap_expr(self._pyexpr.dt_round(every_pyexpr))
399
+
400
+ def replace(
401
+ self,
402
+ *,
403
+ year: int | IntoExpr | None = None,
404
+ month: int | IntoExpr | None = None,
405
+ day: int | IntoExpr | None = None,
406
+ hour: int | IntoExpr | None = None,
407
+ minute: int | IntoExpr | None = None,
408
+ second: int | IntoExpr | None = None,
409
+ microsecond: int | IntoExpr | None = None,
410
+ ambiguous: Ambiguous | Expr = "raise",
411
+ ) -> Expr:
412
+ """
413
+ Replace time unit.
414
+
415
+ Parameters
416
+ ----------
417
+ year
418
+ Column or literal.
419
+ month
420
+ Column or literal, ranging from 1-12.
421
+ day
422
+ Column or literal, ranging from 1-31.
423
+ hour
424
+ Column or literal, ranging from 0-23.
425
+ minute
426
+ Column or literal, ranging from 0-59.
427
+ second
428
+ Column or literal, ranging from 0-59.
429
+ microsecond
430
+ Column or literal, ranging from 0-999999.
431
+ ambiguous
432
+ Determine how to deal with ambiguous datetimes:
433
+
434
+ - `'raise'` (default): raise
435
+ - `'earliest'`: use the earliest datetime
436
+ - `'latest'`: use the latest datetime
437
+ - `'null'`: set to null
438
+
439
+ Returns
440
+ -------
441
+ Expr
442
+ Expression of data type :class:`Date` or :class:`Datetime` with the
443
+ specified time units replaced.
444
+
445
+ Examples
446
+ --------
447
+ >>> from datetime import date
448
+ >>> df = pl.DataFrame(
449
+ ... {
450
+ ... "date": [date(2024, 4, 1), date(2025, 3, 16)],
451
+ ... "new_day": [10, 15],
452
+ ... }
453
+ ... )
454
+ >>> df.with_columns(pl.col("date").dt.replace(day="new_day").alias("replaced"))
455
+ shape: (2, 3)
456
+ ┌────────────┬─────────┬────────────┐
457
+ │ date ┆ new_day ┆ replaced │
458
+ │ --- ┆ --- ┆ --- │
459
+ │ date ┆ i64 ┆ date │
460
+ ╞════════════╪═════════╪════════════╡
461
+ │ 2024-04-01 ┆ 10 ┆ 2024-04-10 │
462
+ │ 2025-03-16 ┆ 15 ┆ 2025-03-15 │
463
+ └────────────┴─────────┴────────────┘
464
+ >>> df.with_columns(pl.col("date").dt.replace(year=1800).alias("replaced"))
465
+ shape: (2, 3)
466
+ ┌────────────┬─────────┬────────────┐
467
+ │ date ┆ new_day ┆ replaced │
468
+ │ --- ┆ --- ┆ --- │
469
+ │ date ┆ i64 ┆ date │
470
+ ╞════════════╪═════════╪════════════╡
471
+ │ 2024-04-01 ┆ 10 ┆ 1800-04-01 │
472
+ │ 2025-03-16 ┆ 15 ┆ 1800-03-16 │
473
+ └────────────┴─────────┴────────────┘
474
+ """
475
+ (
476
+ day_pyexpr,
477
+ month_pyexpr,
478
+ year_pyexpr,
479
+ hour_pyexpr,
480
+ minute_pyexpr,
481
+ second_pyexpr,
482
+ microsecond_pyexpr,
483
+ ) = parse_into_list_of_expressions(
484
+ day, month, year, hour, minute, second, microsecond
485
+ )
486
+ ambiguous_expr = parse_into_expression(ambiguous, str_as_lit=True)
487
+ return wrap_expr(
488
+ self._pyexpr.dt_replace(
489
+ year_pyexpr,
490
+ month_pyexpr,
491
+ day_pyexpr,
492
+ hour_pyexpr,
493
+ minute_pyexpr,
494
+ second_pyexpr,
495
+ microsecond_pyexpr,
496
+ ambiguous_expr,
497
+ )
498
+ )
499
+
500
+ def combine(self, time: dt.time | Expr, time_unit: TimeUnit = "us") -> Expr:
501
+ """
502
+ Create a naive Datetime from an existing Date/Datetime expression and a Time.
503
+
504
+ If the underlying expression is a Datetime then its time component is replaced,
505
+ and if it is a Date then a new Datetime is created by combining the two values.
506
+
507
+ Parameters
508
+ ----------
509
+ time
510
+ A python time literal or polars expression/column that resolves to a time.
511
+ time_unit : {'ns', 'us', 'ms'}
512
+ Unit of time.
513
+
514
+ Examples
515
+ --------
516
+ >>> from datetime import datetime, date, time
517
+ >>> df = pl.DataFrame(
518
+ ... {
519
+ ... "dtm": [
520
+ ... datetime(2022, 12, 31, 10, 30, 45),
521
+ ... datetime(2023, 7, 5, 23, 59, 59),
522
+ ... ],
523
+ ... "dt": [date(2022, 10, 10), date(2022, 7, 5)],
524
+ ... "tm": [time(1, 2, 3, 456000), time(7, 8, 9, 101000)],
525
+ ... }
526
+ ... )
527
+ >>> df
528
+ shape: (2, 3)
529
+ ┌─────────────────────┬────────────┬──────────────┐
530
+ │ dtm ┆ dt ┆ tm │
531
+ │ --- ┆ --- ┆ --- │
532
+ │ datetime[μs] ┆ date ┆ time │
533
+ ╞═════════════════════╪════════════╪══════════════╡
534
+ │ 2022-12-31 10:30:45 ┆ 2022-10-10 ┆ 01:02:03.456 │
535
+ │ 2023-07-05 23:59:59 ┆ 2022-07-05 ┆ 07:08:09.101 │
536
+ └─────────────────────┴────────────┴──────────────┘
537
+ >>> df.select(
538
+ ... [
539
+ ... pl.col("dtm").dt.combine(pl.col("tm")).alias("d1"),
540
+ ... pl.col("dt").dt.combine(pl.col("tm")).alias("d2"),
541
+ ... pl.col("dt").dt.combine(time(4, 5, 6)).alias("d3"),
542
+ ... ]
543
+ ... )
544
+ shape: (2, 3)
545
+ ┌─────────────────────────┬─────────────────────────┬─────────────────────┐
546
+ │ d1 ┆ d2 ┆ d3 │
547
+ │ --- ┆ --- ┆ --- │
548
+ │ datetime[μs] ┆ datetime[μs] ┆ datetime[μs] │
549
+ ╞═════════════════════════╪═════════════════════════╪═════════════════════╡
550
+ │ 2022-12-31 01:02:03.456 ┆ 2022-10-10 01:02:03.456 ┆ 2022-10-10 04:05:06 │
551
+ │ 2023-07-05 07:08:09.101 ┆ 2022-07-05 07:08:09.101 ┆ 2022-07-05 04:05:06 │
552
+ └─────────────────────────┴─────────────────────────┴─────────────────────┘
553
+ """
554
+ if not isinstance(time, (dt.time, pl.Expr)):
555
+ msg = f"expected 'time' to be a Python time or Polars expression, found {qualified_type_name(time)!r}"
556
+ raise TypeError(msg)
557
+ time_pyexpr = parse_into_expression(time)
558
+ return wrap_expr(self._pyexpr.dt_combine(time_pyexpr, time_unit))
559
+
560
+ def to_string(self, format: str | None = None) -> Expr:
561
+ """
562
+ Convert a Date/Time/Datetime column into a String column with the given format.
563
+
564
+ .. versionchanged:: 1.15.0
565
+ Added support for the use of "iso:strict" as a format string.
566
+ .. versionchanged:: 1.14.0
567
+ Added support for the `Duration` dtype, and use of "iso" as a format string.
568
+
569
+ Parameters
570
+ ----------
571
+ format
572
+ * Format to use, refer to the `chrono strftime documentation
573
+ <https://docs.rs/chrono/latest/chrono/format/strftime/index.html>`_
574
+ for specification. Example: `"%y-%m-%d"`.
575
+
576
+ * If no format is provided, the appropriate ISO format for the underlying
577
+ data type is used. This can be made explicit by passing `"iso"` or
578
+ `"iso:strict"` as the format string (see notes below for details).
579
+
580
+ Notes
581
+ -----
582
+ * Similar to `cast(pl.String)`, but this method allows you to customize
583
+ the formatting of the resulting string; if no format is provided, the
584
+ appropriate ISO format for the underlying data type is used.
585
+
586
+ * Datetime dtype expressions distinguish between "iso" and "iso:strict"
587
+ format strings. The difference is in the inclusion of a "T" separator
588
+ between the date and time components ("iso" results in ISO compliant
589
+ date and time components, separated with a space; "iso:strict" returns
590
+ the same components separated with a "T"). All other temporal types
591
+ return the same value for both format strings.
592
+
593
+ * Duration dtype expressions cannot be formatted with `strftime`. Instead,
594
+ only "iso" and "polars" are supported as format strings. The "iso" format
595
+ string results in ISO8601 duration string output, and "polars" results
596
+ in the same form seen in the frame `repr`.
597
+
598
+ Examples
599
+ --------
600
+ >>> from datetime import datetime, date, timedelta, time
601
+ >>> df = pl.DataFrame(
602
+ ... {
603
+ ... "dt": [
604
+ ... date(1999, 3, 1),
605
+ ... date(2020, 5, 3),
606
+ ... date(2077, 7, 5),
607
+ ... ],
608
+ ... "dtm": [
609
+ ... datetime(1980, 8, 10, 0, 10, 20),
610
+ ... datetime(2010, 10, 20, 8, 25, 35),
611
+ ... datetime(2040, 12, 30, 16, 40, 50),
612
+ ... ],
613
+ ... "tm": [
614
+ ... time(1, 2, 3, 456789),
615
+ ... time(23, 59, 9, 101),
616
+ ... time(0, 0, 0, 100),
617
+ ... ],
618
+ ... "td": [
619
+ ... timedelta(days=-1, seconds=-42),
620
+ ... timedelta(days=14, hours=-10, microseconds=100),
621
+ ... timedelta(seconds=0),
622
+ ... ],
623
+ ... }
624
+ ... )
625
+
626
+ Default format for temporal dtypes is ISO8601:
627
+
628
+ >>> import polars.selectors as cs
629
+ >>> df.select(cs.temporal().dt.to_string().name.prefix("s_"))
630
+ shape: (3, 4)
631
+ ┌────────────┬────────────────────────────┬─────────────────┬─────────────────┐
632
+ │ s_dt ┆ s_dtm ┆ s_tm ┆ s_td │
633
+ │ --- ┆ --- ┆ --- ┆ --- │
634
+ │ str ┆ str ┆ str ┆ str │
635
+ ╞════════════╪════════════════════════════╪═════════════════╪═════════════════╡
636
+ │ 1999-03-01 ┆ 1980-08-10 00:10:20.000000 ┆ 01:02:03.456789 ┆ -P1DT42S │
637
+ │ 2020-05-03 ┆ 2010-10-20 08:25:35.000000 ┆ 23:59:09.000101 ┆ P13DT14H0.0001S │
638
+ │ 2077-07-05 ┆ 2040-12-30 16:40:50.000000 ┆ 00:00:00.000100 ┆ PT0S │
639
+ └────────────┴────────────────────────────┴─────────────────┴─────────────────┘
640
+
641
+ For `Datetime` specifically you can choose between "iso" (where the date and
642
+ time components are ISO, separated by a space) and "iso:strict" (where these
643
+ components are separated by a "T"):
644
+
645
+ >>> df.select(
646
+ ... pl.col("dtm").dt.to_string("iso").alias("dtm_iso"),
647
+ ... pl.col("dtm").dt.to_string("iso:strict").alias("dtm_iso_strict"),
648
+ ... )
649
+ shape: (3, 2)
650
+ ┌────────────────────────────┬────────────────────────────┐
651
+ │ dtm_iso ┆ dtm_iso_strict │
652
+ │ --- ┆ --- │
653
+ │ str ┆ str │
654
+ ╞════════════════════════════╪════════════════════════════╡
655
+ │ 1980-08-10 00:10:20.000000 ┆ 1980-08-10T00:10:20.000000 │
656
+ │ 2010-10-20 08:25:35.000000 ┆ 2010-10-20T08:25:35.000000 │
657
+ │ 2040-12-30 16:40:50.000000 ┆ 2040-12-30T16:40:50.000000 │
658
+ └────────────────────────────┴────────────────────────────┘
659
+
660
+ All temporal types (aside from `Duration`) support strftime formatting:
661
+
662
+ >>> df.select(
663
+ ... pl.col("dtm"),
664
+ ... s_dtm=pl.col("dtm").dt.to_string("%Y/%m/%d (%H.%M.%S)"),
665
+ ... )
666
+ shape: (3, 2)
667
+ ┌─────────────────────┬───────────────────────┐
668
+ │ dtm ┆ s_dtm │
669
+ │ --- ┆ --- │
670
+ │ datetime[μs] ┆ str │
671
+ ╞═════════════════════╪═══════════════════════╡
672
+ │ 1980-08-10 00:10:20 ┆ 1980/08/10 (00.10.20) │
673
+ │ 2010-10-20 08:25:35 ┆ 2010/10/20 (08.25.35) │
674
+ │ 2040-12-30 16:40:50 ┆ 2040/12/30 (16.40.50) │
675
+ └─────────────────────┴───────────────────────┘
676
+
677
+ The Polars Duration string format (as seen in the frame repr) is also available:
678
+
679
+ >>> df.select(
680
+ ... pl.col("td"),
681
+ ... s_td=pl.col("td").dt.to_string("polars"),
682
+ ... )
683
+ shape: (3, 2)
684
+ ┌───────────────┬───────────────┐
685
+ │ td ┆ s_td │
686
+ │ --- ┆ --- │
687
+ │ duration[μs] ┆ str │
688
+ ╞═══════════════╪═══════════════╡
689
+ │ -1d -42s ┆ -1d -42s │
690
+ │ 13d 14h 100µs ┆ 13d 14h 100µs │
691
+ │ 0µs ┆ 0µs │
692
+ └───────────────┴───────────────┘
693
+
694
+ If you're interested in extracting the day or month names, you can use
695
+ the `'%A'` and `'%B'` strftime specifiers:
696
+
697
+ >>> df.select(
698
+ ... pl.col("dt"),
699
+ ... day_name=pl.col("dtm").dt.to_string("%A"),
700
+ ... month_name=pl.col("dtm").dt.to_string("%B"),
701
+ ... )
702
+ shape: (3, 3)
703
+ ┌────────────┬───────────┬────────────┐
704
+ │ dt ┆ day_name ┆ month_name │
705
+ │ --- ┆ --- ┆ --- │
706
+ │ date ┆ str ┆ str │
707
+ ╞════════════╪═══════════╪════════════╡
708
+ │ 1999-03-01 ┆ Sunday ┆ August │
709
+ │ 2020-05-03 ┆ Wednesday ┆ October │
710
+ │ 2077-07-05 ┆ Sunday ┆ December │
711
+ └────────────┴───────────┴────────────┘
712
+ """
713
+ if format is None:
714
+ format = "iso"
715
+ return wrap_expr(self._pyexpr.dt_to_string(format))
716
+
717
+ def strftime(self, format: str) -> Expr:
718
+ """
719
+ Convert a Date/Time/Datetime column into a String column with the given format.
720
+
721
+ Similar to `cast(pl.String)`, but this method allows you to customize the
722
+ formatting of the resulting string.
723
+
724
+ Alias for :func:`to_string`.
725
+
726
+ Parameters
727
+ ----------
728
+ format
729
+ Format to use, refer to the `chrono strftime documentation
730
+ <https://docs.rs/chrono/latest/chrono/format/strftime/index.html>`_
731
+ for specification. Example: `"%y-%m-%d"`.
732
+
733
+ See Also
734
+ --------
735
+ to_string : The identical expression for which `strftime` is an alias.
736
+
737
+ Examples
738
+ --------
739
+ >>> from datetime import datetime
740
+ >>> df = pl.DataFrame(
741
+ ... {
742
+ ... "datetime": [
743
+ ... datetime(2020, 3, 1),
744
+ ... datetime(2020, 4, 1),
745
+ ... datetime(2020, 5, 1),
746
+ ... ]
747
+ ... }
748
+ ... )
749
+ >>> df.with_columns(
750
+ ... pl.col("datetime")
751
+ ... .dt.strftime("%Y/%m/%d %H:%M:%S")
752
+ ... .alias("datetime_string")
753
+ ... )
754
+ shape: (3, 2)
755
+ ┌─────────────────────┬─────────────────────┐
756
+ │ datetime ┆ datetime_string │
757
+ │ --- ┆ --- │
758
+ │ datetime[μs] ┆ str │
759
+ ╞═════════════════════╪═════════════════════╡
760
+ │ 2020-03-01 00:00:00 ┆ 2020/03/01 00:00:00 │
761
+ │ 2020-04-01 00:00:00 ┆ 2020/04/01 00:00:00 │
762
+ │ 2020-05-01 00:00:00 ┆ 2020/05/01 00:00:00 │
763
+ └─────────────────────┴─────────────────────┘
764
+
765
+ If you're interested in the day name / month name, you can use
766
+ `'%A'` / `'%B'`:
767
+
768
+ >>> df.with_columns(
769
+ ... day_name=pl.col("datetime").dt.strftime("%A"),
770
+ ... month_name=pl.col("datetime").dt.strftime("%B"),
771
+ ... )
772
+ shape: (3, 3)
773
+ ┌─────────────────────┬───────────┬────────────┐
774
+ │ datetime ┆ day_name ┆ month_name │
775
+ │ --- ┆ --- ┆ --- │
776
+ │ datetime[μs] ┆ str ┆ str │
777
+ ╞═════════════════════╪═══════════╪════════════╡
778
+ │ 2020-03-01 00:00:00 ┆ Sunday ┆ March │
779
+ │ 2020-04-01 00:00:00 ┆ Wednesday ┆ April │
780
+ │ 2020-05-01 00:00:00 ┆ Friday ┆ May │
781
+ └─────────────────────┴───────────┴────────────┘
782
+ """
783
+ return self.to_string(format)
784
+
785
+ def millennium(self) -> Expr:
786
+ """
787
+ Extract the millennium from underlying representation.
788
+
789
+ Applies to Date and Datetime columns.
790
+
791
+ Returns the millennium number in the calendar date.
792
+
793
+ Returns
794
+ -------
795
+ Expr
796
+ Expression of data type :class:`Int32`.
797
+
798
+ Examples
799
+ --------
800
+ >>> from datetime import date
801
+ >>> df = pl.DataFrame(
802
+ ... {
803
+ ... "date": [
804
+ ... date(999, 12, 31),
805
+ ... date(1897, 5, 7),
806
+ ... date(2000, 1, 1),
807
+ ... date(2001, 7, 5),
808
+ ... date(3002, 10, 20),
809
+ ... ]
810
+ ... }
811
+ ... )
812
+ >>> df.with_columns(mlnm=pl.col("date").dt.millennium())
813
+ shape: (5, 2)
814
+ ┌────────────┬──────┐
815
+ │ date ┆ mlnm │
816
+ │ --- ┆ --- │
817
+ │ date ┆ i32 │
818
+ ╞════════════╪══════╡
819
+ │ 0999-12-31 ┆ 1 │
820
+ │ 1897-05-07 ┆ 2 │
821
+ │ 2000-01-01 ┆ 2 │
822
+ │ 2001-07-05 ┆ 3 │
823
+ │ 3002-10-20 ┆ 4 │
824
+ └────────────┴──────┘
825
+ """
826
+ return wrap_expr(self._pyexpr.dt_millennium())
827
+
828
+ def century(self) -> Expr:
829
+ """
830
+ Extract the century from underlying representation.
831
+
832
+ Applies to Date and Datetime columns.
833
+
834
+ Returns the century number in the calendar date.
835
+
836
+ Returns
837
+ -------
838
+ Expr
839
+ Expression of data type :class:`Int32`.
840
+
841
+ Examples
842
+ --------
843
+ >>> from datetime import date
844
+ >>> df = pl.DataFrame(
845
+ ... {
846
+ ... "date": [
847
+ ... date(999, 12, 31),
848
+ ... date(1897, 5, 7),
849
+ ... date(2000, 1, 1),
850
+ ... date(2001, 7, 5),
851
+ ... date(3002, 10, 20),
852
+ ... ]
853
+ ... }
854
+ ... )
855
+ >>> df.with_columns(cent=pl.col("date").dt.century())
856
+ shape: (5, 2)
857
+ ┌────────────┬──────┐
858
+ │ date ┆ cent │
859
+ │ --- ┆ --- │
860
+ │ date ┆ i32 │
861
+ ╞════════════╪══════╡
862
+ │ 0999-12-31 ┆ 10 │
863
+ │ 1897-05-07 ┆ 19 │
864
+ │ 2000-01-01 ┆ 20 │
865
+ │ 2001-07-05 ┆ 21 │
866
+ │ 3002-10-20 ┆ 31 │
867
+ └────────────┴──────┘
868
+ """
869
+ return wrap_expr(self._pyexpr.dt_century())
870
+
871
+ def year(self) -> Expr:
872
+ """
873
+ Extract year from underlying Date representation.
874
+
875
+ Applies to Date and Datetime columns.
876
+
877
+ Returns the year number in the calendar date.
878
+
879
+ Returns
880
+ -------
881
+ Expr
882
+ Expression of data type :class:`Int32`.
883
+
884
+ Examples
885
+ --------
886
+ >>> from datetime import date
887
+ >>> df = pl.DataFrame(
888
+ ... {"date": [date(1977, 1, 1), date(1978, 1, 1), date(1979, 1, 1)]}
889
+ ... )
890
+ >>> df.with_columns(
891
+ ... calendar_year=pl.col("date").dt.year(),
892
+ ... iso_year=pl.col("date").dt.iso_year(),
893
+ ... )
894
+ shape: (3, 3)
895
+ ┌────────────┬───────────────┬──────────┐
896
+ │ date ┆ calendar_year ┆ iso_year │
897
+ │ --- ┆ --- ┆ --- │
898
+ │ date ┆ i32 ┆ i32 │
899
+ ╞════════════╪═══════════════╪══════════╡
900
+ │ 1977-01-01 ┆ 1977 ┆ 1976 │
901
+ │ 1978-01-01 ┆ 1978 ┆ 1977 │
902
+ │ 1979-01-01 ┆ 1979 ┆ 1979 │
903
+ └────────────┴───────────────┴──────────┘
904
+ """
905
+ return wrap_expr(self._pyexpr.dt_year())
906
+
907
+ @unstable()
908
+ def is_business_day(
909
+ self,
910
+ *,
911
+ week_mask: Iterable[bool] = (True, True, True, True, True, False, False),
912
+ holidays: Iterable[dt.date] = (),
913
+ ) -> Expr:
914
+ """
915
+ Determine whether each day lands on a business day.
916
+
917
+ .. warning::
918
+ This functionality is considered **unstable**. It may be changed
919
+ at any point without it being considered a breaking change.
920
+
921
+ Parameters
922
+ ----------
923
+ week_mask
924
+ Which days of the week to count. The default is Monday to Friday.
925
+ If you wanted to count only Monday to Thursday, you would pass
926
+ `(True, True, True, True, False, False, False)`.
927
+ holidays
928
+ Holidays to exclude from the count. The Python package
929
+ `python-holidays <https://github.com/vacanza/python-holidays>`_
930
+ may come in handy here. You can install it with ``pip install holidays``,
931
+ and then, to get all Dutch holidays for years 2020-2024:
932
+
933
+ .. code-block:: python
934
+
935
+ import holidays
936
+
937
+ my_holidays = holidays.country_holidays("NL", years=range(2020, 2025))
938
+
939
+ and pass `holidays=my_holidays` when you call `is_business_day`.
940
+
941
+ Returns
942
+ -------
943
+ Expr
944
+ Expression of data type :class:`Boolean`.
945
+
946
+ Examples
947
+ --------
948
+ >>> from datetime import date
949
+ >>> df = pl.DataFrame({"start": [date(2020, 1, 3), date(2020, 1, 5)]})
950
+ >>> df.with_columns(is_business_day=pl.col("start").dt.is_business_day())
951
+ shape: (2, 2)
952
+ ┌────────────┬─────────────────┐
953
+ │ start ┆ is_business_day │
954
+ │ --- ┆ --- │
955
+ │ date ┆ bool │
956
+ ╞════════════╪═════════════════╡
957
+ │ 2020-01-03 ┆ true │
958
+ │ 2020-01-05 ┆ false │
959
+ └────────────┴─────────────────┘
960
+
961
+ You can pass a custom weekend - for example, if you only take Sunday off:
962
+
963
+ >>> week_mask = (True, True, True, True, True, True, False)
964
+ >>> df.with_columns(
965
+ ... is_business_day=pl.col("start").dt.is_business_day(week_mask=week_mask)
966
+ ... )
967
+ shape: (2, 2)
968
+ ┌────────────┬─────────────────┐
969
+ │ start ┆ is_business_day │
970
+ │ --- ┆ --- │
971
+ │ date ┆ bool │
972
+ ╞════════════╪═════════════════╡
973
+ │ 2020-01-03 ┆ true │
974
+ │ 2020-01-05 ┆ false │
975
+ └────────────┴─────────────────┘
976
+
977
+ You can also pass a list of holidays:
978
+
979
+ >>> from datetime import date
980
+ >>> holidays = [date(2020, 1, 3), date(2020, 1, 6)]
981
+ >>> df.with_columns(
982
+ ... is_business_day=pl.col("start").dt.is_business_day(holidays=holidays)
983
+ ... )
984
+ shape: (2, 2)
985
+ ┌────────────┬─────────────────┐
986
+ │ start ┆ is_business_day │
987
+ │ --- ┆ --- │
988
+ │ date ┆ bool │
989
+ ╞════════════╪═════════════════╡
990
+ │ 2020-01-03 ┆ false │
991
+ │ 2020-01-05 ┆ false │
992
+ └────────────┴─────────────────┘
993
+ """
994
+ unix_epoch = dt.date(1970, 1, 1)
995
+ return wrap_expr(
996
+ self._pyexpr.dt_is_business_day(
997
+ list(week_mask),
998
+ [(holiday - unix_epoch).days for holiday in holidays],
999
+ )
1000
+ )
1001
+
1002
+ def is_leap_year(self) -> Expr:
1003
+ """
1004
+ Determine whether the year of the underlying date is a leap year.
1005
+
1006
+ Applies to Date and Datetime columns.
1007
+
1008
+ Returns
1009
+ -------
1010
+ Expr
1011
+ Expression of data type :class:`Boolean`.
1012
+
1013
+ Examples
1014
+ --------
1015
+ >>> from datetime import date
1016
+ >>> df = pl.DataFrame(
1017
+ ... {"date": [date(2000, 1, 1), date(2001, 1, 1), date(2002, 1, 1)]}
1018
+ ... )
1019
+ >>> df.with_columns(
1020
+ ... leap_year=pl.col("date").dt.is_leap_year(),
1021
+ ... )
1022
+ shape: (3, 2)
1023
+ ┌────────────┬───────────┐
1024
+ │ date ┆ leap_year │
1025
+ │ --- ┆ --- │
1026
+ │ date ┆ bool │
1027
+ ╞════════════╪═══════════╡
1028
+ │ 2000-01-01 ┆ true │
1029
+ │ 2001-01-01 ┆ false │
1030
+ │ 2002-01-01 ┆ false │
1031
+ └────────────┴───────────┘
1032
+ """
1033
+ return wrap_expr(self._pyexpr.dt_is_leap_year())
1034
+
1035
+ def iso_year(self) -> Expr:
1036
+ """
1037
+ Extract ISO year from underlying Date representation.
1038
+
1039
+ Applies to Date and Datetime columns.
1040
+
1041
+ Returns the year number in the ISO standard.
1042
+ This may not correspond with the calendar year.
1043
+
1044
+ Returns
1045
+ -------
1046
+ Expr
1047
+ Expression of data type :class:`Int32`.
1048
+
1049
+ Examples
1050
+ --------
1051
+ >>> from datetime import date
1052
+ >>> df = pl.DataFrame(
1053
+ ... {"date": [date(1977, 1, 1), date(1978, 1, 1), date(1979, 1, 1)]}
1054
+ ... )
1055
+ >>> df.select(
1056
+ ... "date",
1057
+ ... pl.col("date").dt.year().alias("calendar_year"),
1058
+ ... pl.col("date").dt.iso_year().alias("iso_year"),
1059
+ ... )
1060
+ shape: (3, 3)
1061
+ ┌────────────┬───────────────┬──────────┐
1062
+ │ date ┆ calendar_year ┆ iso_year │
1063
+ │ --- ┆ --- ┆ --- │
1064
+ │ date ┆ i32 ┆ i32 │
1065
+ ╞════════════╪═══════════════╪══════════╡
1066
+ │ 1977-01-01 ┆ 1977 ┆ 1976 │
1067
+ │ 1978-01-01 ┆ 1978 ┆ 1977 │
1068
+ │ 1979-01-01 ┆ 1979 ┆ 1979 │
1069
+ └────────────┴───────────────┴──────────┘
1070
+ """
1071
+ return wrap_expr(self._pyexpr.dt_iso_year())
1072
+
1073
+ def quarter(self) -> Expr:
1074
+ """
1075
+ Extract quarter from underlying Date representation.
1076
+
1077
+ Applies to Date and Datetime columns.
1078
+
1079
+ Returns the quarter ranging from 1 to 4.
1080
+
1081
+ Returns
1082
+ -------
1083
+ Expr
1084
+ Expression of data type :class:`Int8`.
1085
+
1086
+ Examples
1087
+ --------
1088
+ >>> from datetime import date
1089
+ >>> df = pl.DataFrame(
1090
+ ... {"date": [date(2001, 1, 1), date(2001, 6, 30), date(2001, 12, 27)]}
1091
+ ... )
1092
+ >>> df.with_columns(pl.col("date").dt.quarter().alias("quarter"))
1093
+ shape: (3, 2)
1094
+ ┌────────────┬─────────┐
1095
+ │ date ┆ quarter │
1096
+ │ --- ┆ --- │
1097
+ │ date ┆ i8 │
1098
+ ╞════════════╪═════════╡
1099
+ │ 2001-01-01 ┆ 1 │
1100
+ │ 2001-06-30 ┆ 2 │
1101
+ │ 2001-12-27 ┆ 4 │
1102
+ └────────────┴─────────┘
1103
+ """
1104
+ return wrap_expr(self._pyexpr.dt_quarter())
1105
+
1106
+ def month(self) -> Expr:
1107
+ """
1108
+ Extract month from underlying Date representation.
1109
+
1110
+ Applies to Date and Datetime columns.
1111
+
1112
+ Returns the month number starting from 1.
1113
+ The return value ranges from 1 to 12.
1114
+
1115
+ Returns
1116
+ -------
1117
+ Expr
1118
+ Expression of data type :class:`Int8`.
1119
+
1120
+ Examples
1121
+ --------
1122
+ >>> from datetime import date
1123
+ >>> df = pl.DataFrame(
1124
+ ... {"date": [date(2001, 1, 1), date(2001, 6, 30), date(2001, 12, 27)]}
1125
+ ... )
1126
+ >>> df.with_columns(pl.col("date").dt.month().alias("month"))
1127
+ shape: (3, 2)
1128
+ ┌────────────┬───────┐
1129
+ │ date ┆ month │
1130
+ │ --- ┆ --- │
1131
+ │ date ┆ i8 │
1132
+ ╞════════════╪═══════╡
1133
+ │ 2001-01-01 ┆ 1 │
1134
+ │ 2001-06-30 ┆ 6 │
1135
+ │ 2001-12-27 ┆ 12 │
1136
+ └────────────┴───────┘
1137
+ """
1138
+ return wrap_expr(self._pyexpr.dt_month())
1139
+
1140
+ def days_in_month(self) -> Expr:
1141
+ """
1142
+ Extract the number of days in the month from the underlying Date representation.
1143
+
1144
+ Applies to Date and Datetime columns.
1145
+
1146
+ Returns the number of days in the month.
1147
+ The return value ranges from 28 to 31.
1148
+
1149
+ Returns
1150
+ -------
1151
+ Expr
1152
+ Expression of data type :class:`Int8`.
1153
+
1154
+ See Also
1155
+ --------
1156
+ month
1157
+ is_leap_year
1158
+
1159
+ Examples
1160
+ --------
1161
+ >>> from datetime import date
1162
+ >>> df = pl.DataFrame(
1163
+ ... {"date": [date(2001, 1, 1), date(2001, 2, 1), date(2000, 2, 1)]}
1164
+ ... )
1165
+ >>> df.with_columns(pl.col("date").dt.days_in_month().alias("days_in_month"))
1166
+ shape: (3, 2)
1167
+ ┌────────────┬───────────────┐
1168
+ │ date ┆ days_in_month │
1169
+ │ --- ┆ --- │
1170
+ │ date ┆ i8 │
1171
+ ╞════════════╪═══════════════╡
1172
+ │ 2001-01-01 ┆ 31 │
1173
+ │ 2001-02-01 ┆ 28 │
1174
+ │ 2000-02-01 ┆ 29 │
1175
+ └────────────┴───────────────┘
1176
+ """
1177
+ return wrap_expr(self._pyexpr.dt_days_in_month())
1178
+
1179
+ def week(self) -> Expr:
1180
+ """
1181
+ Extract the week from the underlying Date representation.
1182
+
1183
+ Applies to Date and Datetime columns.
1184
+
1185
+ Returns the ISO week number starting from 1.
1186
+ The return value ranges from 1 to 53. (The last week of year differs by years.)
1187
+
1188
+ Returns
1189
+ -------
1190
+ Expr
1191
+ Expression of data type :class:`Int8`.
1192
+
1193
+ Examples
1194
+ --------
1195
+ >>> from datetime import date
1196
+ >>> df = pl.DataFrame(
1197
+ ... {"date": [date(2001, 1, 1), date(2001, 6, 30), date(2001, 12, 27)]}
1198
+ ... )
1199
+ >>> df.with_columns(pl.col("date").dt.week().alias("week"))
1200
+ shape: (3, 2)
1201
+ ┌────────────┬──────┐
1202
+ │ date ┆ week │
1203
+ │ --- ┆ --- │
1204
+ │ date ┆ i8 │
1205
+ ╞════════════╪══════╡
1206
+ │ 2001-01-01 ┆ 1 │
1207
+ │ 2001-06-30 ┆ 26 │
1208
+ │ 2001-12-27 ┆ 52 │
1209
+ └────────────┴──────┘
1210
+ """
1211
+ return wrap_expr(self._pyexpr.dt_week())
1212
+
1213
+ def weekday(self) -> Expr:
1214
+ """
1215
+ Extract the week day from the underlying Date representation.
1216
+
1217
+ Applies to Date and Datetime columns.
1218
+
1219
+ Returns the ISO weekday number where monday = 1 and sunday = 7
1220
+
1221
+ Returns
1222
+ -------
1223
+ Expr
1224
+ Expression of data type :class:`Int8`.
1225
+
1226
+ See Also
1227
+ --------
1228
+ day
1229
+ ordinal_day
1230
+
1231
+ Examples
1232
+ --------
1233
+ >>> from datetime import date
1234
+ >>> df = pl.DataFrame(
1235
+ ... {
1236
+ ... "date": pl.date_range(
1237
+ ... date(2001, 12, 22), date(2001, 12, 25), eager=True
1238
+ ... )
1239
+ ... }
1240
+ ... )
1241
+ >>> df.with_columns(
1242
+ ... pl.col("date").dt.weekday().alias("weekday"),
1243
+ ... pl.col("date").dt.day().alias("day_of_month"),
1244
+ ... pl.col("date").dt.ordinal_day().alias("day_of_year"),
1245
+ ... )
1246
+ shape: (4, 4)
1247
+ ┌────────────┬─────────┬──────────────┬─────────────┐
1248
+ │ date ┆ weekday ┆ day_of_month ┆ day_of_year │
1249
+ │ --- ┆ --- ┆ --- ┆ --- │
1250
+ │ date ┆ i8 ┆ i8 ┆ i16 │
1251
+ ╞════════════╪═════════╪══════════════╪═════════════╡
1252
+ │ 2001-12-22 ┆ 6 ┆ 22 ┆ 356 │
1253
+ │ 2001-12-23 ┆ 7 ┆ 23 ┆ 357 │
1254
+ │ 2001-12-24 ┆ 1 ┆ 24 ┆ 358 │
1255
+ │ 2001-12-25 ┆ 2 ┆ 25 ┆ 359 │
1256
+ └────────────┴─────────┴──────────────┴─────────────┘
1257
+ """
1258
+ return wrap_expr(self._pyexpr.dt_weekday())
1259
+
1260
+ def day(self) -> Expr:
1261
+ """
1262
+ Extract day from underlying Date representation.
1263
+
1264
+ Applies to Date and Datetime columns.
1265
+
1266
+ Returns the day of month starting from 1.
1267
+ The return value ranges from 1 to 31. (The last day of month differs by months.)
1268
+
1269
+ Returns
1270
+ -------
1271
+ Expr
1272
+ Expression of data type :class:`Int8`.
1273
+
1274
+ See Also
1275
+ --------
1276
+ weekday
1277
+ ordinal_day
1278
+
1279
+ Examples
1280
+ --------
1281
+ >>> from datetime import date
1282
+ >>> df = pl.DataFrame(
1283
+ ... {
1284
+ ... "date": pl.date_range(
1285
+ ... date(2001, 12, 22), date(2001, 12, 25), eager=True
1286
+ ... )
1287
+ ... }
1288
+ ... )
1289
+ >>> df.with_columns(
1290
+ ... pl.col("date").dt.weekday().alias("weekday"),
1291
+ ... pl.col("date").dt.day().alias("day_of_month"),
1292
+ ... pl.col("date").dt.ordinal_day().alias("day_of_year"),
1293
+ ... )
1294
+ shape: (4, 4)
1295
+ ┌────────────┬─────────┬──────────────┬─────────────┐
1296
+ │ date ┆ weekday ┆ day_of_month ┆ day_of_year │
1297
+ │ --- ┆ --- ┆ --- ┆ --- │
1298
+ │ date ┆ i8 ┆ i8 ┆ i16 │
1299
+ ╞════════════╪═════════╪══════════════╪═════════════╡
1300
+ │ 2001-12-22 ┆ 6 ┆ 22 ┆ 356 │
1301
+ │ 2001-12-23 ┆ 7 ┆ 23 ┆ 357 │
1302
+ │ 2001-12-24 ┆ 1 ┆ 24 ┆ 358 │
1303
+ │ 2001-12-25 ┆ 2 ┆ 25 ┆ 359 │
1304
+ └────────────┴─────────┴──────────────┴─────────────┘
1305
+ """
1306
+ return wrap_expr(self._pyexpr.dt_day())
1307
+
1308
+ def ordinal_day(self) -> Expr:
1309
+ """
1310
+ Extract ordinal day from underlying Date representation.
1311
+
1312
+ Applies to Date and Datetime columns.
1313
+
1314
+ Returns the day of year starting from 1.
1315
+ The return value ranges from 1 to 366. (The last day of year differs by years.)
1316
+
1317
+ Returns
1318
+ -------
1319
+ Expr
1320
+ Expression of data type :class:`Int16`.
1321
+
1322
+ See Also
1323
+ --------
1324
+ weekday
1325
+ day
1326
+
1327
+ Examples
1328
+ --------
1329
+ >>> from datetime import date
1330
+ >>> df = pl.DataFrame(
1331
+ ... {
1332
+ ... "date": pl.date_range(
1333
+ ... date(2001, 12, 22), date(2001, 12, 25), eager=True
1334
+ ... )
1335
+ ... }
1336
+ ... )
1337
+ >>> df.with_columns(
1338
+ ... pl.col("date").dt.weekday().alias("weekday"),
1339
+ ... pl.col("date").dt.day().alias("day_of_month"),
1340
+ ... pl.col("date").dt.ordinal_day().alias("day_of_year"),
1341
+ ... )
1342
+ shape: (4, 4)
1343
+ ┌────────────┬─────────┬──────────────┬─────────────┐
1344
+ │ date ┆ weekday ┆ day_of_month ┆ day_of_year │
1345
+ │ --- ┆ --- ┆ --- ┆ --- │
1346
+ │ date ┆ i8 ┆ i8 ┆ i16 │
1347
+ ╞════════════╪═════════╪══════════════╪═════════════╡
1348
+ │ 2001-12-22 ┆ 6 ┆ 22 ┆ 356 │
1349
+ │ 2001-12-23 ┆ 7 ┆ 23 ┆ 357 │
1350
+ │ 2001-12-24 ┆ 1 ┆ 24 ┆ 358 │
1351
+ │ 2001-12-25 ┆ 2 ┆ 25 ┆ 359 │
1352
+ └────────────┴─────────┴──────────────┴─────────────┘
1353
+ """
1354
+ return wrap_expr(self._pyexpr.dt_ordinal_day())
1355
+
1356
+ def time(self) -> Expr:
1357
+ """
1358
+ Extract time.
1359
+
1360
+ Applies to Datetime columns only; fails on Date.
1361
+
1362
+ Returns
1363
+ -------
1364
+ Expr
1365
+ Expression of data type :class:`Time`.
1366
+
1367
+ Examples
1368
+ --------
1369
+ >>> from datetime import datetime
1370
+ >>> df = pl.DataFrame(
1371
+ ... {
1372
+ ... "datetime": [
1373
+ ... datetime(1978, 1, 1, 1, 1, 1, 0),
1374
+ ... datetime(2024, 10, 13, 5, 30, 14, 500_000),
1375
+ ... datetime(2065, 1, 1, 10, 20, 30, 60_000),
1376
+ ... ]
1377
+ ... }
1378
+ ... )
1379
+ >>> df.with_columns(pl.col("datetime").dt.time().alias("time"))
1380
+ shape: (3, 2)
1381
+ ┌─────────────────────────┬──────────────┐
1382
+ │ datetime ┆ time │
1383
+ │ --- ┆ --- │
1384
+ │ datetime[μs] ┆ time │
1385
+ ╞═════════════════════════╪══════════════╡
1386
+ │ 1978-01-01 01:01:01 ┆ 01:01:01 │
1387
+ │ 2024-10-13 05:30:14.500 ┆ 05:30:14.500 │
1388
+ │ 2065-01-01 10:20:30.060 ┆ 10:20:30.060 │
1389
+ └─────────────────────────┴──────────────┘
1390
+ """
1391
+ return wrap_expr(self._pyexpr.dt_time())
1392
+
1393
+ def date(self) -> Expr:
1394
+ """
1395
+ Extract date from date(time).
1396
+
1397
+ Applies to Date and Datetime columns.
1398
+
1399
+ Returns
1400
+ -------
1401
+ Expr
1402
+ Expression of data type :class:`Date`.
1403
+
1404
+ Examples
1405
+ --------
1406
+ >>> from datetime import datetime
1407
+ >>> df = pl.DataFrame(
1408
+ ... {
1409
+ ... "datetime": [
1410
+ ... datetime(1978, 1, 1, 1, 1, 1, 0),
1411
+ ... datetime(2024, 10, 13, 5, 30, 14, 500_000),
1412
+ ... datetime(2065, 1, 1, 10, 20, 30, 60_000),
1413
+ ... ]
1414
+ ... }
1415
+ ... )
1416
+ >>> df.with_columns(pl.col("datetime").dt.date().alias("date"))
1417
+ shape: (3, 2)
1418
+ ┌─────────────────────────┬────────────┐
1419
+ │ datetime ┆ date │
1420
+ │ --- ┆ --- │
1421
+ │ datetime[μs] ┆ date │
1422
+ ╞═════════════════════════╪════════════╡
1423
+ │ 1978-01-01 01:01:01 ┆ 1978-01-01 │
1424
+ │ 2024-10-13 05:30:14.500 ┆ 2024-10-13 │
1425
+ │ 2065-01-01 10:20:30.060 ┆ 2065-01-01 │
1426
+ └─────────────────────────┴────────────┘
1427
+ """
1428
+ return wrap_expr(self._pyexpr.dt_date())
1429
+
1430
+ @deprecated(
1431
+ "`dt.datetime` is deprecated; use `dt.replace_time_zone(None)` instead."
1432
+ )
1433
+ def datetime(self) -> Expr:
1434
+ """
1435
+ Return datetime.
1436
+
1437
+ .. deprecated:: 0.20.4
1438
+ Use the `dt.replace_time_zone(None)` method instead.
1439
+
1440
+ Applies to Datetime columns.
1441
+
1442
+ Returns
1443
+ -------
1444
+ Expr
1445
+ Expression of data type :class:`Datetime`.
1446
+
1447
+ Examples
1448
+ --------
1449
+ >>> from datetime import datetime
1450
+ >>> df = pl.DataFrame(
1451
+ ... {
1452
+ ... "datetime UTC": [
1453
+ ... datetime(1978, 1, 1, 1, 1, 1, 0),
1454
+ ... datetime(2024, 10, 13, 5, 30, 14, 500_000),
1455
+ ... datetime(2065, 1, 1, 10, 20, 30, 60_000),
1456
+ ... ]
1457
+ ... },
1458
+ ... schema={"datetime UTC": pl.Datetime(time_zone="UTC")},
1459
+ ... )
1460
+ >>> df.with_columns( # doctest: +SKIP
1461
+ ... pl.col("datetime UTC").dt.datetime().alias("datetime (no timezone)"),
1462
+ ... )
1463
+ shape: (3, 2)
1464
+ ┌─────────────────────────────┬─────────────────────────┐
1465
+ │ datetime UTC ┆ datetime (no timezone) │
1466
+ │ --- ┆ --- │
1467
+ │ datetime[μs, UTC] ┆ datetime[μs] │
1468
+ ╞═════════════════════════════╪═════════════════════════╡
1469
+ │ 1978-01-01 01:01:01 UTC ┆ 1978-01-01 01:01:01 │
1470
+ │ 2024-10-13 05:30:14.500 UTC ┆ 2024-10-13 05:30:14.500 │
1471
+ │ 2065-01-01 10:20:30.060 UTC ┆ 2065-01-01 10:20:30.060 │
1472
+ └─────────────────────────────┴─────────────────────────┘
1473
+ """
1474
+ return wrap_expr(self._pyexpr.dt_datetime())
1475
+
1476
+ def hour(self) -> Expr:
1477
+ """
1478
+ Extract hour from underlying DateTime representation.
1479
+
1480
+ Applies to Datetime columns.
1481
+
1482
+ Returns the hour number from 0 to 23.
1483
+
1484
+ Returns
1485
+ -------
1486
+ Expr
1487
+ Expression of data type :class:`Int8`.
1488
+
1489
+ Examples
1490
+ --------
1491
+ >>> from datetime import datetime
1492
+ >>> df = pl.DataFrame(
1493
+ ... {
1494
+ ... "datetime": [
1495
+ ... datetime(1978, 1, 1, 1, 1, 1, 0),
1496
+ ... datetime(2024, 10, 13, 5, 30, 14, 500_000),
1497
+ ... datetime(2065, 1, 1, 10, 20, 30, 60_000),
1498
+ ... ]
1499
+ ... }
1500
+ ... )
1501
+ >>> df.with_columns(
1502
+ ... pl.col("datetime").dt.hour().alias("hour"),
1503
+ ... pl.col("datetime").dt.minute().alias("minute"),
1504
+ ... pl.col("datetime").dt.second().alias("second"),
1505
+ ... pl.col("datetime").dt.millisecond().alias("millisecond"),
1506
+ ... )
1507
+ shape: (3, 5)
1508
+ ┌─────────────────────────┬──────┬────────┬────────┬─────────────┐
1509
+ │ datetime ┆ hour ┆ minute ┆ second ┆ millisecond │
1510
+ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
1511
+ │ datetime[μs] ┆ i8 ┆ i8 ┆ i8 ┆ i32 │
1512
+ ╞═════════════════════════╪══════╪════════╪════════╪═════════════╡
1513
+ │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1 ┆ 0 │
1514
+ │ 2024-10-13 05:30:14.500 ┆ 5 ┆ 30 ┆ 14 ┆ 500 │
1515
+ │ 2065-01-01 10:20:30.060 ┆ 10 ┆ 20 ┆ 30 ┆ 60 │
1516
+ └─────────────────────────┴──────┴────────┴────────┴─────────────┘
1517
+ """
1518
+ return wrap_expr(self._pyexpr.dt_hour())
1519
+
1520
+ def minute(self) -> Expr:
1521
+ """
1522
+ Extract minutes from underlying DateTime representation.
1523
+
1524
+ Applies to Datetime columns.
1525
+
1526
+ Returns the minute number from 0 to 59.
1527
+
1528
+ Returns
1529
+ -------
1530
+ Expr
1531
+ Expression of data type :class:`Int8`.
1532
+
1533
+ Examples
1534
+ --------
1535
+ >>> from datetime import datetime
1536
+ >>> df = pl.DataFrame(
1537
+ ... {
1538
+ ... "datetime": [
1539
+ ... datetime(1978, 1, 1, 1, 1, 1, 0),
1540
+ ... datetime(2024, 10, 13, 5, 30, 14, 500_000),
1541
+ ... datetime(2065, 1, 1, 10, 20, 30, 60_000),
1542
+ ... ]
1543
+ ... }
1544
+ ... )
1545
+ >>> df.with_columns(
1546
+ ... pl.col("datetime").dt.hour().alias("hour"),
1547
+ ... pl.col("datetime").dt.minute().alias("minute"),
1548
+ ... pl.col("datetime").dt.second().alias("second"),
1549
+ ... pl.col("datetime").dt.millisecond().alias("millisecond"),
1550
+ ... )
1551
+ shape: (3, 5)
1552
+ ┌─────────────────────────┬──────┬────────┬────────┬─────────────┐
1553
+ │ datetime ┆ hour ┆ minute ┆ second ┆ millisecond │
1554
+ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
1555
+ │ datetime[μs] ┆ i8 ┆ i8 ┆ i8 ┆ i32 │
1556
+ ╞═════════════════════════╪══════╪════════╪════════╪═════════════╡
1557
+ │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1 ┆ 0 │
1558
+ │ 2024-10-13 05:30:14.500 ┆ 5 ┆ 30 ┆ 14 ┆ 500 │
1559
+ │ 2065-01-01 10:20:30.060 ┆ 10 ┆ 20 ┆ 30 ┆ 60 │
1560
+ └─────────────────────────┴──────┴────────┴────────┴─────────────┘
1561
+ """
1562
+ return wrap_expr(self._pyexpr.dt_minute())
1563
+
1564
+ def second(self, *, fractional: bool = False) -> Expr:
1565
+ """
1566
+ Extract seconds from underlying DateTime representation.
1567
+
1568
+ Applies to Datetime columns.
1569
+
1570
+ Returns the integer second number from 0 to 59, or a floating
1571
+ point number from 0 < 60 if `fractional=True` that includes
1572
+ any milli/micro/nanosecond component.
1573
+
1574
+ Parameters
1575
+ ----------
1576
+ fractional
1577
+ Whether to include the fractional component of the second.
1578
+
1579
+ Returns
1580
+ -------
1581
+ Expr
1582
+ Expression of data type :class:`Int8` or :class:`Float64`.
1583
+
1584
+ Examples
1585
+ --------
1586
+ >>> from datetime import datetime
1587
+ >>> df = pl.DataFrame(
1588
+ ... {
1589
+ ... "datetime": [
1590
+ ... datetime(1978, 1, 1, 1, 1, 1, 0),
1591
+ ... datetime(2024, 10, 13, 5, 30, 14, 500_000),
1592
+ ... datetime(2065, 1, 1, 10, 20, 30, 60_000),
1593
+ ... ]
1594
+ ... }
1595
+ ... )
1596
+ >>> df.with_columns(
1597
+ ... pl.col("datetime").dt.hour().alias("hour"),
1598
+ ... pl.col("datetime").dt.minute().alias("minute"),
1599
+ ... pl.col("datetime").dt.second().alias("second"),
1600
+ ... )
1601
+ shape: (3, 4)
1602
+ ┌─────────────────────────┬──────┬────────┬────────┐
1603
+ │ datetime ┆ hour ┆ minute ┆ second │
1604
+ │ --- ┆ --- ┆ --- ┆ --- │
1605
+ │ datetime[μs] ┆ i8 ┆ i8 ┆ i8 │
1606
+ ╞═════════════════════════╪══════╪════════╪════════╡
1607
+ │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1 │
1608
+ │ 2024-10-13 05:30:14.500 ┆ 5 ┆ 30 ┆ 14 │
1609
+ │ 2065-01-01 10:20:30.060 ┆ 10 ┆ 20 ┆ 30 │
1610
+ └─────────────────────────┴──────┴────────┴────────┘
1611
+ >>> df.with_columns(
1612
+ ... pl.col("datetime").dt.hour().alias("hour"),
1613
+ ... pl.col("datetime").dt.minute().alias("minute"),
1614
+ ... pl.col("datetime").dt.second(fractional=True).alias("second"),
1615
+ ... )
1616
+ shape: (3, 4)
1617
+ ┌─────────────────────────┬──────┬────────┬────────┐
1618
+ │ datetime ┆ hour ┆ minute ┆ second │
1619
+ │ --- ┆ --- ┆ --- ┆ --- │
1620
+ │ datetime[μs] ┆ i8 ┆ i8 ┆ f64 │
1621
+ ╞═════════════════════════╪══════╪════════╪════════╡
1622
+ │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1.0 │
1623
+ │ 2024-10-13 05:30:14.500 ┆ 5 ┆ 30 ┆ 14.5 │
1624
+ │ 2065-01-01 10:20:30.060 ┆ 10 ┆ 20 ┆ 30.06 │
1625
+ └─────────────────────────┴──────┴────────┴────────┘
1626
+ """
1627
+ sec = wrap_expr(self._pyexpr.dt_second())
1628
+ return (
1629
+ sec + (wrap_expr(self._pyexpr.dt_nanosecond()) / F.lit(1_000_000_000.0))
1630
+ if fractional
1631
+ else sec
1632
+ )
1633
+
1634
+ def millisecond(self) -> Expr:
1635
+ """
1636
+ Extract milliseconds from underlying DateTime representation.
1637
+
1638
+ Applies to Datetime columns.
1639
+
1640
+ Returns
1641
+ -------
1642
+ Expr
1643
+ Expression of data type :class:`Int32`.
1644
+
1645
+ Examples
1646
+ --------
1647
+ >>> from datetime import datetime
1648
+ >>> df = pl.DataFrame(
1649
+ ... {
1650
+ ... "datetime": [
1651
+ ... datetime(1978, 1, 1, 1, 1, 1, 0),
1652
+ ... datetime(2024, 10, 13, 5, 30, 14, 500_000),
1653
+ ... datetime(2065, 1, 1, 10, 20, 30, 60_000),
1654
+ ... ]
1655
+ ... }
1656
+ ... )
1657
+ >>> df.with_columns(
1658
+ ... pl.col("datetime").dt.hour().alias("hour"),
1659
+ ... pl.col("datetime").dt.minute().alias("minute"),
1660
+ ... pl.col("datetime").dt.second().alias("second"),
1661
+ ... pl.col("datetime").dt.millisecond().alias("millisecond"),
1662
+ ... )
1663
+ shape: (3, 5)
1664
+ ┌─────────────────────────┬──────┬────────┬────────┬─────────────┐
1665
+ │ datetime ┆ hour ┆ minute ┆ second ┆ millisecond │
1666
+ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
1667
+ │ datetime[μs] ┆ i8 ┆ i8 ┆ i8 ┆ i32 │
1668
+ ╞═════════════════════════╪══════╪════════╪════════╪═════════════╡
1669
+ │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1 ┆ 0 │
1670
+ │ 2024-10-13 05:30:14.500 ┆ 5 ┆ 30 ┆ 14 ┆ 500 │
1671
+ │ 2065-01-01 10:20:30.060 ┆ 10 ┆ 20 ┆ 30 ┆ 60 │
1672
+ └─────────────────────────┴──────┴────────┴────────┴─────────────┘
1673
+ """
1674
+ return wrap_expr(self._pyexpr.dt_millisecond())
1675
+
1676
+ def microsecond(self) -> Expr:
1677
+ """
1678
+ Extract microseconds from underlying DateTime representation.
1679
+
1680
+ Applies to Datetime columns.
1681
+
1682
+ Returns
1683
+ -------
1684
+ Expr
1685
+ Expression of data type :class:`Int32`.
1686
+
1687
+ Examples
1688
+ --------
1689
+ >>> from datetime import datetime
1690
+ >>> df = pl.DataFrame(
1691
+ ... {
1692
+ ... "datetime": [
1693
+ ... datetime(1978, 1, 1, 1, 1, 1, 0),
1694
+ ... datetime(2024, 10, 13, 5, 30, 14, 500_000),
1695
+ ... datetime(2065, 1, 1, 10, 20, 30, 60_000),
1696
+ ... ]
1697
+ ... }
1698
+ ... )
1699
+ >>> df.with_columns(
1700
+ ... pl.col("datetime").dt.hour().alias("hour"),
1701
+ ... pl.col("datetime").dt.minute().alias("minute"),
1702
+ ... pl.col("datetime").dt.second().alias("second"),
1703
+ ... pl.col("datetime").dt.microsecond().alias("microsecond"),
1704
+ ... )
1705
+ shape: (3, 5)
1706
+ ┌─────────────────────────┬──────┬────────┬────────┬─────────────┐
1707
+ │ datetime ┆ hour ┆ minute ┆ second ┆ microsecond │
1708
+ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
1709
+ │ datetime[μs] ┆ i8 ┆ i8 ┆ i8 ┆ i32 │
1710
+ ╞═════════════════════════╪══════╪════════╪════════╪═════════════╡
1711
+ │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1 ┆ 0 │
1712
+ │ 2024-10-13 05:30:14.500 ┆ 5 ┆ 30 ┆ 14 ┆ 500000 │
1713
+ │ 2065-01-01 10:20:30.060 ┆ 10 ┆ 20 ┆ 30 ┆ 60000 │
1714
+ └─────────────────────────┴──────┴────────┴────────┴─────────────┘
1715
+ """
1716
+ return wrap_expr(self._pyexpr.dt_microsecond())
1717
+
1718
+ def nanosecond(self) -> Expr:
1719
+ """
1720
+ Extract nanoseconds from underlying DateTime representation.
1721
+
1722
+ Applies to Datetime columns.
1723
+
1724
+ Returns
1725
+ -------
1726
+ Expr
1727
+ Expression of data type :class:`Int32`.
1728
+
1729
+ Examples
1730
+ --------
1731
+ >>> from datetime import datetime
1732
+ >>> df = pl.DataFrame(
1733
+ ... {
1734
+ ... "datetime": [
1735
+ ... datetime(1978, 1, 1, 1, 1, 1, 0),
1736
+ ... datetime(2024, 10, 13, 5, 30, 14, 500_000),
1737
+ ... datetime(2065, 1, 1, 10, 20, 30, 60_000),
1738
+ ... ]
1739
+ ... }
1740
+ ... )
1741
+ >>> df.with_columns(
1742
+ ... pl.col("datetime").dt.hour().alias("hour"),
1743
+ ... pl.col("datetime").dt.minute().alias("minute"),
1744
+ ... pl.col("datetime").dt.second().alias("second"),
1745
+ ... pl.col("datetime").dt.nanosecond().alias("nanosecond"),
1746
+ ... )
1747
+ shape: (3, 5)
1748
+ ┌─────────────────────────┬──────┬────────┬────────┬────────────┐
1749
+ │ datetime ┆ hour ┆ minute ┆ second ┆ nanosecond │
1750
+ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │
1751
+ │ datetime[μs] ┆ i8 ┆ i8 ┆ i8 ┆ i32 │
1752
+ ╞═════════════════════════╪══════╪════════╪════════╪════════════╡
1753
+ │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1 ┆ 0 │
1754
+ │ 2024-10-13 05:30:14.500 ┆ 5 ┆ 30 ┆ 14 ┆ 500000000 │
1755
+ │ 2065-01-01 10:20:30.060 ┆ 10 ┆ 20 ┆ 30 ┆ 60000000 │
1756
+ └─────────────────────────┴──────┴────────┴────────┴────────────┘
1757
+ """
1758
+ return wrap_expr(self._pyexpr.dt_nanosecond())
1759
+
1760
+ def epoch(self, time_unit: EpochTimeUnit = "us") -> Expr:
1761
+ """
1762
+ Get the time passed since the Unix EPOCH in the give time unit.
1763
+
1764
+ Parameters
1765
+ ----------
1766
+ time_unit : {'ns', 'us', 'ms', 's', 'd'}
1767
+ Time unit.
1768
+
1769
+ Examples
1770
+ --------
1771
+ >>> from datetime import date
1772
+ >>> df = (
1773
+ ... pl.date_range(date(2001, 1, 1), date(2001, 1, 3), eager=True)
1774
+ ... .alias("date")
1775
+ ... .to_frame()
1776
+ ... )
1777
+ >>> df.with_columns(
1778
+ ... pl.col("date").dt.epoch().alias("epoch_ns"),
1779
+ ... pl.col("date").dt.epoch(time_unit="s").alias("epoch_s"),
1780
+ ... )
1781
+ shape: (3, 3)
1782
+ ┌────────────┬─────────────────┬───────────┐
1783
+ │ date ┆ epoch_ns ┆ epoch_s │
1784
+ │ --- ┆ --- ┆ --- │
1785
+ │ date ┆ i64 ┆ i64 │
1786
+ ╞════════════╪═════════════════╪═══════════╡
1787
+ │ 2001-01-01 ┆ 978307200000000 ┆ 978307200 │
1788
+ │ 2001-01-02 ┆ 978393600000000 ┆ 978393600 │
1789
+ │ 2001-01-03 ┆ 978480000000000 ┆ 978480000 │
1790
+ └────────────┴─────────────────┴───────────┘
1791
+ """
1792
+ if time_unit in DTYPE_TEMPORAL_UNITS:
1793
+ return self.timestamp(time_unit) # type: ignore[arg-type]
1794
+ elif time_unit == "s":
1795
+ return self.timestamp("ms") // F.lit(1000, Int64)
1796
+ elif time_unit == "d":
1797
+ return wrap_expr(self._pyexpr).cast(Date).cast(Int32)
1798
+ else:
1799
+ msg = f"`time_unit` must be one of {{'ns', 'us', 'ms', 's', 'd'}}, got {time_unit!r}"
1800
+ raise ValueError(msg)
1801
+
1802
+ def timestamp(self, time_unit: TimeUnit = "us") -> Expr:
1803
+ """
1804
+ Return a timestamp in the given time unit.
1805
+
1806
+ Parameters
1807
+ ----------
1808
+ time_unit : {'ns', 'us', 'ms'}
1809
+ Time unit.
1810
+
1811
+ Examples
1812
+ --------
1813
+ >>> from datetime import date
1814
+ >>> df = (
1815
+ ... pl.date_range(date(2001, 1, 1), date(2001, 1, 3), eager=True)
1816
+ ... .alias("date")
1817
+ ... .to_frame()
1818
+ ... )
1819
+ >>> df.with_columns(
1820
+ ... pl.col("date").dt.timestamp().alias("timestamp_us"),
1821
+ ... pl.col("date").dt.timestamp("ms").alias("timestamp_ms"),
1822
+ ... )
1823
+ shape: (3, 3)
1824
+ ┌────────────┬─────────────────┬──────────────┐
1825
+ │ date ┆ timestamp_us ┆ timestamp_ms │
1826
+ │ --- ┆ --- ┆ --- │
1827
+ │ date ┆ i64 ┆ i64 │
1828
+ ╞════════════╪═════════════════╪══════════════╡
1829
+ │ 2001-01-01 ┆ 978307200000000 ┆ 978307200000 │
1830
+ │ 2001-01-02 ┆ 978393600000000 ┆ 978393600000 │
1831
+ │ 2001-01-03 ┆ 978480000000000 ┆ 978480000000 │
1832
+ └────────────┴─────────────────┴──────────────┘
1833
+ """
1834
+ return wrap_expr(self._pyexpr.dt_timestamp(time_unit))
1835
+
1836
+ @deprecated(
1837
+ "`dt.with_time_unit` is deprecated; instead, first cast "
1838
+ "to `Int64` and then cast to the desired data type."
1839
+ )
1840
+ def with_time_unit(self, time_unit: TimeUnit) -> Expr:
1841
+ """
1842
+ Set time unit of an expression of dtype Datetime or Duration.
1843
+
1844
+ .. deprecated:: 0.20.5
1845
+ First cast to `Int64` and then cast to the desired data type.
1846
+
1847
+ This does not modify underlying data, and should be used to fix an incorrect
1848
+ time unit.
1849
+
1850
+ Parameters
1851
+ ----------
1852
+ time_unit : {'ns', 'us', 'ms'}
1853
+ Unit of time for the `Datetime` or `Duration` expression.
1854
+
1855
+ Examples
1856
+ --------
1857
+ >>> from datetime import datetime
1858
+ >>> df = pl.DataFrame(
1859
+ ... {
1860
+ ... "date": pl.datetime_range(
1861
+ ... datetime(2001, 1, 1),
1862
+ ... datetime(2001, 1, 3),
1863
+ ... "1d",
1864
+ ... time_unit="ns",
1865
+ ... eager=True,
1866
+ ... )
1867
+ ... }
1868
+ ... )
1869
+ >>> df.select(
1870
+ ... pl.col("date"),
1871
+ ... pl.col("date").dt.with_time_unit("us").alias("time_unit_us"),
1872
+ ... ) # doctest: +SKIP
1873
+ shape: (3, 2)
1874
+ ┌─────────────────────┬───────────────────────┐
1875
+ │ date ┆ time_unit_us │
1876
+ │ --- ┆ --- │
1877
+ │ datetime[ns] ┆ datetime[μs] │
1878
+ ╞═════════════════════╪═══════════════════════╡
1879
+ │ 2001-01-01 00:00:00 ┆ +32971-04-28 00:00:00 │
1880
+ │ 2001-01-02 00:00:00 ┆ +32974-01-22 00:00:00 │
1881
+ │ 2001-01-03 00:00:00 ┆ +32976-10-18 00:00:00 │
1882
+ └─────────────────────┴───────────────────────┘
1883
+ """
1884
+ return wrap_expr(self._pyexpr.dt_with_time_unit(time_unit))
1885
+
1886
+ def cast_time_unit(self, time_unit: TimeUnit) -> Expr:
1887
+ """
1888
+ Cast the underlying data to another time unit. This may lose precision.
1889
+
1890
+ Parameters
1891
+ ----------
1892
+ time_unit : {'ns', 'us', 'ms'}
1893
+ Time unit for the `Datetime` expression.
1894
+
1895
+ Examples
1896
+ --------
1897
+ >>> from datetime import datetime
1898
+ >>> df = pl.DataFrame(
1899
+ ... {
1900
+ ... "date": pl.datetime_range(
1901
+ ... datetime(2001, 1, 1), datetime(2001, 1, 3), "1d", eager=True
1902
+ ... )
1903
+ ... }
1904
+ ... )
1905
+ >>> df.select(
1906
+ ... [
1907
+ ... pl.col("date"),
1908
+ ... pl.col("date").dt.cast_time_unit("ms").alias("time_unit_ms"),
1909
+ ... pl.col("date").dt.cast_time_unit("ns").alias("time_unit_ns"),
1910
+ ... ]
1911
+ ... )
1912
+ shape: (3, 3)
1913
+ ┌─────────────────────┬─────────────────────┬─────────────────────┐
1914
+ │ date ┆ time_unit_ms ┆ time_unit_ns │
1915
+ │ --- ┆ --- ┆ --- │
1916
+ │ datetime[μs] ┆ datetime[ms] ┆ datetime[ns] │
1917
+ ╞═════════════════════╪═════════════════════╪═════════════════════╡
1918
+ │ 2001-01-01 00:00:00 ┆ 2001-01-01 00:00:00 ┆ 2001-01-01 00:00:00 │
1919
+ │ 2001-01-02 00:00:00 ┆ 2001-01-02 00:00:00 ┆ 2001-01-02 00:00:00 │
1920
+ │ 2001-01-03 00:00:00 ┆ 2001-01-03 00:00:00 ┆ 2001-01-03 00:00:00 │
1921
+ └─────────────────────┴─────────────────────┴─────────────────────┘
1922
+ """
1923
+ return wrap_expr(self._pyexpr.dt_cast_time_unit(time_unit))
1924
+
1925
+ def convert_time_zone(self, time_zone: str) -> Expr:
1926
+ """
1927
+ Convert to given time zone for an expression of type Datetime.
1928
+
1929
+ Parameters
1930
+ ----------
1931
+ time_zone
1932
+ Time zone for the `Datetime` expression.
1933
+
1934
+ Notes
1935
+ -----
1936
+ If converting from a time-zone-naive datetime, then conversion will happen
1937
+ as if converting from UTC, regardless of your system's time zone.
1938
+
1939
+ Examples
1940
+ --------
1941
+ >>> from datetime import datetime
1942
+ >>> df = pl.DataFrame(
1943
+ ... {
1944
+ ... "date": pl.datetime_range(
1945
+ ... datetime(2020, 3, 1),
1946
+ ... datetime(2020, 5, 1),
1947
+ ... "1mo",
1948
+ ... time_zone="UTC",
1949
+ ... eager=True,
1950
+ ... ),
1951
+ ... }
1952
+ ... )
1953
+ >>> df.select(
1954
+ ... [
1955
+ ... pl.col("date"),
1956
+ ... pl.col("date")
1957
+ ... .dt.convert_time_zone(time_zone="Europe/London")
1958
+ ... .alias("London"),
1959
+ ... ]
1960
+ ... )
1961
+ shape: (3, 2)
1962
+ ┌─────────────────────────┬─────────────────────────────┐
1963
+ │ date ┆ London │
1964
+ │ --- ┆ --- │
1965
+ │ datetime[μs, UTC] ┆ datetime[μs, Europe/London] │
1966
+ ╞═════════════════════════╪═════════════════════════════╡
1967
+ │ 2020-03-01 00:00:00 UTC ┆ 2020-03-01 00:00:00 GMT │
1968
+ │ 2020-04-01 00:00:00 UTC ┆ 2020-04-01 01:00:00 BST │
1969
+ │ 2020-05-01 00:00:00 UTC ┆ 2020-05-01 01:00:00 BST │
1970
+ └─────────────────────────┴─────────────────────────────┘
1971
+ """
1972
+ return wrap_expr(self._pyexpr.dt_convert_time_zone(time_zone))
1973
+
1974
+ def replace_time_zone(
1975
+ self,
1976
+ time_zone: str | None,
1977
+ *,
1978
+ ambiguous: Ambiguous | Expr = "raise",
1979
+ non_existent: NonExistent = "raise",
1980
+ ) -> Expr:
1981
+ """
1982
+ Replace time zone for an expression of type Datetime.
1983
+
1984
+ Different from `convert_time_zone`, this will also modify
1985
+ the underlying timestamp and will ignore the original time zone.
1986
+
1987
+ Parameters
1988
+ ----------
1989
+ time_zone
1990
+ Time zone for the `Datetime` expression. Pass `None` to unset time zone.
1991
+ ambiguous
1992
+ Determine how to deal with ambiguous datetimes:
1993
+
1994
+ - `'raise'` (default): raise
1995
+ - `'earliest'`: use the earliest datetime
1996
+ - `'latest'`: use the latest datetime
1997
+ - `'null'`: set to null
1998
+ non_existent
1999
+ Determine how to deal with non-existent datetimes:
2000
+
2001
+ - `'raise'` (default): raise
2002
+ - `'null'`: set to null
2003
+
2004
+ Examples
2005
+ --------
2006
+ >>> from datetime import datetime
2007
+ >>> df = pl.DataFrame(
2008
+ ... {
2009
+ ... "london_timezone": pl.datetime_range(
2010
+ ... datetime(2020, 3, 1),
2011
+ ... datetime(2020, 7, 1),
2012
+ ... "1mo",
2013
+ ... time_zone="UTC",
2014
+ ... eager=True,
2015
+ ... ).dt.convert_time_zone(time_zone="Europe/London"),
2016
+ ... }
2017
+ ... )
2018
+ >>> df.select(
2019
+ ... [
2020
+ ... pl.col("london_timezone"),
2021
+ ... pl.col("london_timezone")
2022
+ ... .dt.replace_time_zone(time_zone="Europe/Amsterdam")
2023
+ ... .alias("London_to_Amsterdam"),
2024
+ ... ]
2025
+ ... )
2026
+ shape: (5, 2)
2027
+ ┌─────────────────────────────┬────────────────────────────────┐
2028
+ │ london_timezone ┆ London_to_Amsterdam │
2029
+ │ --- ┆ --- │
2030
+ │ datetime[μs, Europe/London] ┆ datetime[μs, Europe/Amsterdam] │
2031
+ ╞═════════════════════════════╪════════════════════════════════╡
2032
+ │ 2020-03-01 00:00:00 GMT ┆ 2020-03-01 00:00:00 CET │
2033
+ │ 2020-04-01 01:00:00 BST ┆ 2020-04-01 01:00:00 CEST │
2034
+ │ 2020-05-01 01:00:00 BST ┆ 2020-05-01 01:00:00 CEST │
2035
+ │ 2020-06-01 01:00:00 BST ┆ 2020-06-01 01:00:00 CEST │
2036
+ │ 2020-07-01 01:00:00 BST ┆ 2020-07-01 01:00:00 CEST │
2037
+ └─────────────────────────────┴────────────────────────────────┘
2038
+
2039
+ You can use `ambiguous` to deal with ambiguous datetimes:
2040
+
2041
+ >>> dates = [
2042
+ ... "2018-10-28 01:30",
2043
+ ... "2018-10-28 02:00",
2044
+ ... "2018-10-28 02:30",
2045
+ ... "2018-10-28 02:00",
2046
+ ... ]
2047
+ >>> df = pl.DataFrame(
2048
+ ... {
2049
+ ... "ts": pl.Series(dates).str.strptime(pl.Datetime),
2050
+ ... "ambiguous": ["earliest", "earliest", "latest", "latest"],
2051
+ ... }
2052
+ ... )
2053
+ >>> df.with_columns(
2054
+ ... ts_localized=pl.col("ts").dt.replace_time_zone(
2055
+ ... "Europe/Brussels", ambiguous=pl.col("ambiguous")
2056
+ ... )
2057
+ ... )
2058
+ shape: (4, 3)
2059
+ ┌─────────────────────┬───────────┬───────────────────────────────┐
2060
+ │ ts ┆ ambiguous ┆ ts_localized │
2061
+ │ --- ┆ --- ┆ --- │
2062
+ │ datetime[μs] ┆ str ┆ datetime[μs, Europe/Brussels] │
2063
+ ╞═════════════════════╪═══════════╪═══════════════════════════════╡
2064
+ │ 2018-10-28 01:30:00 ┆ earliest ┆ 2018-10-28 01:30:00 CEST │
2065
+ │ 2018-10-28 02:00:00 ┆ earliest ┆ 2018-10-28 02:00:00 CEST │
2066
+ │ 2018-10-28 02:30:00 ┆ latest ┆ 2018-10-28 02:30:00 CET │
2067
+ │ 2018-10-28 02:00:00 ┆ latest ┆ 2018-10-28 02:00:00 CET │
2068
+ └─────────────────────┴───────────┴───────────────────────────────┘
2069
+ """
2070
+ if not isinstance(ambiguous, pl.Expr):
2071
+ ambiguous = F.lit(ambiguous)
2072
+ return wrap_expr(
2073
+ self._pyexpr.dt_replace_time_zone(
2074
+ time_zone, ambiguous._pyexpr, non_existent
2075
+ )
2076
+ )
2077
+
2078
+ def total_days(self) -> Expr:
2079
+ """
2080
+ Extract the total days from a Duration type.
2081
+
2082
+ Returns
2083
+ -------
2084
+ Expr
2085
+ Expression of data type :class:`Int64`.
2086
+
2087
+ Examples
2088
+ --------
2089
+ >>> from datetime import datetime
2090
+ >>> df = pl.DataFrame(
2091
+ ... {
2092
+ ... "date": pl.datetime_range(
2093
+ ... datetime(2020, 3, 1), datetime(2020, 5, 1), "1mo", eager=True
2094
+ ... ),
2095
+ ... }
2096
+ ... )
2097
+ >>> df.select(
2098
+ ... [
2099
+ ... pl.col("date"),
2100
+ ... pl.col("date").diff().dt.total_days().alias("days_diff"),
2101
+ ... ]
2102
+ ... )
2103
+ shape: (3, 2)
2104
+ ┌─────────────────────┬───────────┐
2105
+ │ date ┆ days_diff │
2106
+ │ --- ┆ --- │
2107
+ │ datetime[μs] ┆ i64 │
2108
+ ╞═════════════════════╪═══════════╡
2109
+ │ 2020-03-01 00:00:00 ┆ null │
2110
+ │ 2020-04-01 00:00:00 ┆ 31 │
2111
+ │ 2020-05-01 00:00:00 ┆ 30 │
2112
+ └─────────────────────┴───────────┘
2113
+ """
2114
+ return wrap_expr(self._pyexpr.dt_total_days())
2115
+
2116
+ def total_hours(self) -> Expr:
2117
+ """
2118
+ Extract the total hours from a Duration type.
2119
+
2120
+ Returns
2121
+ -------
2122
+ Expr
2123
+ Expression of data type :class:`Int64`.
2124
+
2125
+ Examples
2126
+ --------
2127
+ >>> from datetime import datetime
2128
+ >>> df = pl.DataFrame(
2129
+ ... {
2130
+ ... "date": pl.datetime_range(
2131
+ ... datetime(2020, 1, 1), datetime(2020, 1, 4), "1d", eager=True
2132
+ ... ),
2133
+ ... }
2134
+ ... )
2135
+ >>> df.select(
2136
+ ... [
2137
+ ... pl.col("date"),
2138
+ ... pl.col("date").diff().dt.total_hours().alias("hours_diff"),
2139
+ ... ]
2140
+ ... )
2141
+ shape: (4, 2)
2142
+ ┌─────────────────────┬────────────┐
2143
+ │ date ┆ hours_diff │
2144
+ │ --- ┆ --- │
2145
+ │ datetime[μs] ┆ i64 │
2146
+ ╞═════════════════════╪════════════╡
2147
+ │ 2020-01-01 00:00:00 ┆ null │
2148
+ │ 2020-01-02 00:00:00 ┆ 24 │
2149
+ │ 2020-01-03 00:00:00 ┆ 24 │
2150
+ │ 2020-01-04 00:00:00 ┆ 24 │
2151
+ └─────────────────────┴────────────┘
2152
+ """
2153
+ return wrap_expr(self._pyexpr.dt_total_hours())
2154
+
2155
+ def total_minutes(self) -> Expr:
2156
+ """
2157
+ Extract the total minutes from a Duration type.
2158
+
2159
+ Returns
2160
+ -------
2161
+ Expr
2162
+ Expression of data type :class:`Int64`.
2163
+
2164
+ Examples
2165
+ --------
2166
+ >>> from datetime import datetime
2167
+ >>> df = pl.DataFrame(
2168
+ ... {
2169
+ ... "date": pl.datetime_range(
2170
+ ... datetime(2020, 1, 1), datetime(2020, 1, 4), "1d", eager=True
2171
+ ... ),
2172
+ ... }
2173
+ ... )
2174
+ >>> df.select(
2175
+ ... [
2176
+ ... pl.col("date"),
2177
+ ... pl.col("date").diff().dt.total_minutes().alias("minutes_diff"),
2178
+ ... ]
2179
+ ... )
2180
+ shape: (4, 2)
2181
+ ┌─────────────────────┬──────────────┐
2182
+ │ date ┆ minutes_diff │
2183
+ │ --- ┆ --- │
2184
+ │ datetime[μs] ┆ i64 │
2185
+ ╞═════════════════════╪══════════════╡
2186
+ │ 2020-01-01 00:00:00 ┆ null │
2187
+ │ 2020-01-02 00:00:00 ┆ 1440 │
2188
+ │ 2020-01-03 00:00:00 ┆ 1440 │
2189
+ │ 2020-01-04 00:00:00 ┆ 1440 │
2190
+ └─────────────────────┴──────────────┘
2191
+ """
2192
+ return wrap_expr(self._pyexpr.dt_total_minutes())
2193
+
2194
+ def total_seconds(self) -> Expr:
2195
+ """
2196
+ Extract the total seconds from a Duration type.
2197
+
2198
+ Returns
2199
+ -------
2200
+ Expr
2201
+ Expression of data type :class:`Int64`.
2202
+
2203
+ Examples
2204
+ --------
2205
+ >>> from datetime import datetime
2206
+ >>> df = pl.DataFrame(
2207
+ ... {
2208
+ ... "date": pl.datetime_range(
2209
+ ... datetime(2020, 1, 1),
2210
+ ... datetime(2020, 1, 1, 0, 4, 0),
2211
+ ... "1m",
2212
+ ... eager=True,
2213
+ ... ),
2214
+ ... }
2215
+ ... )
2216
+ >>> df.select(
2217
+ ... pl.col("date"),
2218
+ ... pl.col("date").diff().dt.total_seconds().alias("seconds_diff"),
2219
+ ... )
2220
+ shape: (5, 2)
2221
+ ┌─────────────────────┬──────────────┐
2222
+ │ date ┆ seconds_diff │
2223
+ │ --- ┆ --- │
2224
+ │ datetime[μs] ┆ i64 │
2225
+ ╞═════════════════════╪══════════════╡
2226
+ │ 2020-01-01 00:00:00 ┆ null │
2227
+ │ 2020-01-01 00:01:00 ┆ 60 │
2228
+ │ 2020-01-01 00:02:00 ┆ 60 │
2229
+ │ 2020-01-01 00:03:00 ┆ 60 │
2230
+ │ 2020-01-01 00:04:00 ┆ 60 │
2231
+ └─────────────────────┴──────────────┘
2232
+ """
2233
+ return wrap_expr(self._pyexpr.dt_total_seconds())
2234
+
2235
+ def total_milliseconds(self) -> Expr:
2236
+ """
2237
+ Extract the total milliseconds from a Duration type.
2238
+
2239
+ Returns
2240
+ -------
2241
+ Expr
2242
+ Expression of data type :class:`Int64`.
2243
+
2244
+ Examples
2245
+ --------
2246
+ >>> from datetime import datetime
2247
+ >>> df = pl.DataFrame(
2248
+ ... {
2249
+ ... "date": pl.datetime_range(
2250
+ ... datetime(2020, 1, 1),
2251
+ ... datetime(2020, 1, 1, 0, 0, 1, 0),
2252
+ ... "200ms",
2253
+ ... eager=True,
2254
+ ... ),
2255
+ ... }
2256
+ ... )
2257
+ >>> df.select(
2258
+ ... pl.col("date"),
2259
+ ... milliseconds_diff=pl.col("date").diff().dt.total_milliseconds(),
2260
+ ... )
2261
+ shape: (6, 2)
2262
+ ┌─────────────────────────┬───────────────────┐
2263
+ │ date ┆ milliseconds_diff │
2264
+ │ --- ┆ --- │
2265
+ │ datetime[μs] ┆ i64 │
2266
+ ╞═════════════════════════╪═══════════════════╡
2267
+ │ 2020-01-01 00:00:00 ┆ null │
2268
+ │ 2020-01-01 00:00:00.200 ┆ 200 │
2269
+ │ 2020-01-01 00:00:00.400 ┆ 200 │
2270
+ │ 2020-01-01 00:00:00.600 ┆ 200 │
2271
+ │ 2020-01-01 00:00:00.800 ┆ 200 │
2272
+ │ 2020-01-01 00:00:01 ┆ 200 │
2273
+ └─────────────────────────┴───────────────────┘
2274
+ """
2275
+ return wrap_expr(self._pyexpr.dt_total_milliseconds())
2276
+
2277
+ def total_microseconds(self) -> Expr:
2278
+ """
2279
+ Extract the total microseconds from a Duration type.
2280
+
2281
+ Returns
2282
+ -------
2283
+ Expr
2284
+ Expression of data type :class:`Int64`.
2285
+
2286
+ Examples
2287
+ --------
2288
+ >>> from datetime import datetime
2289
+ >>> df = pl.DataFrame(
2290
+ ... {
2291
+ ... "date": pl.datetime_range(
2292
+ ... datetime(2020, 1, 1),
2293
+ ... datetime(2020, 1, 1, 0, 0, 1, 0),
2294
+ ... "200ms",
2295
+ ... eager=True,
2296
+ ... ),
2297
+ ... }
2298
+ ... )
2299
+ >>> df.select(
2300
+ ... pl.col("date"),
2301
+ ... milliseconds_diff=pl.col("date").diff().dt.total_microseconds(),
2302
+ ... )
2303
+ shape: (6, 2)
2304
+ ┌─────────────────────────┬───────────────────┐
2305
+ │ date ┆ milliseconds_diff │
2306
+ │ --- ┆ --- │
2307
+ │ datetime[μs] ┆ i64 │
2308
+ ╞═════════════════════════╪═══════════════════╡
2309
+ │ 2020-01-01 00:00:00 ┆ null │
2310
+ │ 2020-01-01 00:00:00.200 ┆ 200000 │
2311
+ │ 2020-01-01 00:00:00.400 ┆ 200000 │
2312
+ │ 2020-01-01 00:00:00.600 ┆ 200000 │
2313
+ │ 2020-01-01 00:00:00.800 ┆ 200000 │
2314
+ │ 2020-01-01 00:00:01 ┆ 200000 │
2315
+ └─────────────────────────┴───────────────────┘
2316
+ """
2317
+ return wrap_expr(self._pyexpr.dt_total_microseconds())
2318
+
2319
+ def total_nanoseconds(self) -> Expr:
2320
+ """
2321
+ Extract the total nanoseconds from a Duration type.
2322
+
2323
+ Returns
2324
+ -------
2325
+ Expr
2326
+ Expression of data type :class:`Int64`.
2327
+
2328
+ Examples
2329
+ --------
2330
+ >>> from datetime import datetime
2331
+ >>> df = pl.DataFrame(
2332
+ ... {
2333
+ ... "date": pl.datetime_range(
2334
+ ... datetime(2020, 1, 1),
2335
+ ... datetime(2020, 1, 1, 0, 0, 1, 0),
2336
+ ... "200ms",
2337
+ ... eager=True,
2338
+ ... ),
2339
+ ... }
2340
+ ... )
2341
+ >>> df.select(
2342
+ ... pl.col("date"),
2343
+ ... milliseconds_diff=pl.col("date").diff().dt.total_nanoseconds(),
2344
+ ... )
2345
+ shape: (6, 2)
2346
+ ┌─────────────────────────┬───────────────────┐
2347
+ │ date ┆ milliseconds_diff │
2348
+ │ --- ┆ --- │
2349
+ │ datetime[μs] ┆ i64 │
2350
+ ╞═════════════════════════╪═══════════════════╡
2351
+ │ 2020-01-01 00:00:00 ┆ null │
2352
+ │ 2020-01-01 00:00:00.200 ┆ 200000000 │
2353
+ │ 2020-01-01 00:00:00.400 ┆ 200000000 │
2354
+ │ 2020-01-01 00:00:00.600 ┆ 200000000 │
2355
+ │ 2020-01-01 00:00:00.800 ┆ 200000000 │
2356
+ │ 2020-01-01 00:00:01 ┆ 200000000 │
2357
+ └─────────────────────────┴───────────────────┘
2358
+ """
2359
+ return wrap_expr(self._pyexpr.dt_total_nanoseconds())
2360
+
2361
+ def offset_by(self, by: str | Expr) -> Expr:
2362
+ """
2363
+ Offset this date by a relative time offset.
2364
+
2365
+ This differs from `pl.col("foo") + timedelta` in that it can
2366
+ take months and leap years into account. Note that only a single minus
2367
+ sign is allowed in the `by` string, as the first character.
2368
+
2369
+ Parameters
2370
+ ----------
2371
+ by
2372
+ The offset is dictated by the following string language:
2373
+
2374
+ - 1ns (1 nanosecond)
2375
+ - 1us (1 microsecond)
2376
+ - 1ms (1 millisecond)
2377
+ - 1s (1 second)
2378
+ - 1m (1 minute)
2379
+ - 1h (1 hour)
2380
+ - 1d (1 calendar day)
2381
+ - 1w (1 calendar week)
2382
+ - 1mo (1 calendar month)
2383
+ - 1q (1 calendar quarter)
2384
+ - 1y (1 calendar year)
2385
+
2386
+ By "calendar day", we mean the corresponding time on the next day (which may
2387
+ not be 24 hours, due to daylight savings). Similarly for "calendar week",
2388
+ "calendar month", "calendar quarter", and "calendar year".
2389
+
2390
+ Returns
2391
+ -------
2392
+ Expr
2393
+ Expression of data type :class:`Date` or :class:`Datetime`.
2394
+
2395
+ Examples
2396
+ --------
2397
+ >>> from datetime import datetime
2398
+ >>> df = pl.DataFrame(
2399
+ ... {
2400
+ ... "dates": pl.datetime_range(
2401
+ ... datetime(2000, 1, 1), datetime(2005, 1, 1), "1y", eager=True
2402
+ ... ),
2403
+ ... "offset": ["1d", "2d", "-1d", "1mo", None, "1y"],
2404
+ ... }
2405
+ ... )
2406
+ >>> df.select(
2407
+ ... [
2408
+ ... pl.col("dates").dt.offset_by("1y").alias("date_plus_1y"),
2409
+ ... pl.col("dates").dt.offset_by("-1y2mo").alias("date_min"),
2410
+ ... ]
2411
+ ... )
2412
+ shape: (6, 2)
2413
+ ┌─────────────────────┬─────────────────────┐
2414
+ │ date_plus_1y ┆ date_min │
2415
+ │ --- ┆ --- │
2416
+ │ datetime[μs] ┆ datetime[μs] │
2417
+ ╞═════════════════════╪═════════════════════╡
2418
+ │ 2001-01-01 00:00:00 ┆ 1998-11-01 00:00:00 │
2419
+ │ 2002-01-01 00:00:00 ┆ 1999-11-01 00:00:00 │
2420
+ │ 2003-01-01 00:00:00 ┆ 2000-11-01 00:00:00 │
2421
+ │ 2004-01-01 00:00:00 ┆ 2001-11-01 00:00:00 │
2422
+ │ 2005-01-01 00:00:00 ┆ 2002-11-01 00:00:00 │
2423
+ │ 2006-01-01 00:00:00 ┆ 2003-11-01 00:00:00 │
2424
+ └─────────────────────┴─────────────────────┘
2425
+
2426
+ You can also pass the relative offset as an expression:
2427
+
2428
+ >>> df.with_columns(new_dates=pl.col("dates").dt.offset_by(pl.col("offset")))
2429
+ shape: (6, 3)
2430
+ ┌─────────────────────┬────────┬─────────────────────┐
2431
+ │ dates ┆ offset ┆ new_dates │
2432
+ │ --- ┆ --- ┆ --- │
2433
+ │ datetime[μs] ┆ str ┆ datetime[μs] │
2434
+ ╞═════════════════════╪════════╪═════════════════════╡
2435
+ │ 2000-01-01 00:00:00 ┆ 1d ┆ 2000-01-02 00:00:00 │
2436
+ │ 2001-01-01 00:00:00 ┆ 2d ┆ 2001-01-03 00:00:00 │
2437
+ │ 2002-01-01 00:00:00 ┆ -1d ┆ 2001-12-31 00:00:00 │
2438
+ │ 2003-01-01 00:00:00 ┆ 1mo ┆ 2003-02-01 00:00:00 │
2439
+ │ 2004-01-01 00:00:00 ┆ null ┆ null │
2440
+ │ 2005-01-01 00:00:00 ┆ 1y ┆ 2006-01-01 00:00:00 │
2441
+ └─────────────────────┴────────┴─────────────────────┘
2442
+ """
2443
+ by_pyexpr = parse_into_expression(by, str_as_lit=True)
2444
+ return wrap_expr(self._pyexpr.dt_offset_by(by_pyexpr))
2445
+
2446
+ def month_start(self) -> Expr:
2447
+ """
2448
+ Roll backward to the first day of the month.
2449
+
2450
+ For datetimes, the time-of-day is preserved.
2451
+
2452
+ Returns
2453
+ -------
2454
+ Expr
2455
+ Expression of data type :class:`Date` or :class:`Datetime`.
2456
+
2457
+ Notes
2458
+ -----
2459
+ If you're coming from pandas, you can think of this as a vectorised version
2460
+ of `pandas.tseries.offsets.MonthBegin().rollback(datetime)`.
2461
+
2462
+ Examples
2463
+ --------
2464
+ >>> from datetime import datetime
2465
+ >>> df = pl.DataFrame(
2466
+ ... {
2467
+ ... "dates": pl.datetime_range(
2468
+ ... datetime(2000, 1, 15, 2),
2469
+ ... datetime(2000, 12, 15, 2),
2470
+ ... "1mo",
2471
+ ... eager=True,
2472
+ ... )
2473
+ ... }
2474
+ ... )
2475
+ >>> df.select(pl.col("dates").dt.month_start())
2476
+ shape: (12, 1)
2477
+ ┌─────────────────────┐
2478
+ │ dates │
2479
+ │ --- │
2480
+ │ datetime[μs] │
2481
+ ╞═════════════════════╡
2482
+ │ 2000-01-01 02:00:00 │
2483
+ │ 2000-02-01 02:00:00 │
2484
+ │ 2000-03-01 02:00:00 │
2485
+ │ 2000-04-01 02:00:00 │
2486
+ │ 2000-05-01 02:00:00 │
2487
+ │ … │
2488
+ │ 2000-08-01 02:00:00 │
2489
+ │ 2000-09-01 02:00:00 │
2490
+ │ 2000-10-01 02:00:00 │
2491
+ │ 2000-11-01 02:00:00 │
2492
+ │ 2000-12-01 02:00:00 │
2493
+ └─────────────────────┘
2494
+ """
2495
+ return wrap_expr(self._pyexpr.dt_month_start())
2496
+
2497
+ def month_end(self) -> Expr:
2498
+ """
2499
+ Roll forward to the last day of the month.
2500
+
2501
+ For datetimes, the time-of-day is preserved.
2502
+
2503
+ Returns
2504
+ -------
2505
+ Expr
2506
+ Expression of data type :class:`Date` or :class:`Datetime`.
2507
+
2508
+ Notes
2509
+ -----
2510
+ If you're coming from pandas, you can think of this as a vectorised version
2511
+ of `pandas.tseries.offsets.MonthEnd().rollforward(datetime)`.
2512
+
2513
+ Examples
2514
+ --------
2515
+ >>> from datetime import datetime
2516
+ >>> df = pl.DataFrame(
2517
+ ... {
2518
+ ... "dates": pl.datetime_range(
2519
+ ... datetime(2000, 1, 1, 2),
2520
+ ... datetime(2000, 12, 1, 2),
2521
+ ... "1mo",
2522
+ ... eager=True,
2523
+ ... )
2524
+ ... }
2525
+ ... )
2526
+ >>> df.select(pl.col("dates").dt.month_end())
2527
+ shape: (12, 1)
2528
+ ┌─────────────────────┐
2529
+ │ dates │
2530
+ │ --- │
2531
+ │ datetime[μs] │
2532
+ ╞═════════════════════╡
2533
+ │ 2000-01-31 02:00:00 │
2534
+ │ 2000-02-29 02:00:00 │
2535
+ │ 2000-03-31 02:00:00 │
2536
+ │ 2000-04-30 02:00:00 │
2537
+ │ 2000-05-31 02:00:00 │
2538
+ │ … │
2539
+ │ 2000-08-31 02:00:00 │
2540
+ │ 2000-09-30 02:00:00 │
2541
+ │ 2000-10-31 02:00:00 │
2542
+ │ 2000-11-30 02:00:00 │
2543
+ │ 2000-12-31 02:00:00 │
2544
+ └─────────────────────┘
2545
+ """
2546
+ return wrap_expr(self._pyexpr.dt_month_end())
2547
+
2548
+ def base_utc_offset(self) -> Expr:
2549
+ """
2550
+ Base offset from UTC.
2551
+
2552
+ This is usually constant for all datetimes in a given time zone, but
2553
+ may vary in the rare case that a country switches time zone, like
2554
+ Samoa (Apia) did at the end of 2011.
2555
+
2556
+ Returns
2557
+ -------
2558
+ Expr
2559
+ Expression of data type :class:`Duration`.
2560
+
2561
+ See Also
2562
+ --------
2563
+ Expr.dt.dst_offset : Daylight savings offset from UTC.
2564
+
2565
+ Examples
2566
+ --------
2567
+ >>> from datetime import datetime
2568
+ >>> df = pl.DataFrame(
2569
+ ... {
2570
+ ... "ts": [datetime(2011, 12, 29), datetime(2012, 1, 1)],
2571
+ ... }
2572
+ ... )
2573
+ >>> df = df.with_columns(pl.col("ts").dt.replace_time_zone("Pacific/Apia"))
2574
+ >>> df.with_columns(pl.col("ts").dt.base_utc_offset().alias("base_utc_offset"))
2575
+ shape: (2, 2)
2576
+ ┌────────────────────────────┬─────────────────┐
2577
+ │ ts ┆ base_utc_offset │
2578
+ │ --- ┆ --- │
2579
+ │ datetime[μs, Pacific/Apia] ┆ duration[ms] │
2580
+ ╞════════════════════════════╪═════════════════╡
2581
+ │ 2011-12-29 00:00:00 -10 ┆ -11h │
2582
+ │ 2012-01-01 00:00:00 +14 ┆ 13h │
2583
+ └────────────────────────────┴─────────────────┘
2584
+ """
2585
+ return wrap_expr(self._pyexpr.dt_base_utc_offset())
2586
+
2587
+ def dst_offset(self) -> Expr:
2588
+ """
2589
+ Additional offset currently in effect (typically due to daylight saving time).
2590
+
2591
+ Returns
2592
+ -------
2593
+ Expr
2594
+ Expression of data type :class:`Duration`.
2595
+
2596
+ See Also
2597
+ --------
2598
+ Expr.dt.base_utc_offset : Base offset from UTC.
2599
+
2600
+ Examples
2601
+ --------
2602
+ >>> from datetime import datetime
2603
+ >>> df = pl.DataFrame(
2604
+ ... {
2605
+ ... "ts": [datetime(2020, 10, 25), datetime(2020, 10, 26)],
2606
+ ... }
2607
+ ... )
2608
+ >>> df = df.with_columns(pl.col("ts").dt.replace_time_zone("Europe/London"))
2609
+ >>> df.with_columns(pl.col("ts").dt.dst_offset().alias("dst_offset"))
2610
+ shape: (2, 2)
2611
+ ┌─────────────────────────────┬──────────────┐
2612
+ │ ts ┆ dst_offset │
2613
+ │ --- ┆ --- │
2614
+ │ datetime[μs, Europe/London] ┆ duration[ms] │
2615
+ ╞═════════════════════════════╪══════════════╡
2616
+ │ 2020-10-25 00:00:00 BST ┆ 1h │
2617
+ │ 2020-10-26 00:00:00 GMT ┆ 0ms │
2618
+ └─────────────────────────────┴──────────────┘
2619
+ """
2620
+ return wrap_expr(self._pyexpr.dt_dst_offset())