mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-07 13:41:15 -07:00
Update arrow-1.2.0
This commit is contained in:
parent
3b645cf6c3
commit
9a54fb9a44
11 changed files with 7793 additions and 2322 deletions
|
@ -1,47 +1,117 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
"""Helpful functions used internally within arrow."""
|
||||
|
||||
import sys
|
||||
import datetime
|
||||
from typing import Any, Optional, cast
|
||||
|
||||
# python 2.6 / 2.7 definitions for total_seconds function.
|
||||
from dateutil.rrule import WEEKLY, rrule
|
||||
|
||||
def _total_seconds_27(td): # pragma: no cover
|
||||
return td.total_seconds()
|
||||
|
||||
def _total_seconds_26(td):
|
||||
return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 1e6) / 1e6
|
||||
from arrow.constants import (
|
||||
MAX_ORDINAL,
|
||||
MAX_TIMESTAMP,
|
||||
MAX_TIMESTAMP_MS,
|
||||
MAX_TIMESTAMP_US,
|
||||
MIN_ORDINAL,
|
||||
)
|
||||
|
||||
|
||||
# get version info and assign correct total_seconds function.
|
||||
def next_weekday(
|
||||
start_date: Optional[datetime.date], weekday: int
|
||||
) -> datetime.datetime:
|
||||
"""Get next weekday from the specified start date.
|
||||
|
||||
version = '{0}.{1}.{2}'.format(*sys.version_info[:3])
|
||||
:param start_date: Datetime object representing the start date.
|
||||
:param weekday: Next weekday to obtain. Can be a value between 0 (Monday) and 6 (Sunday).
|
||||
:return: Datetime object corresponding to the next weekday after start_date.
|
||||
|
||||
if version < '2.7': # pragma: no cover
|
||||
total_seconds = _total_seconds_26
|
||||
else: # pragma: no cover
|
||||
total_seconds = _total_seconds_27
|
||||
Usage::
|
||||
|
||||
def is_timestamp(value):
|
||||
if type(value) == bool:
|
||||
# Get first Monday after epoch
|
||||
>>> next_weekday(datetime(1970, 1, 1), 0)
|
||||
1970-01-05 00:00:00
|
||||
|
||||
# Get first Thursday after epoch
|
||||
>>> next_weekday(datetime(1970, 1, 1), 3)
|
||||
1970-01-01 00:00:00
|
||||
|
||||
# Get first Sunday after epoch
|
||||
>>> next_weekday(datetime(1970, 1, 1), 6)
|
||||
1970-01-04 00:00:00
|
||||
"""
|
||||
if weekday < 0 or weekday > 6:
|
||||
raise ValueError("Weekday must be between 0 (Monday) and 6 (Sunday).")
|
||||
return cast(
|
||||
datetime.datetime,
|
||||
rrule(freq=WEEKLY, dtstart=start_date, byweekday=weekday, count=1)[0],
|
||||
)
|
||||
|
||||
|
||||
def is_timestamp(value: Any) -> bool:
|
||||
"""Check if value is a valid timestamp."""
|
||||
if isinstance(value, bool):
|
||||
return False
|
||||
if not isinstance(value, (int, float, str)):
|
||||
return False
|
||||
try:
|
||||
float(value)
|
||||
return True
|
||||
except:
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
# python 2.7 / 3.0+ definitions for isstr function.
|
||||
|
||||
try: # pragma: no cover
|
||||
basestring
|
||||
def validate_ordinal(value: Any) -> None:
|
||||
"""Raise an exception if value is an invalid Gregorian ordinal.
|
||||
|
||||
def isstr(s):
|
||||
return isinstance(s, basestring)
|
||||
:param value: the input to be checked
|
||||
|
||||
except NameError: #pragma: no cover
|
||||
|
||||
def isstr(s):
|
||||
return isinstance(s, str)
|
||||
"""
|
||||
if isinstance(value, bool) or not isinstance(value, int):
|
||||
raise TypeError(f"Ordinal must be an integer (got type {type(value)}).")
|
||||
if not (MIN_ORDINAL <= value <= MAX_ORDINAL):
|
||||
raise ValueError(f"Ordinal {value} is out of range.")
|
||||
|
||||
|
||||
__all__ = ['total_seconds', 'is_timestamp', 'isstr']
|
||||
def normalize_timestamp(timestamp: float) -> float:
|
||||
"""Normalize millisecond and microsecond timestamps into normal timestamps."""
|
||||
if timestamp > MAX_TIMESTAMP:
|
||||
if timestamp < MAX_TIMESTAMP_MS:
|
||||
timestamp /= 1000
|
||||
elif timestamp < MAX_TIMESTAMP_US:
|
||||
timestamp /= 1_000_000
|
||||
else:
|
||||
raise ValueError(f"The specified timestamp {timestamp!r} is too large.")
|
||||
return timestamp
|
||||
|
||||
|
||||
# Credit to https://stackoverflow.com/a/1700069
|
||||
def iso_to_gregorian(iso_year: int, iso_week: int, iso_day: int) -> datetime.date:
|
||||
"""Converts an ISO week date into a datetime object.
|
||||
|
||||
:param iso_year: the year
|
||||
:param iso_week: the week number, each year has either 52 or 53 weeks
|
||||
:param iso_day: the day numbered 1 through 7, beginning with Monday
|
||||
|
||||
"""
|
||||
|
||||
if not 1 <= iso_week <= 53:
|
||||
raise ValueError("ISO Calendar week value must be between 1-53.")
|
||||
|
||||
if not 1 <= iso_day <= 7:
|
||||
raise ValueError("ISO Calendar day value must be between 1-7")
|
||||
|
||||
# The first week of the year always contains 4 Jan.
|
||||
fourth_jan = datetime.date(iso_year, 1, 4)
|
||||
delta = datetime.timedelta(fourth_jan.isoweekday() - 1)
|
||||
year_start = fourth_jan - delta
|
||||
gregorian = year_start + datetime.timedelta(days=iso_day - 1, weeks=iso_week - 1)
|
||||
|
||||
return gregorian
|
||||
|
||||
|
||||
def validate_bounds(bounds: str) -> None:
|
||||
if bounds != "()" and bounds != "(]" and bounds != "[)" and bounds != "[]":
|
||||
raise ValueError(
|
||||
"Invalid bounds. Please select between '()', '(]', '[)', or '[]'."
|
||||
)
|
||||
|
||||
|
||||
__all__ = ["next_weekday", "is_timestamp", "validate_ordinal", "iso_to_gregorian"]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue