dately 3.0.2__tar.gz → 3.2.0__tar.gz
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.
- dately-3.2.0/MANIFEST.in +1 -0
- {dately-3.0.2 → dately-3.2.0}/PKG-INFO +89 -87
- {dately-3.0.2 → dately-3.2.0}/README.md +87 -85
- dately-3.2.0/dately/__envutils.py +41 -0
- dately-3.2.0/dately/__init__.py +269 -0
- dately-3.2.0/dately/__os_config.py +105 -0
- dately-3.2.0/dately/__user_agents_config.py +48 -0
- dately-3.2.0/dately/_api.py +52 -0
- dately-3.2.0/dately/_connect.py +411 -0
- dately-3.2.0/dately/_datetime_scan.py +1658 -0
- dately-3.0.2/dately/holiday.py → dately-3.2.0/dately/_holiday.py +108 -39
- dately-3.2.0/dately/_log.py +14 -0
- dately-3.2.0/dately/_mskutils.py +123 -0
- dately-3.2.0/dately/_proxy.py +43 -0
- dately-3.2.0/dately/_sysutils.py +207 -0
- dately-3.2.0/dately/_temporal_scan.py +2770 -0
- dately-3.2.0/dately/_timeutils.py +360 -0
- dately-3.0.2/dately/timezone.py → dately-3.2.0/dately/_timezone.py +41 -32
- dately-3.0.2/dately/utils.py → dately-3.2.0/dately/_utils.py +19 -7
- dately-3.2.0/dately/_version.py +12 -0
- dately-3.2.0/dately/_webutils.py +199 -0
- dately-3.2.0/dately/core.py +716 -0
- dately-3.2.0/dately/dt_nlp/__init__.py +44 -0
- dately-3.2.0/dately/dt_nlp/arithmetic.py +1347 -0
- dately-3.2.0/dately/dt_nlp/lexical_validation/vocabulary_checks.py +121 -0
- dately-3.2.0/dately/dt_nlp/quantified_time.py +233 -0
- dately-3.2.0/dately/dt_nlp/relative_time.py +433 -0
- dately-3.2.0/dately/dt_nlp/semantic_validation/unit_bounds.py +395 -0
- dately-3.2.0/dately/dt_nlp/string_similarity/spell_correction.py +893 -0
- dately-3.2.0/dately/dt_nlp/syntactic_validation/__init__.py +0 -0
- dately-3.2.0/dately/dt_nlp/syntactic_validation/structure_validator.py +333 -0
- dately-3.2.0/dately/dt_nlp/syntactic_validation/temporal_structure_rules.py +613 -0
- dately-3.2.0/dately/dt_nlp/temporal_core/__init__.py +0 -0
- dately-3.2.0/dately/dt_nlp/temporal_core/temporal_units.py +347 -0
- dately-3.2.0/dately/dt_nlp/temporal_preprocessing.py +1406 -0
- dately-3.2.0/dately/files/__init__.py +0 -0
- dately-3.2.0/dately/files/country_variants.json +293 -0
- dately-3.2.0/dately/files/holiday.json +934 -0
- dately-3.2.0/dately/files/os_versions.json +5 -0
- dately-3.2.0/dately/files/user_agents.json +26 -0
- dately-3.2.0/dately/mold/__init__.py +0 -0
- dately-3.2.0/dately/mold/pyd/Compiled.cp38-win_amd64.pyd +0 -0
- dately-3.2.0/dately/mold/pyd/__init__.py +0 -0
- dately-3.2.0/dately/mold/pyd/cdatetime/__init__.py +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyx/Compiled.pyx +41 -26
- dately-3.2.0/dately/mold/pyx/UniversalDateFormatter.pyx +388 -0
- dately-3.2.0/dately/mold/pyx/whichformat.pyx +911 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/Compiled.c +282 -282
- {dately-3.0.2/dately/sources → dately-3.2.0/dately/tests}/__init__.py +0 -1
- dately-3.2.0/dately/tests/test_parse.py +39 -0
- {dately-3.0.2 → dately-3.2.0}/dately.egg-info/PKG-INFO +89 -87
- {dately-3.0.2 → dately-3.2.0}/dately.egg-info/SOURCES.txt +42 -11
- dately-3.2.0/dately.egg-info/requires.txt +9 -0
- {dately-3.0.2 → dately-3.2.0}/setup.py +99 -43
- dately-3.0.2/dately/__init__.py +0 -7
- dately-3.0.2/dately/connect.py +0 -352
- dately-3.0.2/dately/core.py +0 -534
- dately-3.0.2/dately/mold/pyd/Compiled.cp38-win_amd64.pyd +0 -0
- dately-3.0.2/dately/mold/pyx/UniversalDateFormatter.pyx +0 -189
- dately-3.0.2/dately/mold/pyx/whichformat.pyx +0 -331
- dately-3.0.2/dately/mskutils.py +0 -81
- dately-3.0.2/dately/sources/holiday.json +0 -934
- dately-3.0.2/dately/sysutils.py +0 -125
- dately-3.0.2/dately/timeutils.py +0 -362
- dately-3.0.2/dately/webutils.py +0 -34
- dately-3.0.2/dately.egg-info/requires.txt +0 -4
- {dately-3.0.2/dately/mold → dately-3.2.0/dately/dt_nlp/lexical_validation}/__init__.py +0 -0
- {dately-3.0.2/dately/mold/pyd → dately-3.2.0/dately/dt_nlp/semantic_validation}/__init__.py +0 -0
- {dately-3.0.2/dately/mold/pyd/cdatetime → dately-3.2.0/dately/dt_nlp/string_similarity}/__init__.py +0 -0
- {dately-3.0.2/dately/sources → dately-3.2.0/dately/files}/timezone_data.json +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/include/clean_str.h +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/include/iso8601T.h +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/include/iso8601Z.h +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/include/root_dir_search.h +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/include/time_zones.h +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/cdatetime/UniversalDateFormatter.cp38-win_amd64.pyd +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/cdatetime/iso8601T.cp38-win_amd64.pyd +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/cdatetime/iso8601Z.cp38-win_amd64.pyd +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/cdatetime/whichformat.cp38-win_amd64.pyd +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/clean_str.cp38-win_amd64.pyd +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/time_zones.cp38-win_amd64.pyd +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyx/clean_str.pyx +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyx/iso8601T.pyx +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyx/iso8601Z.pyx +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/pyx/time_zones.pyx +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/UniversalDateFormatter.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/clean_str.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/clean_str_impl.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/iso8601T.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/iso8601T_impl.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/iso8601Z.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/iso8601Z_impl.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/root_dir_search_impl.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/time_zones.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/time_zones_impl.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately/mold/src/whichformat.c +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately.egg-info/dependency_links.txt +0 -0
- {dately-3.0.2 → dately-3.2.0}/dately.egg-info/top_level.txt +0 -0
- {dately-3.0.2 → dately-3.2.0}/setup.cfg +0 -0
dately-3.2.0/MANIFEST.in
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include dately/files *.json
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dately
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: A comprehensive Python library for advanced date and time manipulation.
|
|
5
|
-
Home-page: https://github.com/cedricmoorejr/dately/tree/v3.0
|
|
5
|
+
Home-page: https://github.com/cedricmoorejr/dately/tree/v3.2.0
|
|
6
6
|
Author: Cedric Moore Jr.
|
|
7
7
|
Author-email: cedricmoorejunior5@gmail.com
|
|
8
8
|
License: MIT
|
|
9
|
-
Project-URL: Source Code, https://github.com/cedricmoorejr/dately/releases/tag/v3.0
|
|
9
|
+
Project-URL: Source Code, https://github.com/cedricmoorejr/dately/releases/tag/v3.2.0
|
|
10
10
|
Classifier: Programming Language :: Python :: 3
|
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
|
12
12
|
Classifier: Operating System :: Microsoft :: Windows
|
|
@@ -23,17 +23,16 @@ Description-Content-Type: text/markdown
|
|
|
23
23
|
<img src="https://raw.githubusercontent.com/cedricmoorejr/dately/main/dately/assets/py_dately_logo.png" alt="Dately Logo" width="700"/>
|
|
24
24
|
</p>
|
|
25
25
|
|
|
26
|
-
###
|
|
27
|
-
|
|
26
|
+
### dately: Comprehensive Date, Time **& Natural-Language** Handling in Python
|
|
28
27
|
|
|
29
28
|
[](https://pepy.tech/project/dately)
|
|
30
29
|
[](https://pepy.tech/project/dately)
|
|
31
30
|
[](https://pepy.tech/project/dately)
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
`dately` is an end-to-end date-and-time toolkit that now pairs its high-precision formatting utilities with a **mini natural-language-processing (NLP) engine**. Whether you feed it an ISO-8601 timestamp, a plain month/day string, or a phrase like “second Tuesday of next quarter”, dately can turn it into an exact `datetime` object or `(start, end)` range.
|
|
34
33
|
|
|
35
34
|
#### Table of Contents
|
|
36
|
-
1. [Why Choose
|
|
35
|
+
1. [Why Choose dately?](#why-choose-dately)
|
|
37
36
|
2. [Key Features](#key-features)
|
|
38
37
|
3. [Solving Windows Date Formatting Issues](#solving-windows-date-formatting-issues)
|
|
39
38
|
4. [Usage Examples - Working with Date Strings](#usage-examples---working-with-date-strings)
|
|
@@ -47,36 +46,42 @@ The `dately` module is a comprehensive library designed for advanced date and ti
|
|
|
47
46
|
5. [Working with Time Zones](#working-with-time-zones)
|
|
48
47
|
- [Retrieving Time Zone Information](#retrieving-time-zone-information)
|
|
49
48
|
- [Time Zone Operations](#time-zone-operations)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
|
|
49
|
+
6. [Natural Language Parsing (NLP)](#natural-language-parsing-nlp)
|
|
50
|
+
- [Overview](#overview)
|
|
51
|
+
- [Basic Usage](#basic-usage)
|
|
52
|
+
- [Phrase Examples](#phrase-examples)
|
|
53
|
+
- [Customizing Week Start](#customizing-week-start)
|
|
54
|
+
|
|
55
|
+
#### Why Choose dately?
|
|
56
|
+
- **Windows Optimized** – fixes `%‐m`/#zero-suppression inconsistencies on Windows.
|
|
57
|
+
- **NLP Inside** – understands expressions such as “last 5 weekends”, “Q4 2026”, “3 days ago starting from April 10”.
|
|
58
|
+
- **Comprehensive API** – parsing, detection, extraction and conversion for raw strings, `datetime` objects, pandas Series, NumPy arrays **and** free-text phrases.
|
|
59
|
+
- **High Performance** – Python + Cython hot-paths for heavy string/date workloads.
|
|
56
60
|
|
|
57
61
|
#### Key Features
|
|
58
|
-
|
|
59
62
|
1. **Date and Time Format Detection**:
|
|
60
63
|
- Automatically detect various date and time formats from strings, ensuring seamless parsing and conversion.
|
|
61
64
|
- Supports a wide range of date formats, including standard and unique custom formats.
|
|
62
|
-
|
|
63
65
|
2. **Timezone Management**:
|
|
64
66
|
- Provides detailed information for specific time zones.
|
|
65
67
|
- Converts time from one time zone to another.
|
|
66
68
|
- Retrieves the current time for specific time zones.
|
|
67
69
|
- Categorizes time zones by country, offset, and daylight saving time observance.
|
|
68
|
-
|
|
69
70
|
3. **String Manipulation and Validation**:
|
|
70
71
|
- Extract specific components (year, month, day, hour, minute, second, timezone) from datetime strings.
|
|
71
72
|
- Validate and replace parts of datetime strings to ensure accuracy and consistency.
|
|
72
73
|
- Strip time and timezone information from datetime strings when needed.
|
|
73
|
-
|
|
74
74
|
4. **Performance Optimizations**:
|
|
75
75
|
- Utilizes Cython to enhance performance for computationally intensive tasks.
|
|
76
76
|
- Interfaces with underlying C code to perform high-speed string operations and date validations.
|
|
77
|
+
5. **Natural-Language Parsing** *(new!)*
|
|
78
|
+
- _Relative phrases_ `"next 2 Fridays" → [date, date]`
|
|
79
|
+
- _Range phrases_ `"first half of last year"`
|
|
80
|
+
- _Anchored clauses_ `"start of Q3 2024"`
|
|
81
|
+
- _Token normalisation_ (cardinal ↔︎ ordinal words, plural handling, etc.)
|
|
82
|
+
- Rule-based NLP pipeline: tokenisation → normalisation → pattern matching → date algebra.
|
|
77
83
|
|
|
78
84
|
#### Solving Windows Date Formatting Issues
|
|
79
|
-
|
|
80
85
|
A key aspect of this module is addressing inconsistencies in Python's date formatting on the Windows operating system. The module specifically targets the handling of the hyphen-minus (-) in date format specifiers. This flag, used to remove leading zeros from formatted output (e.g., turning '01' into '1' for January), works reliably on Unix-like systems but does not function as intended on Windows.
|
|
81
86
|
|
|
82
87
|
To solve this problem on Windows, the `dately` module introduces a workaround using regular expressions. It utilizes a detection function to determine the format string and then examines each date component for leading zeros through an extract_date_component function and a subsequent has_leading_zero check. Depending on the presence of leading zeros, the module adjusts the format string-replacing `%m` with `%-m` where applicable-to emulate the behavior expected from the hyphen-minus on Unix-like systems.
|
|
@@ -85,10 +90,9 @@ This method ensures that users on Windows achieve consistent date formatting, ef
|
|
|
85
90
|
|
|
86
91
|
Overall, `dately` is a powerful utility for anyone needing precise and flexible date and time handling in their applications, making it easier to manage, format, and validate date and time data consistently and efficiently.
|
|
87
92
|
|
|
88
|
-
## Usage Examples - Working with Date Strings
|
|
89
93
|
|
|
94
|
+
## Usage Examples - Working with Date Strings
|
|
90
95
|
### Importing the Module
|
|
91
|
-
|
|
92
96
|
```python
|
|
93
97
|
# Import module
|
|
94
98
|
import dately as dtly
|
|
@@ -108,52 +112,39 @@ datestring_array = np.array(datestring_list)
|
|
|
108
112
|
datestring_series = pd.Series(datestring_list)
|
|
109
113
|
```
|
|
110
114
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
115
|
+
---
|
|
114
116
|
### Extracting Datetime Components
|
|
115
|
-
|
|
116
117
|
#### Single Date String
|
|
117
|
-
|
|
118
118
|
```python
|
|
119
119
|
print(dtly.dt.extract_datetime_component(datestring, "year"))
|
|
120
120
|
# Output: '2023'
|
|
121
|
-
|
|
122
121
|
print(dtly.dt.extract_datetime_component(datestring, "day"))
|
|
123
122
|
# Output: '21'
|
|
124
|
-
|
|
125
123
|
print(dtly.dt.extract_datetime_component(datestring, "month"))
|
|
126
124
|
# Output: '06'
|
|
127
125
|
```
|
|
128
126
|
|
|
129
127
|
#### List of Date Strings
|
|
130
|
-
|
|
131
128
|
```python
|
|
132
129
|
print(dtly.dt.extract_datetime_component(datestring_list, "year"))
|
|
133
130
|
# Output: ['2023', '2024', '2024', '2024', '2024', '2024', '2024', '2024', '2025', '2025', '2025', '2025']
|
|
134
|
-
|
|
135
131
|
print(dtly.dt.extract_datetime_component(datestring_list, "day"))
|
|
136
132
|
# Output: ['21', '21', '21', '20', '19', '19', '18', '18', '17', '16', '18', '17']
|
|
137
|
-
|
|
138
133
|
print(dtly.dt.extract_datetime_component(datestring_list, "month"))
|
|
139
134
|
# Output: ['06', '06', '07', '08', '09', '10', '11', '12', '01', '02', '03', '04']
|
|
140
135
|
```
|
|
141
136
|
|
|
142
137
|
#### NumPy Array of Date Strings
|
|
143
|
-
|
|
144
138
|
```python
|
|
145
139
|
print(dtly.dt.extract_datetime_component(datestring_array, "year"))
|
|
146
140
|
# Output: array(['2023', '2024', '2024', '2024', '2024', '2024', '2024', '2024', '2025', '2025', '2025', '2025'], dtype=object)
|
|
147
|
-
|
|
148
141
|
print(dtly.dt.extract_datetime_component(datestring_array, "day"))
|
|
149
142
|
# Output: array(['21', '21', '21', '20', '19', '19', '18', '18', '17', '16', '18', '17'], dtype=object)
|
|
150
|
-
|
|
151
143
|
print(dtly.dt.extract_datetime_component(datestring_array, "month"))
|
|
152
144
|
# Output: array(['06', '06', '07', '08', '09', '10', '11', '12', '01', '02', '03', '04'], dtype=object)
|
|
153
145
|
```
|
|
154
146
|
|
|
155
147
|
#### Pandas Series of Date Strings
|
|
156
|
-
|
|
157
148
|
```python
|
|
158
149
|
print(dtly.dt.extract_datetime_component(datestring_series, "year"))
|
|
159
150
|
# Output:
|
|
@@ -170,7 +161,6 @@ print(dtly.dt.extract_datetime_component(datestring_series, "year"))
|
|
|
170
161
|
# 10 2025
|
|
171
162
|
# 11 2025
|
|
172
163
|
# dtype: object
|
|
173
|
-
|
|
174
164
|
print(dtly.dt.extract_datetime_component(datestring_series, "day"))
|
|
175
165
|
# Output:
|
|
176
166
|
# 0 21
|
|
@@ -186,7 +176,6 @@ print(dtly.dt.extract_datetime_component(datestring_series, "day"))
|
|
|
186
176
|
# 10 18
|
|
187
177
|
# 11 17
|
|
188
178
|
# dtype: object
|
|
189
|
-
|
|
190
179
|
print(dtly.dt.extract_datetime_component(datestring_series, "month"))
|
|
191
180
|
# Output:
|
|
192
181
|
# 0 06
|
|
@@ -205,33 +194,24 @@ print(dtly.dt.extract_datetime_component(datestring_series, "month"))
|
|
|
205
194
|
```
|
|
206
195
|
|
|
207
196
|
|
|
208
|
-
|
|
209
|
-
|
|
197
|
+
---
|
|
210
198
|
### Detecting Datetime Formats
|
|
211
|
-
|
|
212
199
|
#### Single Date String
|
|
213
|
-
|
|
214
200
|
```python
|
|
215
201
|
print(dtly.dt.detect_date_format(datestring))
|
|
216
202
|
# Output: '%Y-%m-%d'
|
|
217
203
|
```
|
|
218
|
-
|
|
219
204
|
#### List of Date Strings
|
|
220
|
-
|
|
221
205
|
```python
|
|
222
206
|
print(dtly.dt.detect_date_format(datestring_list))
|
|
223
207
|
# Output: ['%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d']
|
|
224
208
|
```
|
|
225
|
-
|
|
226
209
|
#### NumPy Array of Date Strings
|
|
227
|
-
|
|
228
210
|
```python
|
|
229
211
|
print(dtly.dt.detect_date_format(datestring_array))
|
|
230
212
|
# Output: array(['%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d', '%Y-%m-%d'], dtype=object)
|
|
231
213
|
```
|
|
232
|
-
|
|
233
214
|
#### Pandas Series of Date Strings
|
|
234
|
-
|
|
235
215
|
```python
|
|
236
216
|
print(dtly.dt.detect_date_format(datestring_series))
|
|
237
217
|
# Output:
|
|
@@ -249,26 +229,18 @@ print(dtly.dt.detect_date_format(datestring_series))
|
|
|
249
229
|
# 11 %Y-%m-%d
|
|
250
230
|
# dtype: object
|
|
251
231
|
```
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
232
|
+
---
|
|
257
233
|
### Converting Dates
|
|
258
|
-
|
|
259
234
|
```python
|
|
260
235
|
# Converting a single date string
|
|
261
236
|
print(dtly.dt.convert_date(datestring, to_format='%m.%Y/%d %I:%M %p', delta=1))
|
|
262
237
|
# Output: '06.2023/22 12:00 AM'
|
|
263
|
-
|
|
264
238
|
# Converting a list of date strings
|
|
265
239
|
print(dtly.dt.convert_date(datestring_list, to_format='%Y/%m/%d %I:%M:%S %p'))
|
|
266
240
|
# Output: ['2023/06/21 12:00:00 AM', '2024/06/21 12:00:00 AM', '2024/07/21 12:00:00 AM', '2024/08/20 12:00:00 AM', '2024/09/19 12:00:00 AM', '2024/10/19 12:00:00 AM', '2024/11/18 12:00:00 AM', '2024/12/18 12:00:00 AM', '2025/01/17 12:00:00 AM', '2025/02/16 12:00:00 AM', '2025/03/18 12:00:00 AM', '2025/04/17 12:00:00 AM']
|
|
267
|
-
|
|
268
241
|
# Converting a NumPy array of date strings
|
|
269
242
|
print(dtly.dt.convert_date(datestring_array, to_format='%y/%m-%d %H:%M'))
|
|
270
243
|
# Output: array(['23/06-21 00:00', '24/06-21 00:00', '24/07-21 00:00', '24/08-20 00:00', '24/09-19 00:00', '24/10-19 00:00', '24/11-18 00:00', '24/12-18 00:00', '25/01-17 00:00', '25/02-16 00:00', '25/03-18 00:00', '25/04-17 00:00'], dtype=object)
|
|
271
|
-
|
|
272
244
|
# Converting a Pandas Series of date strings
|
|
273
245
|
print(dtly.dt.convert_date(datestring_series, to_format='%Y.%m.%d'))
|
|
274
246
|
# Output:
|
|
@@ -286,9 +258,8 @@ print(dtly.dt.convert_date(datestring_series, to_format='%Y.%m.%d'))
|
|
|
286
258
|
# 11 2025.04.17
|
|
287
259
|
# dtype: object
|
|
288
260
|
```
|
|
289
|
-
|
|
261
|
+
---
|
|
290
262
|
### Converting Dates in Dictionaries
|
|
291
|
-
|
|
292
263
|
```python
|
|
293
264
|
# Sample dictionary with dates
|
|
294
265
|
sample_dict = {
|
|
@@ -335,30 +306,24 @@ sample_dict = {
|
|
|
335
306
|
]
|
|
336
307
|
}
|
|
337
308
|
}
|
|
338
|
-
|
|
339
309
|
# Converting dates in a dictionary
|
|
340
310
|
converted_dict = dtly.dt.convert_date(sample_dict, to_format='%Y/%m', dict_keys=["meeting_date", "date", "session_dates"])
|
|
341
311
|
print(converted_dict)
|
|
342
312
|
# Output:
|
|
343
313
|
# {'event': {'name': 'Annual Conference', 'dates': {'start_date': '2024-01-15', 'end_date': '2024-01-20'}, 'registration': {'open_date': '2023-11-01', 'close_date': '2023-12-30'}}, 'meetings': [{'title': 'Planning Meeting', 'meeting_date': '2023/10'}, {'title': 'Review Meeting', 'meeting_date': '2023/10'}], 'webinars': [{'topic': 'Introduction to the Event', 'session_dates': ['2023/11', '2023/11']}], 'workshops': {'sessions': [{'session_name': 'Workshop 1', 'date': '2024/01'}, {'session_name': 'Workshop 2', 'date': '2024/01'}]}}
|
|
344
314
|
```
|
|
345
|
-
|
|
346
|
-
|
|
315
|
+
---
|
|
347
316
|
### Replacing Datestring
|
|
348
|
-
|
|
349
317
|
```python
|
|
350
318
|
# Replacing year in a single date string
|
|
351
319
|
print(dtly.dt.replace_datestring(datestring, year=2021))
|
|
352
320
|
# Output: '2021-06-21'
|
|
353
|
-
|
|
354
321
|
# Replacing month in a single date string
|
|
355
322
|
print(dtly.dt.replace_datestring(datestring, month="5"))
|
|
356
323
|
# Output: '2023-5-21'
|
|
357
|
-
|
|
358
324
|
# Replacing day in a list of date strings
|
|
359
325
|
print(dtly.dt.replace_datestring(datestring_list, day=6))
|
|
360
326
|
# Output: ['2023-06-6', '2024-06-6', '2024-07-6', '2024-08-6', '2024-09-6', '2024-10-6', '2024-11-6', '2024-12-6', '2025-01-6', '2025-02-6', '2025-03-6', '2025-04-6']
|
|
361
|
-
|
|
362
327
|
# Replacing day in a Pandas Series of date strings
|
|
363
328
|
print(dtly.dt.replace_datestring(datestring_series, day="02"))
|
|
364
329
|
# Output:
|
|
@@ -376,72 +341,54 @@ print(dtly.dt.replace_datestring(datestring_series, day="02"))
|
|
|
376
341
|
# 11 2025-04-02
|
|
377
342
|
# dtype: object
|
|
378
343
|
```
|
|
379
|
-
|
|
344
|
+
---
|
|
380
345
|
### Replacing Datetimestring
|
|
381
|
-
|
|
382
346
|
```python
|
|
383
347
|
# Replacing time components in a single date string
|
|
384
348
|
print(dtly.dt.replace_timestring(datestring))
|
|
385
349
|
# Output: '2023-06-21 15:17:47.50691'
|
|
386
|
-
|
|
387
350
|
print(dtly.dt.replace_timestring(datestring, hour=13))
|
|
388
351
|
# Output: '2023-06-21 13:17:47.56700'
|
|
389
|
-
|
|
390
352
|
print(dtly.dt.replace_timestring(datestring, hour="02"))
|
|
391
353
|
# Output: '2023-06-21 02:17:47.63773'
|
|
392
|
-
|
|
393
354
|
print(dtly.dt.replace_timestring(datestring, hour="02", minute=11))
|
|
394
355
|
# Output: '2023-06-21 02:11:47.69779'
|
|
395
|
-
|
|
396
356
|
print(dtly.dt.replace_timestring(datestring, hour="02", minute=10, second=44))
|
|
397
357
|
# Output: '2023-06-21 02:10:44.75777'
|
|
398
|
-
|
|
399
358
|
print(dtly.dt.replace_timestring(datestring, hour="02", minute=10, second=44, microsecond=1))
|
|
400
359
|
# Output: '2023-06-21 02:10:44.00001'
|
|
401
|
-
|
|
402
360
|
print(dtly.dt.replace_timestring(datestring, hour="02", minute=10, second=44, microsecond=1, time_indicator="AM"))
|
|
403
361
|
# Output: '2023-06-21 02:10:44.00001 AM'
|
|
404
|
-
|
|
405
362
|
# Replacing time components in an ISO date string
|
|
406
363
|
iso_datestring = "2023-06-21T12:30:00Z"
|
|
407
364
|
print(dtly.dt.replace_timestring(iso_datestring, hour=2, minute=10, second=44, microsecond=1))
|
|
408
365
|
# Output: '2023-06-21T02:10:44.000001+00:00'
|
|
409
|
-
|
|
410
366
|
print(dtly.dt.replace_timestring(iso_datestring, hour=2, minute=10, second=44, microsecond=1, tzinfo=3))
|
|
411
367
|
# Output: '2023-06-21T02:10:44.000001+03:00'
|
|
412
368
|
```
|
|
413
369
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
370
|
## Working with Time Zones
|
|
418
|
-
|
|
419
371
|
### Retrieving Time Zone Information
|
|
420
|
-
|
|
421
372
|
```python
|
|
422
373
|
# Get the list of country codes
|
|
423
374
|
dtly.TimeZoner.CountryCodes
|
|
424
375
|
# Output: ['AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX'.....]
|
|
425
376
|
```
|
|
426
|
-
|
|
427
377
|
```python
|
|
428
378
|
# Get the list of country names
|
|
429
379
|
dtly.TimeZoner.CountryNames
|
|
430
380
|
# Output: ['Afghanistan', 'Aland Islands', 'Albania', 'Algeria', 'American Samoa', 'Andorra', 'Angola', 'Anguilla', 'Antarctica'.....]
|
|
431
381
|
```
|
|
432
|
-
|
|
433
382
|
```python
|
|
434
383
|
# Get the list of time zones
|
|
435
384
|
dtly.TimeZoner.Zones
|
|
436
385
|
# Output: ['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', 'Africa/Algiers', 'Africa/Asmara', 'Africa/Bamako', 'Africa/Bangui'.....]
|
|
437
386
|
```
|
|
438
|
-
|
|
439
387
|
```python
|
|
440
388
|
# Get time zones by country
|
|
441
389
|
dtly.TimeZoner.ZonesByCountry
|
|
442
390
|
# Output: {'CI': ['Africa/Abidjan'], 'GH': ['Africa/Accra'], 'ET': ['Africa/Addis_Ababa'].....]}
|
|
443
391
|
```
|
|
444
|
-
|
|
445
392
|
```python
|
|
446
393
|
# Get time zones by DST observance
|
|
447
394
|
dtly.TimeZoner.ObservesDST
|
|
@@ -452,21 +399,18 @@ dtly.TimeZoner.ObservesDST
|
|
|
452
399
|
dtly.TimeZoner.Offsets
|
|
453
400
|
# Output: {'+00:00': ['Africa/Abidjan', 'Africa/Accra', 'Africa/Bamako'.....], '+03:00': ['Africa/Addis_Ababa', 'Africa/Asmara'.....], '-09:00': ['America/Adak', 'Pacific/Gambier'.....], '-08:00': ['America/Anchorage'.....]}
|
|
454
401
|
```
|
|
455
|
-
|
|
402
|
+
---
|
|
456
403
|
### Time Zone Operations
|
|
457
|
-
|
|
458
404
|
```python
|
|
459
405
|
# Retrieve detailed information for a specific time zone
|
|
460
406
|
dtly.TimeZoner.FilterZoneDetail('America/Denver')
|
|
461
407
|
# Output: {'countryCode': 'US', 'countryName': 'United States', 'Offset': '-06:00', 'UTC offset (STD)': '-07:00', 'UTC offset (DST)': '-06:00', 'Abbreviation (STD)': 'MST', 'Abbreviation (DST)': 'MDT'}
|
|
462
408
|
```
|
|
463
|
-
|
|
464
409
|
```python
|
|
465
410
|
# Get the current time for a specific time zone
|
|
466
411
|
dtly.TimeZoner.CurrentTimebyZone('Australia/Adelaide')
|
|
467
412
|
# Output: '2024-07-02T04:32:05.642329+09:30'
|
|
468
413
|
```
|
|
469
|
-
|
|
470
414
|
```python
|
|
471
415
|
# Convert time from one time zone to another
|
|
472
416
|
from_zone = 'Africa/Ceuta'
|
|
@@ -474,3 +418,61 @@ to_zone = 'America/Anchorage'
|
|
|
474
418
|
dtly.TimeZoner.ConvertTimeZone(from_zone, to_zone, year=2024, month=5, day=22, hour=12, minute=13, second=22)
|
|
475
419
|
# Output: [{'countryCode': 'ES', 'countryName': 'Spain', 'zoneName': 'Africa/Ceuta', 'gmtOffset': 7200, 'timestamp': 1719865256}, {'countryCode': 'US', 'countryName': 'United States', 'zoneName': 'America/Anchorage', 'gmtOffset': -28800, 'timestamp': 1719829256}]
|
|
476
420
|
```
|
|
421
|
+
|
|
422
|
+
## Natural Language Parsing (NLP)
|
|
423
|
+
|
|
424
|
+
### Overview
|
|
425
|
+
|
|
426
|
+
dately's new NLP engine allows you to interpret and resolve **free-text temporal expressions** into real calendar dates. It supports a wide range of grammar structures and handles expressions like:
|
|
427
|
+
|
|
428
|
+
* `"2nd Monday of next month"`
|
|
429
|
+
* `"last 3 weekends"`
|
|
430
|
+
* `"Q2 2026"`
|
|
431
|
+
* `"5 days ago"`
|
|
432
|
+
* `"middle of this year"`
|
|
433
|
+
* `"next 6 weeks starting from March 15"`
|
|
434
|
+
|
|
435
|
+
Behind the scenes, it uses rule-based grammars, temporal math, and context-aware resolution anchored to today's date (or a custom one you provide).
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
### Basic Usage
|
|
440
|
+
|
|
441
|
+
```python
|
|
442
|
+
import dately as dtly
|
|
443
|
+
|
|
444
|
+
# Parse natural phrases into exact dates or date ranges
|
|
445
|
+
dtly.parse("first Monday of next month")
|
|
446
|
+
|
|
447
|
+
# → datetime.date(2024, 6, 3)
|
|
448
|
+
dtly.parse("last 5 weekends")
|
|
449
|
+
# → [(start_date_1, end_date_1), ..., (start_date_5, end_date_5)]
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
### Phrase Examples
|
|
455
|
+
|
|
456
|
+
| Expression | Output |
|
|
457
|
+
| -------------------------------- | ---------------------------- |
|
|
458
|
+
| `"3 days ago"` | `datetime.date(2024, 4, 29)` |
|
|
459
|
+
| `"start of next quarter"` | `(2024-07-01, 2024-09-30)` |
|
|
460
|
+
| `"next 2 Fridays"` | `[date1, date2]` |
|
|
461
|
+
| `"middle of last year"` | `datetime.date(2023, 7, 1)` |
|
|
462
|
+
| `"start of the 2nd week of May"` | `(2024-05-06, 2024-05-12)` |
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
### Customizing Week Start
|
|
468
|
+
|
|
469
|
+
Control which day is considered the start of the week (default = Sunday):
|
|
470
|
+
|
|
471
|
+
```python
|
|
472
|
+
import dately as dtly
|
|
473
|
+
|
|
474
|
+
dtly.set_week_start("monday") # affects “this week”, “last 3 weekends”, etc.
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
|