Source code for dolfyn.time

from datetime import datetime, timedelta, timezone
import numpy as np
from .tools.misc import fillgaps


def _fullyear(year):
    if year > 100:
        return year
    year += 1900 + 100 * (year < 90)
    return year


[docs] def epoch2dt64(ep_time): """Convert from epoch time (seconds since 1/1/1970 00:00:00) to numpy.datetime64 array Parameters ---------- ep_time : xarray.DataArray Time coordinate data-array or single time element Returns ------- time : numpy.datetime64 The converted datetime64 array """ # assumes t0=1970-01-01 00:00:00 out = np.array(ep_time.astype('int')).astype('datetime64[s]') out = out + ((ep_time % 1) * 1e9).astype('timedelta64[ns]') return out
[docs] def dt642epoch(dt64): """Convert numpy.datetime64 array to epoch time (seconds since 1/1/1970 00:00:00) Parameters ---------- dt64 : numpy.datetime64 Single or array of datetime64 object(s) Returns ------- time : float Epoch time (seconds since 1/1/1970 00:00:00) """ return dt64.astype('datetime64[ns]').astype('float') / 1e9
[docs] def date2dt64(dt): """Convert numpy.datetime64 array to list of datetime objects Parameters ---------- time : datetime.datetime The converted datetime object Returns ------- dt64 : numpy.datetime64 Single or array of datetime64 object(s) """ return np.array(dt).astype('datetime64[ns]')
[docs] def dt642date(dt64): """Convert numpy.datetime64 array to list of datetime objects Parameters ---------- dt64 : numpy.datetime64 Single or array of datetime64 object(s) Returns ------- time : datetime.datetime The converted datetime object """ return epoch2date(dt642epoch(dt64))
[docs] def epoch2date(ep_time, offset_hr=0, to_str=False): """Convert from epoch time (seconds since 1/1/1970 00:00:00) to a list of datetime objects Parameters ---------- ep_time : xarray.DataArray Time coordinate data-array or single time element offset_hr : int Number of hours to offset time by (e.g. UTC -7 hours = PDT) to_str : logical Converts datetime object to a readable string Returns ------- time : datetime.datetime The converted datetime object or list(strings) Notes ----- The specific time instance is set during deployment, usually sync'd to the deployment computer. The time seen by |dlfn| is in the timezone of the deployment computer, which is unknown to |dlfn|. """ try: ep_time = ep_time.values except AttributeError: pass if isinstance(ep_time, (np.ndarray)) and ep_time.ndim == 0: ep_time = [ep_time.item()] elif not isinstance(ep_time, (np.ndarray, list)): ep_time = [ep_time] ######### IMPORTANT ######### # Note the use of `utcfromtimestamp` here, rather than `fromtimestamp` # This is CRITICAL! See the difference between those functions here: # https://docs.python.org/3/library/datetime.html#datetime.datetime.fromtimestamp # Long story short: `fromtimestamp` used system-specific timezone # info to calculate the datetime object, but returns a # timezone-agnostic object. if offset_hr != 0: delta = timedelta(hours=offset_hr) time = [datetime.utcfromtimestamp(t) + delta for t in ep_time] else: time = [datetime.utcfromtimestamp(t) for t in ep_time] if to_str: time = date2str(time) return time
[docs] def date2str(dt, format_str=None): """Convert list of datetime objects to legible strings Parameters ---------- dt : datetime.datetime Single or list of datetime object(s) format_str : string Timestamp string formatting, default: '%Y-%m-%d %H:%M:%S.%f'. See datetime.strftime documentation for timestamp string formatting Returns ------- time : string Converted timestamps """ if format_str is None: format_str = '%Y-%m-%d %H:%M:%S.%f' if not isinstance(dt, list): dt = [dt] return [t.strftime(format_str) for t in dt]
[docs] def date2epoch(dt): """Convert list of datetime objects to epoch time Parameters ---------- dt : datetime.datetime Single or list of datetime object(s) Returns ------- time : float Datetime converted to epoch time (seconds since 1/1/1970 00:00:00) """ if not isinstance(dt, list): dt = [dt] return [t.replace(tzinfo=timezone.utc).timestamp() for t in dt]
[docs] def date2matlab(dt): """Convert list of datetime objects to MATLAB datenum Parameters ---------- dt : datetime.datetime List of datetime objects Returns ------- time : float List of timestamps in MATLAB datnum format """ time = list() for i in range(len(dt)): mdn = dt[i] + timedelta(days=366) frac_seconds = (dt[i]-datetime(dt[i].year, dt[i].month, dt[i].day, 0, 0, 0)).seconds / (24*60*60) frac_microseconds = dt[i].microsecond / (24*60*60*1000000) time.append(mdn.toordinal() + frac_seconds + frac_microseconds) return time
[docs] def matlab2date(matlab_dn): """Convert MATLAB datenum to list of datetime objects Parameters ---------- matlab_dn : float List of timestamps in MATLAB datnum format Returns ------- dt : datetime.datetime List of datetime objects """ time = list() for i in range(len(matlab_dn)): day = datetime.fromordinal(int(matlab_dn[i])) dayfrac = timedelta(days=matlab_dn[i] % 1) - timedelta(days=366) time.append(day + dayfrac) # Datenum is precise down to 100 microseconds - add difference to round us = int(round(time[i].microsecond/100, 0))*100 time[i] = time[i].replace(microsecond=time[i].microsecond) + \ timedelta(microseconds=us-time[i].microsecond) return time
def _fill_time_gaps(epoch, sample_rate_hz): """Fill gaps (NaN values) in the timeseries by simple linear interpolation. The ends are extrapolated by stepping forward/backward by 1/sample_rate_hz. """ # epoch is seconds since 1970 dt = 1. / sample_rate_hz epoch = fillgaps(epoch) if np.isnan(epoch[0]): i0 = np.nonzero(~np.isnan(epoch))[0][0] delta = np.arange(-i0, 0, 1) * dt epoch[:i0] = epoch[i0] + delta if np.isnan(epoch[-1]): # Search backward through the array to get the 'negative index' ie = -np.nonzero(~np.isnan(epoch[::-1]))[0][0] - 1 delta = np.arange(1, -ie, 1) * dt epoch[(ie + 1):] = epoch[ie] + delta return epoch