Source code for majis.misc.time

"""Time miscellaneous module."""

import re

from numpy import datetime64, timedelta64

from planetary_coverage import datetime

from .evf import EVF_KEY, read_evf, ref_key

# Timedelta pattern: 'EVENT_NAME (COUNT = N) [-+][JJJ.]HH:MM:SS[.MS]'
EVF_TD = (
    r'^' + EVF_KEY + r'\s+'
    r'(?P<sign>[+-])?'
    r'(?:(?P<day>\d+)\.)?'
    r'(?P<h>\d{2})'
    r':'
    r'(?P<m>\d{2})'
    r':'
    r'(?P<s>\d{2})'
    r'(?:\.(?P<ms>\d+))?'
)


[docs] def get_datetime(time: str, refs: dict | str | list | None = None) -> datetime64: """Datetime getter.""" if match := re.match(EVF_TD, time): ref, count, sign, d, h, m, s, ms = match.groups() # Extract reference absolute time if refs and not isinstance(refs, dict): refs = read_evf(refs) if not refs or (key := (ref.upper(), int(count))) not in refs: raise KeyError(f'Unknown time reference: `{ref} (COUNT = {count})`') # Compute time delta to reference t_delta = (-1 if sign == '-' else 1) * ( timedelta64(int(d) if d else 0, 'D') + timedelta64(int(h), 'h') + timedelta64(int(m), 'm') + timedelta64(int(s), 's') + (timedelta64(int(1_000 * float(f'0.{ms}')), 'ms') if ms else 0) ) return refs[key] + t_delta t, *_ = str(time).strip().split() return datetime(t)
[docs] def fmt_datetime( *times: str | datetime64, ref: str | dict | tuple | None = None ) -> str | list[str]: """Format relative datetime for a time or a list of times.""" if ref is not None: key, t_ref = ref_key(ref) t = [f'{key} {fmt_timedelta(datetime(t) - t_ref)}' for t in times] else: t = [ (datetime(t).item().strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z').replace( '.000Z', 'Z' ) for t in times ] return t if len(times) > 1 else t[0]
[docs] def fmt_timedelta(dt: timedelta64) -> str: """Format time delta.""" t = abs(dt.item()) h, r = divmod(t.seconds, 3600) m, s = divmod(r, 60) out = '-' if dt < 0 else '+' out += f'{t.days:03d}.' out += f'{h:02d}:{m:02d}:{s:02d}' out += f'.{t.microseconds // 1_000:03d}' return out