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.
Files changed (99) hide show
  1. dately-3.2.0/MANIFEST.in +1 -0
  2. {dately-3.0.2 → dately-3.2.0}/PKG-INFO +89 -87
  3. {dately-3.0.2 → dately-3.2.0}/README.md +87 -85
  4. dately-3.2.0/dately/__envutils.py +41 -0
  5. dately-3.2.0/dately/__init__.py +269 -0
  6. dately-3.2.0/dately/__os_config.py +105 -0
  7. dately-3.2.0/dately/__user_agents_config.py +48 -0
  8. dately-3.2.0/dately/_api.py +52 -0
  9. dately-3.2.0/dately/_connect.py +411 -0
  10. dately-3.2.0/dately/_datetime_scan.py +1658 -0
  11. dately-3.0.2/dately/holiday.py → dately-3.2.0/dately/_holiday.py +108 -39
  12. dately-3.2.0/dately/_log.py +14 -0
  13. dately-3.2.0/dately/_mskutils.py +123 -0
  14. dately-3.2.0/dately/_proxy.py +43 -0
  15. dately-3.2.0/dately/_sysutils.py +207 -0
  16. dately-3.2.0/dately/_temporal_scan.py +2770 -0
  17. dately-3.2.0/dately/_timeutils.py +360 -0
  18. dately-3.0.2/dately/timezone.py → dately-3.2.0/dately/_timezone.py +41 -32
  19. dately-3.0.2/dately/utils.py → dately-3.2.0/dately/_utils.py +19 -7
  20. dately-3.2.0/dately/_version.py +12 -0
  21. dately-3.2.0/dately/_webutils.py +199 -0
  22. dately-3.2.0/dately/core.py +716 -0
  23. dately-3.2.0/dately/dt_nlp/__init__.py +44 -0
  24. dately-3.2.0/dately/dt_nlp/arithmetic.py +1347 -0
  25. dately-3.2.0/dately/dt_nlp/lexical_validation/vocabulary_checks.py +121 -0
  26. dately-3.2.0/dately/dt_nlp/quantified_time.py +233 -0
  27. dately-3.2.0/dately/dt_nlp/relative_time.py +433 -0
  28. dately-3.2.0/dately/dt_nlp/semantic_validation/unit_bounds.py +395 -0
  29. dately-3.2.0/dately/dt_nlp/string_similarity/spell_correction.py +893 -0
  30. dately-3.2.0/dately/dt_nlp/syntactic_validation/__init__.py +0 -0
  31. dately-3.2.0/dately/dt_nlp/syntactic_validation/structure_validator.py +333 -0
  32. dately-3.2.0/dately/dt_nlp/syntactic_validation/temporal_structure_rules.py +613 -0
  33. dately-3.2.0/dately/dt_nlp/temporal_core/__init__.py +0 -0
  34. dately-3.2.0/dately/dt_nlp/temporal_core/temporal_units.py +347 -0
  35. dately-3.2.0/dately/dt_nlp/temporal_preprocessing.py +1406 -0
  36. dately-3.2.0/dately/files/__init__.py +0 -0
  37. dately-3.2.0/dately/files/country_variants.json +293 -0
  38. dately-3.2.0/dately/files/holiday.json +934 -0
  39. dately-3.2.0/dately/files/os_versions.json +5 -0
  40. dately-3.2.0/dately/files/user_agents.json +26 -0
  41. dately-3.2.0/dately/mold/__init__.py +0 -0
  42. dately-3.2.0/dately/mold/pyd/Compiled.cp38-win_amd64.pyd +0 -0
  43. dately-3.2.0/dately/mold/pyd/__init__.py +0 -0
  44. dately-3.2.0/dately/mold/pyd/cdatetime/__init__.py +0 -0
  45. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyx/Compiled.pyx +41 -26
  46. dately-3.2.0/dately/mold/pyx/UniversalDateFormatter.pyx +388 -0
  47. dately-3.2.0/dately/mold/pyx/whichformat.pyx +911 -0
  48. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/Compiled.c +282 -282
  49. {dately-3.0.2/dately/sources → dately-3.2.0/dately/tests}/__init__.py +0 -1
  50. dately-3.2.0/dately/tests/test_parse.py +39 -0
  51. {dately-3.0.2 → dately-3.2.0}/dately.egg-info/PKG-INFO +89 -87
  52. {dately-3.0.2 → dately-3.2.0}/dately.egg-info/SOURCES.txt +42 -11
  53. dately-3.2.0/dately.egg-info/requires.txt +9 -0
  54. {dately-3.0.2 → dately-3.2.0}/setup.py +99 -43
  55. dately-3.0.2/dately/__init__.py +0 -7
  56. dately-3.0.2/dately/connect.py +0 -352
  57. dately-3.0.2/dately/core.py +0 -534
  58. dately-3.0.2/dately/mold/pyd/Compiled.cp38-win_amd64.pyd +0 -0
  59. dately-3.0.2/dately/mold/pyx/UniversalDateFormatter.pyx +0 -189
  60. dately-3.0.2/dately/mold/pyx/whichformat.pyx +0 -331
  61. dately-3.0.2/dately/mskutils.py +0 -81
  62. dately-3.0.2/dately/sources/holiday.json +0 -934
  63. dately-3.0.2/dately/sysutils.py +0 -125
  64. dately-3.0.2/dately/timeutils.py +0 -362
  65. dately-3.0.2/dately/webutils.py +0 -34
  66. dately-3.0.2/dately.egg-info/requires.txt +0 -4
  67. {dately-3.0.2/dately/mold → dately-3.2.0/dately/dt_nlp/lexical_validation}/__init__.py +0 -0
  68. {dately-3.0.2/dately/mold/pyd → dately-3.2.0/dately/dt_nlp/semantic_validation}/__init__.py +0 -0
  69. {dately-3.0.2/dately/mold/pyd/cdatetime → dately-3.2.0/dately/dt_nlp/string_similarity}/__init__.py +0 -0
  70. {dately-3.0.2/dately/sources → dately-3.2.0/dately/files}/timezone_data.json +0 -0
  71. {dately-3.0.2 → dately-3.2.0}/dately/mold/include/clean_str.h +0 -0
  72. {dately-3.0.2 → dately-3.2.0}/dately/mold/include/iso8601T.h +0 -0
  73. {dately-3.0.2 → dately-3.2.0}/dately/mold/include/iso8601Z.h +0 -0
  74. {dately-3.0.2 → dately-3.2.0}/dately/mold/include/root_dir_search.h +0 -0
  75. {dately-3.0.2 → dately-3.2.0}/dately/mold/include/time_zones.h +0 -0
  76. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/cdatetime/UniversalDateFormatter.cp38-win_amd64.pyd +0 -0
  77. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/cdatetime/iso8601T.cp38-win_amd64.pyd +0 -0
  78. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/cdatetime/iso8601Z.cp38-win_amd64.pyd +0 -0
  79. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/cdatetime/whichformat.cp38-win_amd64.pyd +0 -0
  80. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/clean_str.cp38-win_amd64.pyd +0 -0
  81. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyd/time_zones.cp38-win_amd64.pyd +0 -0
  82. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyx/clean_str.pyx +0 -0
  83. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyx/iso8601T.pyx +0 -0
  84. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyx/iso8601Z.pyx +0 -0
  85. {dately-3.0.2 → dately-3.2.0}/dately/mold/pyx/time_zones.pyx +0 -0
  86. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/UniversalDateFormatter.c +0 -0
  87. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/clean_str.c +0 -0
  88. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/clean_str_impl.c +0 -0
  89. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/iso8601T.c +0 -0
  90. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/iso8601T_impl.c +0 -0
  91. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/iso8601Z.c +0 -0
  92. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/iso8601Z_impl.c +0 -0
  93. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/root_dir_search_impl.c +0 -0
  94. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/time_zones.c +0 -0
  95. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/time_zones_impl.c +0 -0
  96. {dately-3.0.2 → dately-3.2.0}/dately/mold/src/whichformat.c +0 -0
  97. {dately-3.0.2 → dately-3.2.0}/dately.egg-info/dependency_links.txt +0 -0
  98. {dately-3.0.2 → dately-3.2.0}/dately.egg-info/top_level.txt +0 -0
  99. {dately-3.0.2 → dately-3.2.0}/setup.cfg +0 -0
@@ -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.2
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.2
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.2
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
- ### Dately Library: Comprehensive Date and Time Handling in Python
27
-
26
+ ### dately: Comprehensive Date, Time **& Natural-Language** Handling in Python
28
27
 
29
28
  [![Downloads](https://static.pepy.tech/badge/dately)](https://pepy.tech/project/dately)
30
29
  [![Downloads](https://static.pepy.tech/badge/dately/month)](https://pepy.tech/project/dately)
31
30
  [![Downloads](https://static.pepy.tech/badge/dately/week)](https://pepy.tech/project/dately)
32
31
 
33
- The `dately` module is a comprehensive library designed for advanced date and time manipulation. It offers extensive capabilities to handle various date and time formats, ensuring compatibility across different systems and data structures. The module provides tools for validating, extracting, and transforming date and time information with a focus on performance and accuracy.
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&nbsp;“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 Dately?](#why-choose-dately)
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
- #### Why Choose Dately?
52
-
53
- - **Windows Optimized**: Specifically addresses inconsistencies in Python's date formatting on the Windows operating system.
54
- - **Comprehensive Functionalities**: Supports date parsing, detection, extraction, and conversion for various input types, including date strings, datetime objects, pandas Series, and NumPy arrays.
55
- - **High Performance**: Leverages both high-level Python and low-level C code (via Cython) for efficient operations.
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
+