LCOV - code coverage report
Current view: top level - src - clock-time.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 131 131 100.0 %
Date: 2017-04-30 Functions: 30 30 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Present - Date/Time Library
       3             :  *
       4             :  * Implementation of the ClockTime methods
       5             :  *
       6             :  * Licensed under the MIT License.
       7             :  * For details, see LICENSE.
       8             :  */
       9             : 
      10             : #include <assert.h>
      11             : #include <stddef.h>
      12             : 
      13             : #include "present.h"
      14             : 
      15             : #include "utils/constants.h"
      16             : #include "utils/impl-utils.h"
      17             : #include "utils/time-utils.h"
      18             : 
      19             : /**
      20             :  * Initialize a new ClockTime instance based on its data parameters.
      21             :  */
      22             : static void
      23        1444 : init_clock_time(
      24             :         struct ClockTime * const result,
      25             :         int_hour hour,
      26             :         int_minute minute,
      27             :         int_second second,
      28             :         int_nanosecond nanosecond)
      29             : {
      30        1444 :     assert(result != NULL);
      31        1444 :     CLEAR(result);
      32             : 
      33        1444 :     if (hour == 24) hour = 0;
      34        1444 :     if (hour < 0 || hour > 24) {
      35           5 :         result->has_error = 1;
      36           5 :         result->errors.hour_out_of_range = 1;
      37             :     }
      38             : 
      39        1444 :     if (minute < 0 || minute >= 60) {
      40           5 :         result->has_error = 1;
      41           5 :         result->errors.minute_out_of_range = 1;
      42             :     }
      43             : 
      44             :     /* 61 because of leap seconds :( */
      45        1444 :     if (second < 0 || second >= 61) {
      46           9 :         result->has_error = 1;
      47           9 :         result->errors.second_out_of_range = 1;
      48             :     }
      49             : 
      50        1444 :     if (nanosecond < 0 || nanosecond >= NANOSECONDS_IN_SECOND) {
      51           4 :         result->has_error = 1;
      52           4 :         result->errors.nanosecond_out_of_range = 1;
      53             :     }
      54             : 
      55        1444 :     if (!result->has_error) {
      56        2846 :         result->data_.seconds = second +
      57        2846 :             minute * SECONDS_IN_MINUTE +
      58        1423 :             hour * SECONDS_IN_HOUR;
      59        1423 :         result->data_.nanoseconds = nanosecond;
      60             :     }
      61        1444 : }
      62             : 
      63             : /**
      64             :  * Check the bounds on data.{nanosecond,second} and modify or wrap around if
      65             :  * necessary.
      66             :  */
      67             : static void
      68          13 : check_clock_time(struct ClockTime * const self)
      69             : {
      70             : #define d self->data_
      71          13 :     if (d.nanoseconds >= NANOSECONDS_IN_SECOND) {
      72           1 :         d.seconds += d.nanoseconds / NANOSECONDS_IN_SECOND;
      73           1 :         d.nanoseconds %= NANOSECONDS_IN_SECOND;
      74             :     }
      75          27 :     while (d.nanoseconds < 0) {
      76           1 :         d.seconds -= 1;
      77           1 :         d.nanoseconds += NANOSECONDS_IN_SECOND;
      78             :     }
      79             : 
      80          13 :     if (d.seconds >= SECONDS_IN_DAY) {
      81           1 :         d.seconds %= SECONDS_IN_DAY;
      82             :     }
      83          27 :     while (d.seconds < 0) {
      84           1 :         d.seconds += SECONDS_IN_DAY;
      85             :     }
      86             : #undef d
      87          13 : }
      88             : 
      89             : 
      90             : struct ClockTime
      91           3 : ClockTime_from_hour(int_hour hour)
      92             : {
      93             :     struct ClockTime result;
      94           3 :     init_clock_time(&result, hour, 0, 0, 0);
      95           3 :     return result;
      96             : }
      97             : 
      98             : void
      99           9 : ClockTime_ptr_from_hour(struct ClockTime * const result, int_hour hour)
     100             : {
     101           9 :     init_clock_time(result, hour, 0, 0, 0);
     102           9 : }
     103             : 
     104             : struct ClockTime
     105           3 : ClockTime_from_hour_minute(int_hour hour, int_minute minute)
     106             : {
     107             :     struct ClockTime result;
     108           3 :     init_clock_time(&result, hour, minute, 0, 0);
     109           3 :     return result;
     110             : }
     111             : 
     112             : void
     113          10 : ClockTime_ptr_from_hour_minute(
     114             :         struct ClockTime * const result,
     115             :         int_hour hour,
     116             :         int_minute minute)
     117             : {
     118          10 :     init_clock_time(result, hour, minute, 0, 0);
     119          10 : }
     120             : 
     121             : struct ClockTime
     122           3 : ClockTime_from_hour_minute_second(
     123             :         int_hour hour,
     124             :         int_minute minute,
     125             :         int_second second)
     126             : {
     127             :     struct ClockTime result;
     128           3 :     init_clock_time(&result, hour, minute, second, 0);
     129           3 :     return result;
     130             : }
     131             : 
     132             : void
     133         164 : ClockTime_ptr_from_hour_minute_second(
     134             :         struct ClockTime * const result,
     135             :         int_hour hour,
     136             :         int_minute minute,
     137             :         int_second second)
     138             : {
     139         164 :     init_clock_time(result, hour, minute, second, 0);
     140         164 : }
     141             : 
     142             : struct ClockTime
     143           3 : ClockTime_from_hour_minute_second_nanosecond(
     144             :         int_hour hour,
     145             :         int_minute minute,
     146             :         int_second second,
     147             :         int_nanosecond nanosecond)
     148             : {
     149             :     struct ClockTime result;
     150           3 :     init_clock_time(&result, hour, minute, second, nanosecond);
     151           3 :     return result;
     152             : }
     153             : 
     154             : void
     155          23 : ClockTime_ptr_from_hour_minute_second_nanosecond(
     156             :         struct ClockTime * const result,
     157             :         int_hour hour,
     158             :         int_minute minute,
     159             :         int_second second,
     160             :         int_nanosecond nanosecond)
     161             : {
     162          23 :     init_clock_time(result, hour, minute, second, nanosecond);
     163          23 : }
     164             : 
     165             : struct ClockTime
     166           2 : ClockTime_create_with_decimal_seconds(
     167             :         int_hour hour,
     168             :         int_minute minute,
     169             :         double second)
     170             : {
     171             :     struct ClockTime result;
     172           2 :     ClockTime_ptr_create_with_decimal_seconds(&result, hour, minute, second);
     173           2 :     return result;
     174             : }
     175             : 
     176             : void
     177          10 : ClockTime_ptr_create_with_decimal_seconds(
     178             :         struct ClockTime * const result,
     179             :         int_hour hour,
     180             :         int_minute minute,
     181             :         double second)
     182             : {
     183             :     int_second second_int;
     184             : 
     185          10 :     second_int = (int_second) second;
     186          10 :     second = (second - second_int) * (double) NANOSECONDS_IN_SECOND;
     187          10 :     init_clock_time(result, hour, minute, second_int,
     188          10 :             (int_nanosecond) present_round(second));
     189          10 : }
     190             : 
     191             : struct ClockTime
     192           1 : ClockTime_midnight(void)
     193             : {
     194             :     struct ClockTime result;
     195           1 :     init_clock_time(&result, 0, 0, 0, 0);
     196           1 :     return result;
     197             : }
     198             : 
     199             : void
     200        1207 : ClockTime_ptr_midnight(struct ClockTime * const result)
     201             : {
     202        1207 :     init_clock_time(result, 0, 0, 0, 0);
     203        1207 : }
     204             : 
     205             : struct ClockTime
     206           5 : ClockTime_noon(void)
     207             : {
     208             :     struct ClockTime result;
     209           5 :     init_clock_time(&result, 12, 0, 0, 0);
     210           5 :     return result;
     211             : }
     212             : 
     213             : void
     214           3 : ClockTime_ptr_noon(struct ClockTime * const result)
     215             : {
     216           3 :     init_clock_time(result, 12, 0, 0, 0);
     217           3 : }
     218             : 
     219             : int_hour
     220          61 : ClockTime_hour(const struct ClockTime * const self)
     221             : {
     222          61 :     assert(self != NULL);
     223          61 :     assert(self->has_error == 0);
     224             : 
     225          61 :     return self->data_.seconds / SECONDS_IN_HOUR;
     226             : }
     227             : 
     228             : int_minute
     229          97 : ClockTime_minute(const struct ClockTime * const self)
     230             : {
     231          97 :     assert(self != NULL);
     232          97 :     assert(self->has_error == 0);
     233             : 
     234          97 :     return self->data_.seconds % SECONDS_IN_HOUR / SECONDS_IN_MINUTE;
     235             : }
     236             : 
     237             : int_second
     238          39 : ClockTime_second(const struct ClockTime * const self)
     239             : {
     240          39 :     assert(self != NULL);
     241          39 :     assert(self->has_error == 0);
     242             : 
     243          39 :     return self->data_.seconds % SECONDS_IN_MINUTE;
     244             : }
     245             : 
     246             : int_nanosecond
     247          38 : ClockTime_nanosecond(const struct ClockTime * const self)
     248             : {
     249          38 :     assert(self != NULL);
     250          38 :     assert(self->has_error == 0);
     251             : 
     252          38 :     return self->data_.nanoseconds;
     253             : }
     254             : 
     255             : double
     256          60 : ClockTime_second_decimal(const struct ClockTime * const self)
     257             : {
     258          60 :     assert(self != NULL);
     259          60 :     assert(self->has_error == 0);
     260             : 
     261         120 :     return (self->data_.seconds % SECONDS_IN_MINUTE) +
     262          60 :            ((double)self->data_.nanoseconds / (double)NANOSECONDS_IN_SECOND);
     263             : }
     264             : 
     265             : struct TimeDelta
     266        1255 : ClockTime_time_since_midnight(const struct ClockTime * const self)
     267             : {
     268             :     struct TimeDelta delta, ns_delta;
     269             : 
     270        1255 :     assert(self != NULL);
     271        1255 :     assert(self->has_error == 0);
     272             : 
     273        1255 :     delta = TimeDelta_from_seconds(self->data_.seconds);
     274        1255 :     ns_delta = TimeDelta_from_nanoseconds(self->data_.nanoseconds);
     275        1255 :     TimeDelta_add(&delta, &ns_delta);
     276        1255 :     return delta;
     277             : }
     278             : 
     279             : void
     280           7 : ClockTime_add_TimeDelta(
     281             :         struct ClockTime * const self,
     282             :         const struct TimeDelta * const delta)
     283             : {
     284           7 :     assert(self != NULL);
     285           7 :     assert(self->has_error == 0);
     286           7 :     assert(delta != NULL);
     287             : 
     288           7 :     self->data_.seconds += delta->data_.delta_seconds;
     289           7 :     self->data_.nanoseconds += delta->data_.delta_nanoseconds;
     290             : 
     291           7 :     check_clock_time(self);
     292           7 : }
     293             : 
     294             : void
     295           6 : ClockTime_subtract_TimeDelta(
     296             :         struct ClockTime * const self,
     297             :         const struct TimeDelta * const delta)
     298             : {
     299           6 :     assert(self != NULL);
     300           6 :     assert(self->has_error == 0);
     301           6 :     assert(delta != NULL);
     302             : 
     303           6 :     self->data_.seconds -= delta->data_.delta_seconds;
     304           6 :     self->data_.nanoseconds -= delta->data_.delta_nanoseconds;
     305             : 
     306           6 :     check_clock_time(self);
     307           6 : }
     308             : 
     309             : short
     310          40 : ClockTime_compare(
     311             :         const struct ClockTime * const lhs,
     312             :         const struct ClockTime * const rhs)
     313             : {
     314          40 :     assert(lhs != NULL);
     315          40 :     assert(lhs->has_error == 0);
     316          40 :     assert(rhs != NULL);
     317          40 :     assert(rhs->has_error == 0);
     318             : 
     319         121 :     return
     320         121 :         STRUCT_COMPARE(seconds,
     321             :             STRUCT_COMPARE(nanoseconds, 0));
     322             : }
     323             : 
     324          36 : STRUCT_COMPARISON_OPERATORS(ClockTime)
     325             : 

Generated by: LCOV version 1.10