Time control functions

Some generally helpful time control functions for base QC.

marine_qc.time_control.convert_date(params)[source]

Decorator to extract date components and inject them as function parameters.

This decorator intercepts the ‘date’ argument from the function call, splits it into its components (e.g., year, month, day), and assigns those components to specified parameters in the wrapped function. It supports scalar or sequence inputs for ‘date’.

Parameters:

params (list of str) – List of parameter names corresponding to date components to be extracted and passed to the decorated function.

Return type:

Callable[..., Any]

Returns:

Callable[..., Any] – A decorator that wraps a function, extracting date components before calling it.

Notes

  • The decorator expects the wrapped function to accept the parameters listed in params. If a parameter is missing, it raises a ValueError.

  • If the ‘date’ argument is None, the original function is called without modification.

  • Supports scalar-like ‘date’ values as well as iterable sequences.

  • Assumes a helper function split_date exists that splits a date into components and returns a dictionary mapping parameter names to their values.

marine_qc.time_control.convert_date_to_hours(dates)[source]

Convert an array of datetimes to an array of hours since the first element.

Parameters:

dates (array-like of datetime, shape (n,)) – 1-dimensional date array.

Return type:

Sequence[float]

Returns:

array-like of float, shape (n,) – 1- dimensional array containing hours since the first element in the array.

marine_qc.time_control.convert_time_in_hours(hour, minute, sec, zone, daylight_savings_time)[source]

Convert integer hour, minute, and second to time in decimal hours.

Parameters:
  • hour (int) – Hour.

  • minute (int) – Minute.

  • sec (int) – Second.

  • zone (int or float) – Correction for timezone.

  • daylight_savings_time (float) – Set to 1 if daylight savings time is in effect else set to 0.

Return type:

float

Returns:

float – Time converted to decimal hour in day.

marine_qc.time_control.day_in_year(year=None, month=1, day=1)[source]

Get the day in year from 1 to 365 or 366.

Parameters:
  • year (int, optional, default: None) – Year to be tested. If none, set year to default leap year.

  • month (int, default: 1) – Month to be tested.

  • day (int, default: 1) – Day to be tested.

Return type:

int

Returns:

int – Day in year. If year is not specified then the year is treated as a non-leap year and 29 February returns the same value as 1 March.

marine_qc.time_control.day_in_year_array(month, day)[source]

Get the day in year from 1 to 365. Leap years are dealt with by allowing Feb 29 and Mar 1 to be the same day.

Parameters:
  • month (1D np.ndarray) – Array of months.

  • day (1D np.ndarray) – Array of days.

Return type:

ndarray

Returns:

np.ndarray – Array of day number from 1-365.

marine_qc.time_control.get_month_lengths(year)[source]

Return a list holding the lengths of the months in a given year.

Parameters:

year (int) – Year for which you want month lengths.

Return type:

list[int]

Returns:

list of int – List of month lengths.

marine_qc.time_control.jul_day(year, month, day)[source]

Routine to calculate julian day. This is the weird Astronomical thing which counts from 1 Jan 4713 BC.

Parameters:
  • year (int) – Year.

  • month (int) – Month.

  • day (int) – Day.

Return type:

int

Returns:

int – Julian day.

Notes

This is one of those routines that looks baffling but works. No one is sure exactly how. It gets written once and then remains untouched for centuries, mysteriously working.

marine_qc.time_control.leap_year(years_since_1980)[source]

Check if input year is a Leap year.

Parameters:

years_since_1980 (int) – Number of years since 1980.

Return type:

int

Returns:

int – 1 if it is a leap year, 0 otherwise.

marine_qc.time_control.leap_year_correction(time_in_hours, day, years_since_1980)[source]

Make leap year correction.

Parameters:
  • time_in_hours (float) – Time in hours.

  • day (int) – Day number.

  • years_since_1980 (int) – Years since 1980.

Return type:

float

Returns:

float – Leap year corrected time.

marine_qc.time_control.pentad_to_month_day(p)[source]

Given a pentad number, return the month and day of the first day in the pentad.

Parameters:

p (int) – Pentad number from 1 to 73.

Return type:

tuple[int, int]

Returns:

tuple of int – A tuple of two ints representing month and day of the first day of the pentad.

marine_qc.time_control.relative_year_number(year, reference=1979)[source]

Get number of year relative to reference year (1979 by default).

Parameters:
  • year (int) – Year.

  • reference (int, default: 1979) – Reference year.

Return type:

int

Returns:

int – Number of year relative to reference year.

marine_qc.time_control.split_date(date)[source]

Split datetime date into year, month, day and hour.

Parameters:

date (datetime) – Date to split.

Return type:

dict[str, float]

Returns:

dict – Dictionary containing year, month, day and hour.

marine_qc.time_control.time_difference(times1, times2)[source]

Convert two arrays of datetimes to the difference in hours.

Parameters:
Return type:

ndarray

Returns:

array-like of float, shape (n,) – 1-dimensional array containing the time difference in hours computed as times2 - times1.

Raises:

TypeError – If inspect_arrays does not return np.ndarrays.

marine_qc.time_control.time_in_whole_days(time_in_hours, day, years_since_1980, leap)[source]

Calculate from time in hours to time in whole days.

Parameters:
  • time_in_hours (int) – Time in hours.

  • day (int) – Day number.

  • years_since_1980 (int) – Number of years since 1980.

  • leap (int) – Set to 1 for a leap year, else set to 0.

Return type:

float

Returns:

float – Time in whole days.

marine_qc.time_control.valid_month_day(year=None, month=1, day=1)[source]

Return True if month and day combination are allowed, False otherwise. Assumes that Feb 29th is valid.

Parameters:
  • year (int, optional, default: None) – Year to be tested. If none, set year to default leap year.

  • month (int, default: 1) – Month to be tested.

  • day (int, default: 1) – Day to be tested.

Return type:

bool

Returns:

bool – True if month and day (or year month and day) are a valid combination (e.g. 12th March) and False if not (e.g. 30th February).

Notes

Assumes that February 29th is a valid date.

marine_qc.time_control.which_pentad(month, day)[source]

Take month and day as inputs and return pentad in range 1-73.

Parameters:
  • month (int) – Month containing the day for which we want to calculate the pentad.

  • day (int) – Day for the day for which we want to calculate the pentad.

Return type:

int

Returns:

int – Pentad (5-day period) containing input day, from 1 (1 Jan-5 Jan) to 73 (27-31 Dec).

Raises:

ValueError – If month not in range 1-12 or day not in range 1-31.

Notes

The calculation is rather simple. It just loops through the year and adds up days till it reaches the day we are interested in. February 29th is treated as though it were March 1st in a regular year.

marine_qc.time_control.which_pentad_array(month, day)[source]

Take month and day arrays as inputs and return array of pentads in range 1-73.

Parameters:
  • month (ndarray) – Month containing the day for which we want to calculate the pentad.

  • day (ndarray) – Day for the day for which we want to calculate the pentad.

Return type:

ndarray

Returns:

ndarray – Pentad (5-day period) containing input day, from 1 (1 Jan-5 Jan) to 73 (27-31 Dec).