rashdf 0.8.3__py3-none-any.whl → 0.8.4__py3-none-any.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.
rashdf/utils.py CHANGED
@@ -10,6 +10,36 @@ from typing import Any, Callable, List, Tuple, Union, Optional
10
10
  import warnings
11
11
 
12
12
 
13
+ def deprecated(func) -> Callable:
14
+ """
15
+ Deprecate a function.
16
+
17
+ This is a decorator which can be used to mark functions as deprecated.
18
+ It will result in a warning being emitted when the function is used.
19
+
20
+ Parameters
21
+ ----------
22
+ func: The function to be deprecated.
23
+
24
+ Returns
25
+ -------
26
+ The decorated function.
27
+ """
28
+
29
+ def new_func(*args, **kwargs):
30
+ warnings.warn(
31
+ f"{func.__name__} is deprecated and will be removed in a future version.",
32
+ category=DeprecationWarning,
33
+ stacklevel=2,
34
+ )
35
+ return func(*args, **kwargs)
36
+
37
+ new_func.__name__ = func.__name__
38
+ new_func.__doc__ = func.__doc__
39
+ new_func.__dict__.update(func.__dict__)
40
+ return new_func
41
+
42
+
13
43
  def parse_ras_datetime_ms(datetime_str: str) -> datetime:
14
44
  """Parse a datetime string with milliseconds from a RAS file into a datetime object.
15
45
 
@@ -36,24 +66,37 @@ def parse_ras_datetime(datetime_str: str) -> datetime:
36
66
 
37
67
  Parameters
38
68
  ----------
39
- datetime_str (str): The datetime string to be parsed. The string should be in the format "ddMMMyyyy HH:mm:ss".
69
+ datetime_str (str): The datetime string to be parsed.
40
70
 
41
71
  Returns
42
72
  -------
43
73
  datetime: A datetime object representing the parsed datetime.
44
74
  """
45
- datetime_format = "%d%b%Y %H:%M:%S"
75
+ date_formats = ["%d%b%Y", "%m/%d/%Y", "%m-%d-%Y", "%Y/%m/%d", "%Y-%m-%d"]
76
+ time_formats = ["%H:%M:%S", "%H%M"]
77
+ datetime_formats = [
78
+ f"{date} {time}" for date in date_formats for time in time_formats
79
+ ]
46
80
 
47
- if datetime_str.endswith("24:00:00"):
48
- datetime_str = datetime_str.replace("24:00:00", "00:00:00")
49
- parsed_dt = datetime.strptime(datetime_str, datetime_format)
50
- parsed_dt += timedelta(days=1)
51
- else:
52
- parsed_dt = datetime.strptime(datetime_str, datetime_format)
81
+ is_2400 = datetime_str.endswith((" 24:00:00", " 2400", " 24:00"))
82
+ if is_2400:
83
+ datetime_str = datetime_str.split()[0] + " 00:00:00"
53
84
 
54
- return parsed_dt
85
+ last_exception = None
86
+ for fmt in datetime_formats:
87
+ try:
88
+ parsed_dt = datetime.strptime(datetime_str, fmt)
89
+ if is_2400:
90
+ parsed_dt += timedelta(days=1)
91
+ return parsed_dt
92
+ except ValueError as e:
93
+ last_exception = e
94
+ continue
95
+
96
+ raise ValueError(f"Invalid date format: {datetime_str}") from last_exception
55
97
 
56
98
 
99
+ @deprecated
57
100
  def parse_ras_simulation_window_datetime(datetime_str) -> datetime:
58
101
  """
59
102
  Parse a datetime string from a RAS simulation window into a datetime object.
@@ -139,32 +182,37 @@ def convert_ras_hdf_string(
139
182
  a list of datetime strings, a timedelta objects, or the original string
140
183
  if no other conditions are met.
141
184
  """
142
- ras_datetime_format1_re = r"\d{2}\w{3}\d{4} \d{2}:\d{2}:\d{2}"
143
- ras_datetime_format2_re = r"\d{2}\w{3}\d{4} \d{2}\d{2}"
144
185
  ras_duration_format_re = r"\d{2}:\d{2}:\d{2}"
186
+ date_patterns_re = [
187
+ r"\d{2}\w{3}\d{4}",
188
+ r"\d{2}/\d{2}/\d{4}",
189
+ r"\d{2}-\d{2}-\d{4}",
190
+ r"\d{4}/\d{2}/\d{2}",
191
+ r"\d{4}-\d{2}-\d{2}",
192
+ ]
193
+ time_patterns_re = [
194
+ r"\d{2}:\d{2}:\d{2}",
195
+ r"\d{4}",
196
+ ]
197
+ datetime_patterns_re = [
198
+ f"{date} {time}" for date in date_patterns_re for time in time_patterns_re
199
+ ]
145
200
  s = value.decode("utf-8")
146
201
  if s == "True":
147
202
  return True
148
203
  elif s == "False":
149
204
  return False
150
- elif re.match(rf"^{ras_datetime_format1_re}", s):
151
- if re.match(rf"^{ras_datetime_format1_re} to {ras_datetime_format1_re}$", s):
152
- split = s.split(" to ")
153
- return [
154
- parse_ras_datetime(split[0]),
155
- parse_ras_datetime(split[1]),
156
- ]
157
- return parse_ras_datetime(s)
158
- elif re.match(rf"^{ras_datetime_format2_re}", s):
159
- if re.match(rf"^{ras_datetime_format2_re} to {ras_datetime_format2_re}$", s):
160
- split = s.split(" to ")
161
- return [
162
- parse_ras_simulation_window_datetime(split[0]),
163
- parse_ras_simulation_window_datetime(split[1]),
164
- ]
165
- return parse_ras_simulation_window_datetime(s)
166
205
  elif re.match(rf"^{ras_duration_format_re}$", s):
167
206
  return parse_duration(s)
207
+ for dt_re in datetime_patterns_re:
208
+ if re.match(rf"^{dt_re}", s):
209
+ if re.match(rf"^{dt_re} to {dt_re}$", s):
210
+ start, end = s.split(" to ")
211
+ return [
212
+ parse_ras_datetime(start),
213
+ parse_ras_datetime(end),
214
+ ]
215
+ return parse_ras_datetime(s)
168
216
  return s
169
217
 
170
218
 
@@ -306,33 +354,3 @@ def ras_timesteps_to_datetimes(
306
354
  start_time + pd.Timedelta(timestep, unit=time_unit).round(round_to)
307
355
  for timestep in timesteps.astype(np.float64)
308
356
  ]
309
-
310
-
311
- def deprecated(func) -> Callable:
312
- """
313
- Deprecate a function.
314
-
315
- This is a decorator which can be used to mark functions as deprecated.
316
- It will result in a warning being emitted when the function is used.
317
-
318
- Parameters
319
- ----------
320
- func: The function to be deprecated.
321
-
322
- Returns
323
- -------
324
- The decorated function.
325
- """
326
-
327
- def new_func(*args, **kwargs):
328
- warnings.warn(
329
- f"{func.__name__} is deprecated and will be removed in a future version.",
330
- category=DeprecationWarning,
331
- stacklevel=2,
332
- )
333
- return func(*args, **kwargs)
334
-
335
- new_func.__name__ = func.__name__
336
- new_func.__doc__ = func.__doc__
337
- new_func.__dict__.update(func.__dict__)
338
- return new_func
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rashdf
3
- Version: 0.8.3
3
+ Version: 0.8.4
4
4
  Summary: Read data from HEC-RAS HDF files.
5
5
  Project-URL: repository, https://github.com/fema-ffrd/rashdf
6
6
  Classifier: Development Status :: 4 - Beta
@@ -3,10 +3,10 @@ rashdf/__init__.py,sha256=XXFtJDgLPCimqAhfsFz_pTWYECJiRT0i-Kb1uflXmVU,156
3
3
  rashdf/base.py,sha256=cAQJX1aeBJKb3MJ06ltpbRTUaZX5NkuxpR1J4f7FyTU,2507
4
4
  rashdf/geom.py,sha256=O2PMYY7w7fdW2U4u0rsbWeEDKAmsUh4-49ro-xUMc4A,28755
5
5
  rashdf/plan.py,sha256=ctkfLBqocF2TpU6wYygXkxE2voCJa8WyVGYlimsyxS4,63612
6
- rashdf/utils.py,sha256=AihMVcxxaufAnOVT3e5ollD5UINI_kjxSHohBS77-l0,10879
7
- rashdf-0.8.3.dist-info/licenses/LICENSE,sha256=L_0QaLpQVHPcglVjiaJPnOocwzP8uXevDRjUPr9DL1Y,1065
8
- rashdf-0.8.3.dist-info/METADATA,sha256=myhrp-erERbBWyofdiUaJLgC1apyviBizGBHMyGhRak,6072
9
- rashdf-0.8.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
- rashdf-0.8.3.dist-info/entry_points.txt,sha256=LHHMR1lLy4wRyscMuW1RlYDXemtPgqQhNcILz0DtStY,36
11
- rashdf-0.8.3.dist-info/top_level.txt,sha256=SrmLb6FFTJtM_t6O1v0M0JePshiQJMHr0yYVkHL7ztk,11
12
- rashdf-0.8.3.dist-info/RECORD,,
6
+ rashdf/utils.py,sha256=I23Zij1EFi9v99UXFIJVGaZ2JN48-q5TK1aNsKwL4vE,11113
7
+ rashdf-0.8.4.dist-info/licenses/LICENSE,sha256=L_0QaLpQVHPcglVjiaJPnOocwzP8uXevDRjUPr9DL1Y,1065
8
+ rashdf-0.8.4.dist-info/METADATA,sha256=ZHbiO37k11MIami2y_JyuRzlLNk_qsgiLCx2Gi6TDKs,6072
9
+ rashdf-0.8.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
+ rashdf-0.8.4.dist-info/entry_points.txt,sha256=LHHMR1lLy4wRyscMuW1RlYDXemtPgqQhNcILz0DtStY,36
11
+ rashdf-0.8.4.dist-info/top_level.txt,sha256=SrmLb6FFTJtM_t6O1v0M0JePshiQJMHr0yYVkHL7ztk,11
12
+ rashdf-0.8.4.dist-info/RECORD,,
File without changes