propertime package¶
Submodules¶
propertime.time module¶
Time and TimeSpan classes
-
class
propertime.time.Time(*args, tz='UTC', offset='auto', guessing=False)¶ Bases:
floatA time object, as a floating point number corresponding to the number of seconds after the zero on the time axis. This is commonly known as Epoch, and set to 1st January 1970 UTC. Any other representations (as calendar time, time zones and daylight saving times) are built on top of it.
It can be initialized in three main ways:
Time(): if no arguments are given, then time is set to now;Time(1703517120.3): it the argument is a number, it is treated as Epoch seconds;Time(2023,5,6,13,45): if there is more than one argument, a datetime-like mode is used, with year, month, day, hour and second components all mandatory and in this order.
In all three cases, by default the time is assumed on UTC. To create a time instance on a specific time zone, or with a specific UTC offset, you can use their respective keyword arguments
tzandoffset. Sub-second precision for the datetime-like initialization mode can be achieved by setting a floating point value to the seconds component. Time can also be initialized using its string representation:Time(str(Time(2023,5,6,13,45, tz='US/Eastern'))will instantiate a time object equivalent to the original one.The initialization in case of ambiguous or not-existent time specifications generates an error:
Time(2023,11,5,1,15, tz='US/Eastern')is ambiguous as there are “two” 1:15 AM on DST change on time zone US/Eastern, andTime(2023,3,12,2,30, tz='US/Eastern')just does not exists on such time zone. Creating time objects form an ambiguous time specification can be forced by enabling the “guessing” mode (guessing=True), but it will only be possible to create one of the two. To address this issue, use Epoch seconds or provide an UTC offset.- Parameters:
*args – the time value, either as seconds (float), datetime-like components (year, month, day, hour, minute, second) or string representation. If no value is given, then time is set to now.
tz (
str,tzinfo) – the time zone, either as string representation or tzinfo object (including pytz and ZoneInfo). Defaults to ‘UTC’.offset (
float,int) – the offset, in seconds, with respect to UTC. Defaults to ‘auto’, which sets it accordingly to the time zone. If set explicitly, it has to be consistent with the time zone, or the time zone has to be set to None.guessing (
bool) – if to enable guessing mode in case of ambiguous time specifications. Defaults to False.
-
classmethod
from_dt(dt, tz='auto', offset='auto', guessing=False)¶ Create a Time object form a datetime. If naive, then a time zone or an offset is required.
Please note that tz and offset arguments, if set to something else than “auto” when using a timezone-aware (or offset-aware) datetime, will “move” it to the given time zone or offset.
For example,
Time.from_dt(dt(2023,5,6,13,45, tz='US/Eastern'), tz='Europe/Rome')will result in the Time object corresponding to 2023-05-06 19:45:00 Europe/Rome.- Parameters:
dt (
datetime) – the datetime from which to create the new Time object.tz (
str,tzinfo) – the time zone, either as string representation or tzinfo object. Defaults to ‘UTC’.offset (
float,int) – the offset, in seconds, with respect to UTC. Defaults to ‘auto’, which sets it accordingly to the time zone. If set explicitly, it has to be consistent with the time zone, or the time zone has to be set to None.guessing (
bool) – if to enable guessing mode in case of ambiguous time specifications. Defaults to False.
-
classmethod
from_iso(iso, tz='auto', offset='auto')¶ Create a Time object form an ISO 8601 string. If naive, then a time zone or an offset is required.
Please note that tz and offset arguments, if set to something else than “auto” when using a UTC-aware (or offset-aware) ISO string, will “move” it to the given time zone or offset.
For example,
Time.from_iso('2023-12-25T16:12:00+01:00', tz='US/Eastern')will result in the Time object corresponding to 2023-12-25 10:12:00 US/Eastern.- Parameters:
dt (
datetime) – the datetime from which to create the new Time object.tz (
str,tzinfo) – the time zone, either as string representation or tzinfo object. Defaults to ‘UTC’.offset (
float,int) – the offset, in seconds, with respect to UTC. Defaults to ‘auto’, which sets it accordingly to the time zone. If set explicitly, it has to be consistent with the time zone, or the time zone has to be set to None.
-
to_dt()¶ Return time as a datetime object.
-
to_iso()¶ Return time as a string in ISO 8601 format.
-
property
tz¶ The time zone of the time. If this was set with a string (including the default ‘UTC’ value), then this is a pytz object. Otherwise, it is the exact same object used for the tz argument, assuming it was a valid tzinfo (e.g. a ZoneInfo).
-
property
offset¶ The (UTC) offset of the time, in seconds.
-
as_tz(tz)¶ Get this time on another time zone.
-
as_offset(offset)¶ Get this time with another (UTC) offset.
-
is_integer()¶ Return True if time is an integer, i.e. it has no or zero sub-seconds.
-
as_integer_ratio()¶ Return time as integer ratio.
-
classmethod
fromhex(string)¶ Create time from a hexadecimal string.
-
hex()¶ Return a hexadecimal representation of time.
-
conjugate()¶ Disabled. It does not make sense to use imaginary numbers with time.
-
imag()¶ Disabled. It does not make sense to use imaginary numbers with time.
-
real()¶ Disabled. It does not make sense to use imaginary numbers with time.
-
class
propertime.time.TimeSpan(value=None, years=0, weeks=0, months=0, days=0, hours=0, minutes=0, seconds=0)¶ Bases:
objectA time span object, that can have either fixed or variable length (duration). Whether this is variable or not, it depends if there are any calendar time components involved (years, months, weeks and days).
Time spans support many operations, and can be added and subtracted with numerical values, Propertime’s time objects, datetime objects, as well as other time spans.
Their initialization supports both string representations and explicitly setting the various components: years, months, weeks, days, hours, minutes and seconds. Sub-second precision can be achieved by using a floating point value for the seconds component.
In the string representation, the mapping is as follows:
'Y': 'years''M': 'months''W': 'weeks''D': 'days''h': 'hours''m': 'minutes''s': 'seconds'
For example, to create a time span of one hour, the following four are equivalent:
TimeSpan('1h') == TimeSpan('3600s') == TimeSpan(seconds=3600) == TimeSpan(hours=1)
The first two use the string representation, while the third and the fourth explicitly set its components (hours and seconds, in this case).
To get the time span length, or duration, you can use the
as_seconds()method:TimeSpan('1h').as_seconds()
However, as soon as a calendar time component kicks in, the time span length becomes variable: a time span of one day can last for 23, 24 or 24 hours (and thus 82800, 86400 and 90000 seconds) depending on DST changes. Similarly, a month can have 28, 29, 30 or 31 days; and a year can have both 365 and 366 days.
Note indeed that:
TimeSpan('24h') != TimeSpan('1D')
The length of a time span where one ore more calendar time components are involved is therefore well defined only if providing context about when it is applied:
TimeSpan('1D').as_seconds(starting_at=some_time)
This is automatically handled when using time spans to perform operations, so that for example to get to tomorow’s same time of the day, you would just do:
Time() + TimeSpan('1D')
…and the time span will take care of computing the correct calendar arithmetic, including the DST change. If you instead wanted to add exactly 24 hours, thus getting to a different time of the day if DST changed within the time span, you would have used:
Time() + TimeSpan('24h')
Lastly, when calendar time components are involved, there might be also some undefined or ambiguous operations. And exactly as it would happen if dividing a number by zero, they will cause an error:
Time(2023,1,31) + TimeSpan(months=1) # Error, the 31st of February does not exist Time(2023,3,25,2,15,0, tz='Europe/Rome') + TimeSpan(days=1) # Error, the 2:15 AM does not exist on Europe/Rome in the target day Time(2023,10,28,2,15,0, tz='Europe/Rome') + TimeSpan(days=1) # Error, there are two 2:15 AM on Europe/Rome in the target day
- Parameters:
value (
str) – the time span value as string representation.years (
int) – the time span years component.weeks (
int) – the time span weeks component.months (
int) – the time span weeks component.days (
int) – the time span days component.hours (
int) – the time span hours component.minutes (
int) – the time span minutes component.seconds (
int,float) – the time span seconds, as float to include sub-second precision (up to the microsecond).
-
round(time, how='half')¶ Round a time or datetime object according to this TimeSpan.
-
floor(time)¶ Floor a time or datetime object according to this time span.
-
ceil(time)¶ Ceil a time or datetime object according to this time span.
-
shift(time, times=1)¶ Shift a given time or datetime object of n times this time span.
-
as_seconds(starting_at=None)¶ The length (duration) of the time span, in seconds.
Time manipulation utilities
-
propertime.utils.timezonize(tz)¶ Convert a string representation of a time zone to a pytz object, or just re-return the argument if this is already a valid time zone, offset or None
-
propertime.utils.is_dt_inconsistent(dt)¶ Check that a datetieme object is consistent with its time zone (some conditions can lead to have summer time set in winter, or to end up in non-existent times as when changing DST).
-
propertime.utils.is_dt_ambiguous_without_offset(dt)¶ Check if a datetime object is specified in an ambiguous way on a given time zone
-
propertime.utils.now_s()¶ Return the current time in epoch seconds.
-
propertime.utils.now_dt(tz='UTC')¶ Return the current time in datetime format.
-
propertime.utils.dt(*args, **kwargs)¶ Initialize a datetime object with the time zone in the proper way. Using the standard datetime initialization leads to various problems if setting a pytz time zone.
- Parameters:
year (int) – the year.
month (int) – the month.
day (int) – the day.
hour (int) – the hour, defaults to 0.
minute (int) – the minute, Defaults to 0.
second (int) – the second, Defaults to 0.
microsecond (int) – the microsecond, Defaults to None.
naive (bool) – if to create a naive (without time zone) datetime.
tz (tzinfo, pytz, str) – the time zone, defaults to UTC or None if naive is set.
offset_s (int,float) – an optional offset, in seconds.
trustme (bool) – if to skip sanity checks. Defaults to False.
guessing (bool) – if to enable guessing mode and guess in ambiguous situations.
-
propertime.utils.get_tz_offset(dt)¶ Get the time zone offset, in seconds.
-
propertime.utils.get_offset_from_dt(dt)¶ Get the offset from a datetime, in seconds.
-
propertime.utils.correct_dt_dst(dt)¶ Correct the DST of a datetime object, by re-creating it.
-
propertime.utils.as_tz(dt, tz)¶ Get a datetime object as if it was on the given time zone.
- Parameters:
dt (datetime) – the datetime object.
tz (tzinfo,pytz,str) – the time zone.
-
propertime.utils.dt_from_s(s, tz='UTC')¶ Create a datetime object from epoch seconds. If no time zone is given, UTC is assumed.
-
propertime.utils.s_from_dt(dt, tz=None)¶ Return the epoch seconds from a datetime object, with floating point for milliseconds/microseconds.
-
propertime.utils.dt_from_str(string, tz=None)¶ Create a datetime object from a string.
This is a basic IS0 8601, see https://www.w3.org/TR/NOTE-datetime
- Supported formats on UTC:
YYYY-MM-DDThh:mm:ssZ
YYYY-MM-DDThh:mm:ss.{u}Z
- Supported formats with offset
YYYY-MM-DDThh:mm:ss+ZZ:ZZ
YYYY-MM-DDThh:mm:ss.{u}+ZZ:ZZ
- Other supported formats:
YYYY-MM-DDThh:mm:ss (without the trailing Z, treated as naive)
-
propertime.utils.str_from_dt(dt)¶ Return the a string representation of a datetime object (as IS08601).
-
propertime.utils.is_numerical(item)¶ Check if the argument is numerical.
The library logger
-
propertime.logger.setup(level='CRITICAL', force=False)¶ Setup the library logger at the given level. Checks also if such logger is already inizialized and if there are any inconsistencies between the legger levels, and force the new level if required to.
Common exceptions
-
exception
propertime.exceptions.ConsistencyError¶ Bases:
ExceptionRaised when there is an internal consistency error.