Source code for hum.utils.date_ticks

"""
Date utils
"""

import numpy as np
from datetime import datetime as dt

unit_str_to_unit_in_seconds = {
    'day': 3600 * 24,
    'hour': 3600,
    'h': 3600,
    'minute': 60,
    'mn': 60,
    'second': 1,
    's': 1,
    'millisecond': 0.001,
    'ms': 0.001,
    'microsecond': 1e-6,
    'us': 1e-6,
}

unit_in_seconds = np.array(
    [
        60 * 60 * 24 * 365,  # year
        60 * 60 * 24 * 30,  # month
        60 * 60 * 24 * 7,  # week
        60 * 60 * 24,  # day
        60 * 60,  # hour
        60,  # minute
        1,  # second
        1e-3,  # millisecond
        1e-6,  # microsecond
        1e-9,  # nanosecond
    ]
)

strftime_format_for_unit = {
    60 * 60 * 24 * 30: '%y-%m-%d',  # month
    60 * 60 * 24 * 7: '%b %d',  # week
    60 * 60 * 24: '%b %d',  # day
    60 * 60: '%d-%H:%M',  # hour
    60: '%H:%M:%S',  # minute
    1: '%M:%S.%f',  # second
    1e-3: "%S''%f",  # millisecond
    1e-6: "%S''%f",  # microsecond
}


def utc_datetime_from_val_and_unit(val, unit):
    if isinstance(unit, str):
        unit = unit_str_to_unit_in_seconds[unit]
    return dt.utcfromtimestamp(val * unit)


[docs]def largest_unit_that_changes_at_every_tick(ticks, ticks_unit): """ Returns the largest time unit for which each time tick changes. :param ticks: The list of ticks :param ticks_unit: The unit of the elements of ticks, expressed in seconds. For example, if the list contains hours, unit=3600, if minutes, unit=60, if seconds unit=1, if milliseconds unit=0.001. Note: You can also use a string to express the unit, as long as it's recognized by the unit_str_to_unit_in_seconds dict. Keys recognized: ['day', 'hour', 'h', 'minute', 'mn', 'second', 's', 'millisecond', 'ms', 'microsecond', 'us'] :return: """ ticks = np.array(ticks) if isinstance(ticks_unit, str): ticks_unit = unit_str_to_unit_in_seconds[ticks_unit] min_tick_diff = min(np.diff(ticks)) min_tick_diff *= ticks_unit # convert to seconds for u in unit_in_seconds: if u < min_tick_diff: return u
def strftime_format_for_ticks(ticks, ticks_unit): unit = largest_unit_that_changes_at_every_tick(ticks, ticks_unit) return strftime_format_for_unit[unit]
[docs]def strftime_with_precision(tick, format, sub_secs_precision=2): """ Returns a formatted string for a datetime (tick). :param tick: The datetime for this tick :param format: The formatting string :param sub_secs_precision: Number of digits to used for sub-seconds. If None, will choose it "smartly/dynamically" :return: Formatted string """ t = tick.strftime(format) is_us = '%f' in format if is_us: if sub_secs_precision is None: while t[-1] == '0': t = t[:-1] while not t[-1].isdigit(): t = t[:-1] return t else: if sub_secs_precision < 0: sub_secs_precision = 0 elif sub_secs_precision > 6: sub_secs_precision = 6 DFLT_PRECISION = 6 digits_to_skip = DFLT_PRECISION - sub_secs_precision if digits_to_skip == 0: return t else: t = t[:-digits_to_skip] while not t[-1].isdigit(): t = t[:-1] return t else: return t
def str_ticks(ticks, ticks_unit, sub_secs_precision=2): t_format = strftime_format_for_ticks(ticks, ticks_unit) return [ strftime_with_precision( utc_datetime_from_val_and_unit(x, ticks_unit), t_format, sub_secs_precision, ) for x in ticks ] def unit_aligned_ticks(ticks, ticks_unit): pass