Skip to content

Commit ce1d08b

Browse files
committed
Fix datetime calculations
1 parent 50c2baf commit ce1d08b

File tree

2 files changed

+40
-9
lines changed

2 files changed

+40
-9
lines changed

faker/providers/date_time/__init__.py

+30-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
import platform
23
import re
34

@@ -19,20 +20,29 @@
1920

2021
localized = True
2122

23+
log = logging.getLogger(__name__)
24+
2225

2326
def datetime_to_timestamp(dt: Union[dtdate, datetime]) -> int:
24-
if isinstance(dt, datetime) and getattr(dt, "tzinfo", None) is not None:
25-
dt = dt.astimezone(tzutc())
27+
if dt == datetime.min:
28+
return timegm(dt.timetuple())
29+
if isinstance(dt, datetime):
30+
try:
31+
dt = dt.astimezone(tzutc())
32+
except OSError:
33+
pass
2634
return timegm(dt.timetuple())
2735

2836

2937
def convert_timestamp_to_datetime(timestamp: Union[int, float], tzinfo: TzInfo) -> datetime:
30-
import datetime as dt
31-
3238
if timestamp >= 0:
33-
return dt.datetime.fromtimestamp(timestamp, tzinfo)
39+
try:
40+
return datetime.fromtimestamp(timestamp, tzinfo)
41+
except OSError:
42+
log.exception("OSError occurred while converting timestamp '%s' to datetime", timestamp)
43+
raise
3444
else:
35-
return dt.datetime(1970, 1, 1, tzinfo=tzinfo) + dt.timedelta(seconds=int(timestamp))
45+
return datetime(1970, 1, 1, tzinfo=tzinfo) + timedelta(seconds=int(timestamp))
3646

3747

3848
def timestamp_to_datetime(timestamp: Union[int, float], tzinfo: Optional[TzInfo]) -> datetime:
@@ -1849,10 +1859,15 @@ def _get_reference_date_time(
18491859
If both are absolute, return the most recent one.
18501860
If both are None, return now.
18511861
"""
1862+
18521863
min_ = datetime_to_timestamp(datetime.min)
18531864
now = datetime.now(tzinfo)
18541865
if start_date is None and end_date is None:
18551866
return now
1867+
if start_date is None and end_date is not None:
1868+
start_date = now
1869+
elif start_date is not None and end_date is None:
1870+
end_date = now
18561871

18571872
start_int = cls._parse_date_time(start_date, now) if start_date is not None else min_
18581873
end_int = cls._parse_date_time(end_date, now) if end_date is not None else min_
@@ -1965,7 +1980,14 @@ def unix_time(
19651980
19661981
:example: 1061306726.6
19671982
"""
1968-
now = self._get_reference_date_time(start_datetime, end_datetime, tzinfo=None)
1983+
if start_datetime is not None and end_datetime is None:
1984+
if start_datetime == "now":
1985+
end_datetime = "+30d"
1986+
else:
1987+
end_datetime = datetime.now(tz=tzutc())
1988+
elif start_datetime is None and end_datetime is not None:
1989+
start_datetime = datetime(1970, 1, 1, tzinfo=tzutc())
1990+
now = self._get_reference_date_time(start_datetime, end_datetime, tzinfo=tzutc())
19691991
start_datetime = self._parse_start_datetime(now, start_datetime)
19701992
end_datetime = self._parse_end_datetime(now, end_datetime)
19711993
return float(self._rand_seconds(start_datetime, end_datetime))
@@ -2220,7 +2242,7 @@ def date_time_between_dates(
22202242
if tzinfo is None:
22212243
pick = convert_timestamp_to_datetime(timestamp, tzlocal())
22222244
try:
2223-
pick = pick.astimezone(tzutc()).replace(tzinfo=None)
2245+
pick = pick.replace(tzinfo=None)
22242246
except OSError:
22252247
pass
22262248
else:

faker/providers/user_agent/__init__.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@
44

55
from .. import BaseProvider, ElementsType
66

7-
_DT_ALMOST_MAX = datetime.max - timedelta(1.0)
7+
8+
def datetime_max() -> datetime:
9+
try:
10+
datetime.fromtimestamp(datetime.max)
11+
return datetime.max
12+
except OSError:
13+
return datetime.fromtimestamp(2177452799)
14+
15+
16+
_DT_ALMOST_MAX = datetime_max() - timedelta(1.0)
817

918

1019
class Provider(BaseProvider):

0 commit comments

Comments
 (0)