From 73794a04090856bb124c81683644b8ae7b25b042 Mon Sep 17 00:00:00 2001 From: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> Date: Wed, 2 Aug 2023 13:59:45 -0700 Subject: [PATCH] Improve parsing to datetime and add error handling --- plexapi/utils.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/plexapi/utils.py b/plexapi/utils.py index d1882fbbc..1062e662c 100644 --- a/plexapi/utils.py +++ b/plexapi/utils.py @@ -11,13 +11,13 @@ import warnings import zipfile from collections import deque -from datetime import datetime +from datetime import datetime, timedelta, timezone from getpass import getpass from threading import Event, Thread from urllib.parse import quote -from requests.status_codes import _codes as codes import requests +from requests.status_codes import _codes as codes from plexapi.exceptions import BadRequest, NotFound, Unauthorized @@ -313,19 +313,22 @@ def toDatetime(value, format=None): value (str): value to return as a datetime format (str): Format to pass strftime (optional; if value is a str). """ - if value and value is not None: + if value is not None: if format: try: - value = datetime.strptime(value, format) + return datetime.strptime(value, format) except ValueError: - log.info('Failed to parse %s to datetime, defaulting to None', value) + log.info('Failed to parse "%s" to datetime as format "%s", defaulting to None', value, format) return None else: - # https://bugs.python.org/issue30684 - # And platform support for before epoch seems to be flaky. - # Also limit to max 32-bit integer - value = min(max(int(value), 86400), 2**31 - 1) - value = datetime.fromtimestamp(int(value)) + try: + return (datetime.fromtimestamp(0, tz=timezone.utc) + timedelta(seconds=int(value))).replace(tzinfo=None) + except ValueError: + log.info('Failed to parse "%s" to datetime as timestamp, defaulting to None', value) + return None + except OverflowError: + log.info('Failed to parse "%s" to datetime as timestamp (out-of-bounds), defaulting to None', value) + return None return value