Skip to content

Commit

Permalink
Fix datetime calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
fcurella committed Jan 22, 2025
1 parent 50c2baf commit c330978
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 9 deletions.
38 changes: 30 additions & 8 deletions faker/providers/date_time/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import platform
import re

Expand All @@ -19,20 +20,29 @@

localized = True

log = logging.getLogger(__name__)


def datetime_to_timestamp(dt: Union[dtdate, datetime]) -> int:
if isinstance(dt, datetime) and getattr(dt, "tzinfo", None) is not None:
dt = dt.astimezone(tzutc())
if dt == datetime.min:
return timegm(dt.timetuple())
if isinstance(dt, datetime):
try:
dt = dt.astimezone(tzutc())
except OSError:
pass
return timegm(dt.timetuple())


def convert_timestamp_to_datetime(timestamp: Union[int, float], tzinfo: TzInfo) -> datetime:
import datetime as dt

if timestamp >= 0:
return dt.datetime.fromtimestamp(timestamp, tzinfo)
try:
return datetime.fromtimestamp(timestamp, tzinfo)
except OSError:
log.exception("OSError occurred while converting timestamp '%s' to datetime", timestamp)
raise
else:
return dt.datetime(1970, 1, 1, tzinfo=tzinfo) + dt.timedelta(seconds=int(timestamp))
return datetime(1970, 1, 1, tzinfo=tzinfo) + timedelta(seconds=int(timestamp))


def timestamp_to_datetime(timestamp: Union[int, float], tzinfo: Optional[TzInfo]) -> datetime:
Expand Down Expand Up @@ -1849,10 +1859,15 @@ def _get_reference_date_time(
If both are absolute, return the most recent one.
If both are None, return now.
"""

min_ = datetime_to_timestamp(datetime.min)
now = datetime.now(tzinfo)
if start_date is None and end_date is None:
return now
if start_date is None and end_date is not None:
start_date = now
elif start_date is not None and end_date is None:
end_date = now

start_int = cls._parse_date_time(start_date, now) if start_date is not None else min_
end_int = cls._parse_date_time(end_date, now) if end_date is not None else min_
Expand Down Expand Up @@ -1965,7 +1980,14 @@ def unix_time(
:example: 1061306726.6
"""
now = self._get_reference_date_time(start_datetime, end_datetime, tzinfo=None)
if start_datetime is not None and end_datetime is None:
if start_datetime == "now":
end_datetime = "+30d"
else:
end_datetime = datetime.now(tz=tzutc())
elif start_datetime is None and end_datetime is not None:
start_datetime = datetime(1970, 1, 1, tzinfo=tzutc())
now = self._get_reference_date_time(start_datetime, end_datetime, tzinfo=tzutc())
start_datetime = self._parse_start_datetime(now, start_datetime)
end_datetime = self._parse_end_datetime(now, end_datetime)
return float(self._rand_seconds(start_datetime, end_datetime))
Expand Down Expand Up @@ -2220,7 +2242,7 @@ def date_time_between_dates(
if tzinfo is None:
pick = convert_timestamp_to_datetime(timestamp, tzlocal())
try:
pick = pick.astimezone(tzutc()).replace(tzinfo=None)
pick = pick.replace(tzinfo=None)
except OSError:
pass
else:
Expand Down
14 changes: 13 additions & 1 deletion faker/providers/user_agent/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@

from datetime import datetime, timedelta

from dateutil.tz import tzutc

from .. import BaseProvider, ElementsType

_DT_ALMOST_MAX = datetime.max - timedelta(1.0)

def datetime_max() -> datetime:
try:
max = datetime.max - timedelta(1.0)
datetime.fromtimestamp(max.timestamp(), tz=tzutc())
return max
except OSError:
return datetime.fromtimestamp(2177366400)


_DT_ALMOST_MAX = datetime_max()


class Provider(BaseProvider):
Expand Down

0 comments on commit c330978

Please sign in to comment.