pydae 0.57.1__py3-none-any.whl → 0.57.2__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.
pydae/__init__.py CHANGED
@@ -7,5 +7,5 @@ Differential Algebraic Equations in Python
7
7
 
8
8
  """
9
9
 
10
- __version__ = "0.57.1"
10
+ __version__ = "0.57.2"
11
11
 
pydae/utils/dates.py CHANGED
@@ -270,7 +270,56 @@ def hour_index_to_date_components(absolute_hour_index: int, timezone_name: str)
270
270
  return None
271
271
 
272
272
 
273
+ def day_to_absolute_hour(day_of_year: int, target_year: int, timezone_name: str = 'Europe/Madrid') -> int:
274
+ """
275
+ Calculates the absolute hour of the year (based on UTC) for a specific day
276
+ at 00:00 local time, correctly accounting for time zone and DST changes.
277
+
278
+ Args:
279
+ day_of_year: The sequential day of the year (1 for Jan 1st, 365/366 for Dec 31st).
280
+ target_year: The year for the calculation (e.g., 2024).
281
+ timezone_name: The target time zone string (e.g., 'Europe/London', 'America/New_York').
282
+ Defaults to 'UTC'.
283
+
284
+ Returns:
285
+ The total number of hours elapsed from the beginning of the year
286
+ (Jan 1st 00:00 UTC) up to the specified date and time (converted to UTC).
287
+
288
+ Raises:
289
+ pytz.UnknownTimeZoneError: If the provided timezone_name is invalid.
290
+ """
291
+
292
+ # 1. Define the start of the year and the target date (unlocalized)
293
+ start_of_year = datetime.datetime(target_year, 1, 1, 0, 0, 0)
294
+
295
+ # Calculate the target date (00:00 local time)
296
+ # We subtract 1 from day_of_year because Jan 1st is day 1, but represents 0 days of offset.
297
+ target_date = start_of_year + datetime.timedelta(days=day_of_year - 1)
273
298
 
299
+ try:
300
+ # 2. Localize the dates
301
+ tz = pytz.timezone(timezone_name)
302
+
303
+ # Localize the date to the target timezone (this handles DST shift at 00:00 if any)
304
+ # .localize() is the safe way to assign timezone awareness.
305
+ start_of_year_local = tz.localize(start_of_year)
306
+ target_date_local = tz.localize(target_date)
307
+
308
+ # 3. Convert both localized times to UTC
309
+ start_of_year_utc = start_of_year_local.astimezone(pytz.utc)
310
+ target_date_utc = target_date_local.astimezone(pytz.utc)
311
+
312
+ # 4. Calculate the difference in hours
313
+ time_difference = target_date_utc - start_of_year_utc
314
+
315
+ # Convert total seconds in the timedelta to total hours (integer result)
316
+ absolute_hour = int(time_difference.total_seconds() / 3600)
317
+
318
+ return absolute_hour
319
+
320
+ except pytz.UnknownTimeZoneError:
321
+ raise pytz.UnknownTimeZoneError(f"Time zone '{timezone_name}' is not recognized by pytz.")
322
+
274
323
  if __name__ == '__main__':
275
324
 
276
325
  result_1 = parse_datetime('31/12/2024 23:00', 'Europe/Paris')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pydae
3
- Version: 0.57.1
3
+ Version: 0.57.2
4
4
  Summary: =====
5
5
  Keywords: engineering
6
6
  Author-email: Juan Manuel Mauricio <jmmauricio6@gmail.com>
@@ -1,5 +1,5 @@
1
1
  pydae/.gitignore,sha256=c1jUQV9WXX3PWrlOzHiKvUWFomLJUrfYogbU7nYwAwc,288
2
- pydae/__init__.py,sha256=AooVv7ncEnuMOCQXzdgZBl_YmdIa5ILy7R4W22vxoNw,106
2
+ pydae/__init__.py,sha256=fUy1IioPTAmI5CGTEuu5wHj1YqgbZ1bjvpvdZA2X7eM,106
3
3
  pydae/b_pu.py,sha256=FdRRVieJLQDYPwYNWhbXJ0SXvf4jtPdbvIZTKWi16I0,6775
4
4
  pydae/bpu.py,sha256=FdRRVieJLQDYPwYNWhbXJ0SXvf4jtPdbvIZTKWi16I0,6775
5
5
  pydae/build.py,sha256=ECfc_doyK9PhrjEAlWJGLfirQmpT24XuYNxUgtrXI74,46151
@@ -735,15 +735,15 @@ pydae/urisi/vsgs/vsg_lpf_ib.hjson,sha256=xpuo5fPCdO5Ze0X-KDCsa_eRpde5f5KDDFoDkWI
735
735
  pydae/urisi/vsgs/vsgs.py,sha256=v17sLm7EaaAyBVJk9-8DnLtxPDtXmkyizFlGhgqyFEE,644
736
736
  pydae/urisi/vsgs/xy_0.json,sha256=Q6qWPIqEP-w5Qu2twd3S4PX4zMggpNpG2W62e7ry70g,851
737
737
  pydae/utils/__init__.py,sha256=kwp76qeU2mnwrCexDSF15id9ih12Q0VRL3l-_c6omcQ,184
738
- pydae/utils/dates.py,sha256=wWVhgprZ6Iu8garC8BASKrPWDtXtZY1_ss3iDMLE2mA,11349
738
+ pydae/utils/dates.py,sha256=bx3NyCkyWFbp3hlsOTbUSXSbXDAqYGIWA8aXoslE0_I,13612
739
739
  pydae/utils/ss_num2sym.py,sha256=ZA-x01y1mEWk1HdlpNv9rNspFdH0RBlTq_JRDHmjlpU,3209
740
740
  pydae/utils/svg2pdf.py,sha256=6tNORhlu_cMPDp264Kg3X_eBORfT9Q1cqAcWaWgDs7k,1861
741
741
  pydae/utils/tools.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
742
742
  pydae/utils/types_converter.py,sha256=3eAWwELgG1d6iFX8sn8iGPIp6NBaX4I-eyUriRDOFyE,7929
743
743
  pydae/utils/utils.py,sha256=AI0wZr4PJ3Td3vjfAW06FJdgcK01TpUAukhG37gZP5g,1079
744
744
  pydae/utils/emtp/readPL4.py,sha256=R59KhXTmFrqtdv-9nv5tkdHoTs9uoofGqEfBCF4fGEY,3088
745
- pydae-0.57.1.dist-info/licenses/COPYING,sha256=QWnWoslbTjQmtlFSRoGF3wxJEJuTJdlEMZ7lHtbGAeQ,1139
746
- pydae-0.57.1.dist-info/licenses/LICENSE,sha256=8hQe1oM4ySdliF3R-NEvR6HqrcGDKvsLFJC3gA1sNjY,1108
747
- pydae-0.57.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
748
- pydae-0.57.1.dist-info/METADATA,sha256=JFOPnyIcoXWAmiFg-hoAZwyQ_QrkH-hKD45FgPG9vrs,1090
749
- pydae-0.57.1.dist-info/RECORD,,
745
+ pydae-0.57.2.dist-info/licenses/COPYING,sha256=QWnWoslbTjQmtlFSRoGF3wxJEJuTJdlEMZ7lHtbGAeQ,1139
746
+ pydae-0.57.2.dist-info/licenses/LICENSE,sha256=8hQe1oM4ySdliF3R-NEvR6HqrcGDKvsLFJC3gA1sNjY,1108
747
+ pydae-0.57.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
748
+ pydae-0.57.2.dist-info/METADATA,sha256=pPD7BWSoPod5OcSfSLQh_E3EJjDn3n8UynyO4l9reUM,1090
749
+ pydae-0.57.2.dist-info/RECORD,,
File without changes