LCOV - code coverage report
Current view: top level - src - timestamp.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 261 269 97.0 %
Date: 2017-04-30 Functions: 42 48 87.5 %

          Line data    Source code
       1             : /*
       2             :  * Present - Date/Time Library
       3             :  *
       4             :  * Implementation of the Timestamp 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             :  * Convert a struct tm to a Date.
      21             :  *
      22             :  * Precondition: The struct tm must be valid (see @p clean_struct_tm).
      23             :  */
      24             : static void
      25        1256 : struct_tm_to_date(const struct tm * const tm, struct Date * const date)
      26             : {
      27        3768 :     Date_ptr_from_year_month_day(
      28             :             date,
      29        1256 :             tm->tm_year + STRUCT_TM_YEAR_OFFSET,
      30        1256 :             tm->tm_mon + STRUCT_TM_MONTH_OFFSET,
      31        1256 :             tm->tm_mday);
      32        1256 : }
      33             : 
      34             : /**
      35             :  * Convert a struct tm to a ClockTime.
      36             :  *
      37             :  * Precondition: The struct tm must be valid (see @p clean_struct_tm).
      38             :  */
      39             : static void
      40         136 : struct_tm_to_clock_time(
      41             :         const struct tm * const tm,
      42             :         struct ClockTime * const clock_time)
      43             : {
      44         408 :     ClockTime_ptr_from_hour_minute_second(
      45             :             clock_time,
      46         136 :             tm->tm_hour,
      47         136 :             tm->tm_min,
      48         136 :             tm->tm_sec);
      49         136 : }
      50             : 
      51             : /**
      52             :  * Check additional_nanoseconds to make sure it is a positive integer less
      53             :  * than NANOSECONDS_IN_SECOND.
      54             :  */
      55             : #define CHECK_DATA(data)                                            \
      56             :     do {                                                            \
      57             :         while (data.additional_nanoseconds < 0) {                   \
      58             :             data.timestamp_seconds -= 1;                            \
      59             :             data.additional_nanoseconds += NANOSECONDS_IN_SECOND;   \
      60             :         }                                                           \
      61             :         if (data.additional_nanoseconds >= NANOSECONDS_IN_SECOND) { \
      62             :             data.timestamp_seconds += data.additional_nanoseconds / \
      63             :                 NANOSECONDS_IN_SECOND;                              \
      64             :             data.additional_nanoseconds %= NANOSECONDS_IN_SECOND;   \
      65             :         }                                                           \
      66             :     } while (0)
      67             : 
      68             : /**
      69             :  * Check a Date and a ClockTime to make sure they aren't erroneous (if so, set
      70             :  * the proper errors on "result").
      71             :  */
      72             : #define CHECK_DATE_AND_CLOCK_TIME(date, clock_time) \
      73             :     do {                                            \
      74             :         if ((date)->has_error) {                    \
      75             :             result->has_error = 1;                  \
      76             :             result->errors.invalid_date = 1;        \
      77             :         }                                           \
      78             :         if ((clock_time)->has_error) {              \
      79             :             result->has_error = 1;                  \
      80             :             result->errors.invalid_clock_time = 1;  \
      81             :         }                                           \
      82             :     } while (0)
      83             : 
      84             : 
      85             : /** Initialize a new Timestamp instance based on its data parameters. */
      86             : static void
      87        1273 : init_timestamp(
      88             :         struct Timestamp * const result,
      89             :         int_timestamp timestamp_seconds,
      90             :         int_timestamp additional_nanoseconds)
      91             : {
      92        1273 :     assert(result != NULL);
      93        1273 :     CLEAR(result);
      94             : 
      95        1273 :     result->data_.timestamp_seconds = timestamp_seconds;
      96        1273 :     result->data_.additional_nanoseconds = additional_nanoseconds;
      97        1273 : }
      98             : 
      99             : /**
     100             :  * Initialize a new Timestamp instance based on a Date and a ClockTime in UTC.
     101             :  */
     102             : static void
     103        1254 : init_timestamp_from_date_and_clock_time_utc(
     104             :         struct Timestamp * const result,
     105             :         const struct Date * const date,
     106             :         const struct ClockTime * const clock_time)
     107             : {
     108             :     struct TimeDelta time_since_midnight;
     109             : 
     110        1254 :     assert(result != NULL);
     111        1254 :     assert(date != NULL);
     112        1254 :     assert(clock_time != NULL);
     113             : 
     114        1254 :     CLEAR(result);
     115             : 
     116             :     /* Make sure the Date and ClockTime aren't erroneous */
     117        1254 :     CHECK_DATE_AND_CLOCK_TIME(date, clock_time);
     118             : 
     119        1254 :     if (!result->has_error) {
     120             :         /* This is a more useful form of the clock time */
     121        1252 :         time_since_midnight = ClockTime_time_since_midnight(clock_time);
     122             : 
     123        2504 :         init_timestamp(
     124             :                 result,
     125        1252 :                 to_unix_timestamp(
     126             :                         Date_year(date),
     127             :                         Date_month(date),
     128             :                         Date_day(date),
     129             :                         0, 0, 0) +
     130        1252 :                     time_since_midnight.data_.delta_seconds,
     131             :                 time_since_midnight.data_.delta_nanoseconds);
     132             :     }
     133        1254 : }
     134             : 
     135             : /**
     136             :  * Initialize a new Timestamp instance based on a Date, a ClockTime, and a time
     137             :  * zone offset.
     138             :  */
     139             : static void
     140          38 : init_timestamp_from_date_and_clock_time(
     141             :         struct Timestamp * const result,
     142             :         const struct Date * const date,
     143             :         const struct ClockTime * const clock_time,
     144             :         const struct TimeDelta * const time_zone_offset)
     145             : {
     146          38 :     assert(result != NULL);
     147          38 :     assert(date != NULL);
     148          38 :     assert(clock_time != NULL);
     149             : 
     150          38 :     CLEAR(result);
     151             : 
     152             :     /* Make sure the Date and ClockTime aren't erroneous */
     153          38 :     CHECK_DATE_AND_CLOCK_TIME(date, clock_time);
     154             : 
     155          38 :     if (!result->has_error) {
     156             :         /* First, pretend it's just UTC */
     157          36 :         init_timestamp_from_date_and_clock_time_utc(result, date, clock_time);
     158             :         /* Now, subtract the UTC offset (since we're technically converting
     159             :            TO UTC) */
     160          36 :         Timestamp_subtract_TimeDelta(result, time_zone_offset);
     161             :     }
     162          38 : }
     163             : 
     164             : /**
     165             :  * Initialize a new Timestamp instance based on a "struct tm" in the system's
     166             :  * current local time zone.
     167             :  */
     168             : static void
     169           2 : init_timestamp_from_struct_tm_local(
     170             :         struct Timestamp * const result,
     171             :         const struct tm tm)
     172             : {
     173             :     struct tm tm_copy;
     174             :     time_t time;
     175             : 
     176           2 :     tm_copy = tm;
     177             :     /* Throw it right through mktime */
     178           2 :     time = struct_tm_to_time_t_local(&tm_copy);
     179           2 :     init_timestamp(result, time_t_to_unix_timestamp(time), 0);
     180           2 : }
     181             : 
     182             : 
     183             : struct Timestamp
     184           2 : Timestamp_from_time_t(const time_t time)
     185             : {
     186             :     struct Timestamp result;
     187           2 :     init_timestamp(&result, time_t_to_unix_timestamp(time), 0);
     188           2 :     return result;
     189             : }
     190             : 
     191             : void
     192          10 : Timestamp_ptr_from_time_t(
     193             :         struct Timestamp * const result,
     194             :         const time_t time)
     195             : {
     196          10 :     init_timestamp(result, time_t_to_unix_timestamp(time), 0);
     197          10 : }
     198             : 
     199             : struct Timestamp
     200           6 : Timestamp_from_struct_tm(
     201             :         const struct tm tm,
     202             :         const struct TimeDelta * const time_zone_offset)
     203             : {
     204             :     struct Timestamp result;
     205           6 :     Timestamp_ptr_from_struct_tm(&result, tm, time_zone_offset);
     206           6 :     return result;
     207             : }
     208             : 
     209             : void
     210          18 : Timestamp_ptr_from_struct_tm(
     211             :         struct Timestamp * const result,
     212             :         const struct tm tm,
     213             :         const struct TimeDelta * const time_zone_offset)
     214             : {
     215             :     struct Date date;
     216             :     struct ClockTime clock_time;
     217             :     struct tm tm_copy;
     218             : 
     219          18 :     tm_copy = tm;
     220          18 :     clean_struct_tm(&tm_copy);
     221             : 
     222          18 :     struct_tm_to_date(&tm_copy, &date);
     223          18 :     struct_tm_to_clock_time(&tm_copy, &clock_time);
     224          18 :     init_timestamp_from_date_and_clock_time(
     225             :             result, &date, &clock_time, time_zone_offset);
     226          18 : }
     227             : 
     228             : struct Timestamp
     229           1 : Timestamp_from_struct_tm_utc(const struct tm tm)
     230             : {
     231             :     struct Timestamp result;
     232           1 :     Timestamp_ptr_from_struct_tm_utc(&result, tm);
     233           1 :     return result;
     234             : }
     235             : 
     236             : void
     237           2 : Timestamp_ptr_from_struct_tm_utc(
     238             :         struct Timestamp * const result,
     239             :         const struct tm tm)
     240             : {
     241             :     struct Date date;
     242             :     struct ClockTime clock_time;
     243             :     struct tm tm_copy;
     244             : 
     245           2 :     tm_copy = tm;
     246           2 :     clean_struct_tm(&tm_copy);
     247             : 
     248           2 :     struct_tm_to_date(&tm_copy, &date);
     249           2 :     struct_tm_to_clock_time(&tm_copy, &clock_time);
     250           2 :     init_timestamp_from_date_and_clock_time_utc(result, &date, &clock_time);
     251           2 : }
     252             : 
     253             : struct Timestamp
     254           1 : Timestamp_from_struct_tm_local(const struct tm tm)
     255             : {
     256             :     struct Timestamp result;
     257           1 :     Timestamp_ptr_from_struct_tm_local(&result, tm);
     258           1 :     return result;
     259             : }
     260             : 
     261             : void
     262           1 : Timestamp_ptr_from_struct_tm_local(
     263             :         struct Timestamp * const result,
     264             :         const struct tm tm)
     265             : {
     266           1 :     init_timestamp_from_struct_tm_local(result, tm);
     267           1 : }
     268             : 
     269             : struct Timestamp
     270           6 : Timestamp_create(
     271             :         const struct Date * const date,
     272             :         const struct ClockTime * const clock_time,
     273             :         const struct TimeDelta * const time_zone_offset)
     274             : {
     275             :     struct Timestamp result;
     276           6 :     Timestamp_ptr_create(&result, date, clock_time, time_zone_offset);
     277           6 :     return result;
     278             : }
     279             : 
     280             : void
     281          20 : Timestamp_ptr_create(
     282             :         struct Timestamp * const result,
     283             :         const struct Date * const date,
     284             :         const struct ClockTime * const clock_time,
     285             :         const struct TimeDelta * const time_zone_offset)
     286             : {
     287          20 :     init_timestamp_from_date_and_clock_time(
     288             :             result, date, clock_time, time_zone_offset);
     289          20 : }
     290             : 
     291             : struct Timestamp
     292           8 : Timestamp_create_utc(
     293             :         const struct Date * const date,
     294             :         const struct ClockTime * const clock_time)
     295             : {
     296             :     struct Timestamp result;
     297           8 :     Timestamp_ptr_create_utc(&result, date, clock_time);
     298           8 :     return result;
     299             : }
     300             : 
     301             : void
     302        1216 : Timestamp_ptr_create_utc(
     303             :         struct Timestamp * const result,
     304             :         const struct Date * const date,
     305             :         const struct ClockTime * const clock_time)
     306             : {
     307        1216 :     init_timestamp_from_date_and_clock_time_utc(result, date, clock_time);
     308        1216 : }
     309             : 
     310             : struct Timestamp
     311           1 : Timestamp_create_local(
     312             :         const struct Date * const date,
     313             :         const struct ClockTime * const clock_time)
     314             : {
     315             :     struct Timestamp result;
     316           1 :     Timestamp_ptr_create_local(&result, date, clock_time);
     317           1 :     return result;
     318             : }
     319             : 
     320             : void
     321           3 : Timestamp_ptr_create_local(
     322             :         struct Timestamp * const result,
     323             :         const struct Date * const date,
     324             :         const struct ClockTime * const clock_time)
     325             : {
     326             :     struct tm tm;
     327             : 
     328           3 :     assert(result != NULL);
     329           3 :     assert(date != NULL);
     330           3 :     assert(clock_time != NULL);
     331             : 
     332           3 :     CLEAR(result);
     333             : 
     334             :     /* Make sure the Date and ClockTime aren't erroneous */
     335           3 :     CHECK_DATE_AND_CLOCK_TIME(date, clock_time);
     336             : 
     337           3 :     if (!result->has_error) {
     338           1 :         CLEAR(&tm);
     339           1 :         tm.tm_year = Date_year(date) - STRUCT_TM_YEAR_OFFSET;
     340           1 :         tm.tm_mon = Date_month(date) - STRUCT_TM_MONTH_OFFSET;
     341           1 :         tm.tm_mday = Date_day(date);
     342           1 :         tm.tm_hour = ClockTime_hour(clock_time);
     343           1 :         tm.tm_min = ClockTime_minute(clock_time);
     344           1 :         tm.tm_sec = ClockTime_second(clock_time);
     345           1 :         tm.tm_isdst = -1;
     346             : 
     347           1 :         init_timestamp_from_struct_tm_local(
     348             :                 result,
     349             :                 tm);
     350             :     }
     351           3 : }
     352             : 
     353             : struct Timestamp
     354           1 : Timestamp_now(void)
     355             : {
     356             :     struct Timestamp result;
     357           1 :     Timestamp_ptr_now(&result);
     358           1 :     return result;
     359             : }
     360             : 
     361             : void
     362           4 : Timestamp_ptr_now(struct Timestamp * const result)
     363             : {
     364             :     struct PresentNowStruct now;
     365           4 :     present_now(&now);
     366           4 :     init_timestamp(result, time_t_to_unix_timestamp(now.sec), now.nsec);
     367           4 : }
     368             : 
     369             : struct Timestamp
     370           1 : Timestamp_epoch(void)
     371             : {
     372             :     struct Timestamp result;
     373           1 :     init_timestamp(&result, 0, 0);
     374           1 :     return result;
     375             : }
     376             : 
     377             : void
     378           2 : Timestamp_ptr_epoch(struct Timestamp * const result)
     379             : {
     380           2 :     init_timestamp(result, 0, 0);
     381           2 : }
     382             : 
     383             : time_t
     384           7 : Timestamp_get_time_t(const struct Timestamp * const self)
     385             : {
     386           7 :     assert(self != NULL);
     387           7 :     assert(self->has_error == 0);
     388             : 
     389           7 :     return unix_timestamp_to_time_t(self->data_.timestamp_seconds);
     390             : }
     391             : 
     392             : struct tm
     393           8 : Timestamp_get_struct_tm(
     394             :         const struct Timestamp * const self,
     395             :         const struct TimeDelta * const time_zone_offset)
     396             : {
     397             :     struct Timestamp copy;
     398             : 
     399           8 :     assert(self != NULL);
     400           8 :     assert(self->has_error == 0);
     401           8 :     assert(time_zone_offset != NULL);
     402             : 
     403           8 :     copy = *self;
     404           8 :     Timestamp_add_TimeDelta(&copy, time_zone_offset);
     405           8 :     return Timestamp_get_struct_tm_utc(&copy);
     406             : }
     407             : 
     408             : struct tm
     409        1351 : Timestamp_get_struct_tm_utc(const struct Timestamp * const self)
     410             : {
     411             :     time_t time;
     412             :     struct tm result;
     413             : 
     414        1351 :     assert(self != NULL);
     415        1351 :     assert(self->has_error == 0);
     416             : 
     417        1351 :     time = unix_timestamp_to_time_t(self->data_.timestamp_seconds);
     418        1351 :     time_t_to_struct_tm(&time, &result);
     419        1351 :     return result;
     420             : }
     421             : 
     422             : struct tm
     423           6 : Timestamp_get_struct_tm_local(const struct Timestamp * const self)
     424             : {
     425             :     time_t time;
     426             :     struct tm result;
     427             : 
     428           6 :     assert(self != NULL);
     429           6 :     assert(self->has_error == 0);
     430             : 
     431           6 :     time = unix_timestamp_to_time_t(self->data_.timestamp_seconds);
     432           6 :     time_t_to_struct_tm_local(&time, &result);
     433           6 :     return result;
     434             : }
     435             : 
     436             : struct Date
     437           3 : Timestamp_get_date(
     438             :         const struct Timestamp * const self,
     439             :         const struct TimeDelta * const time_zone_offset)
     440             : {
     441             :     struct tm tm;
     442             :     struct Date date;
     443             : 
     444           3 :     assert(self != NULL);
     445           3 :     assert(self->has_error == 0);
     446           3 :     assert(time_zone_offset != NULL);
     447             : 
     448           3 :     tm = Timestamp_get_struct_tm(self, time_zone_offset);
     449           3 :     struct_tm_to_date(&tm, &date);
     450           3 :     return date;
     451             : }
     452             : 
     453             : struct Date
     454        1231 : Timestamp_get_date_utc(const struct Timestamp * const self)
     455             : {
     456             :     struct tm tm;
     457             :     struct Date date;
     458             : 
     459        1231 :     assert(self != NULL);
     460        1231 :     assert(self->has_error == 0);
     461             : 
     462        1231 :     tm = Timestamp_get_struct_tm_utc(self);
     463        1231 :     struct_tm_to_date(&tm, &date);
     464        1231 :     return date;
     465             : }
     466             : 
     467             : struct Date
     468           2 : Timestamp_get_date_local(const struct Timestamp * const self)
     469             : {
     470             :     struct tm tm;
     471             :     struct Date date;
     472             : 
     473           2 :     assert(self != NULL);
     474           2 :     assert(self->has_error == 0);
     475             : 
     476           2 :     tm = Timestamp_get_struct_tm_local(self);
     477           2 :     struct_tm_to_date(&tm, &date);
     478           2 :     return date;
     479             : }
     480             : 
     481             : struct ClockTime
     482           3 : Timestamp_get_clock_time(
     483             :         const struct Timestamp * const self,
     484             :         const struct TimeDelta * const time_zone_offset)
     485             : {
     486             :     struct tm tm;
     487             :     struct ClockTime clock_time;
     488             : 
     489           3 :     assert(self != NULL);
     490           3 :     assert(self->has_error == 0);
     491             : 
     492           3 :     tm = Timestamp_get_struct_tm(self, time_zone_offset);
     493           3 :     struct_tm_to_clock_time(&tm, &clock_time);
     494           3 :     return clock_time;
     495             : }
     496             : 
     497             : struct ClockTime
     498         111 : Timestamp_get_clock_time_utc(const struct Timestamp * const self)
     499             : {
     500             :     struct tm tm;
     501             :     struct ClockTime clock_time;
     502             : 
     503         111 :     assert(self != NULL);
     504         111 :     assert(self->has_error == 0);
     505             : 
     506         111 :     tm = Timestamp_get_struct_tm_utc(self);
     507         111 :     struct_tm_to_clock_time(&tm, &clock_time);
     508         111 :     return clock_time;
     509             : }
     510             : 
     511             : struct ClockTime
     512           2 : Timestamp_get_clock_time_local(const struct Timestamp * const self)
     513             : {
     514             :     struct tm tm;
     515             :     struct ClockTime clock_time;
     516             : 
     517           2 :     assert(self != NULL);
     518           2 :     assert(self->has_error == 0);
     519             : 
     520           2 :     tm = Timestamp_get_struct_tm_local(self);
     521           2 :     struct_tm_to_clock_time(&tm, &clock_time);
     522           2 :     return clock_time;
     523             : }
     524             : 
     525             : struct TimeDelta
     526           8 : Timestamp_difference(
     527             :         const struct Timestamp * const self,
     528             :         const struct Timestamp * const other)
     529             : {
     530             :     struct TimeDelta delta, ns_delta;
     531             : 
     532           8 :     assert(self != NULL);
     533           8 :     assert(self->has_error == 0);
     534           8 :     assert(other != NULL);
     535           8 :     assert(other->has_error == 0);
     536             : 
     537           8 :     delta = TimeDelta_from_seconds(
     538           8 :             self->data_.timestamp_seconds - other->data_.timestamp_seconds);
     539           8 :     ns_delta = TimeDelta_from_nanoseconds(
     540           8 :             self->data_.additional_nanoseconds -
     541           8 :             other->data_.additional_nanoseconds);
     542           8 :     TimeDelta_add(&delta, &ns_delta);
     543           8 :     return delta;
     544             : }
     545             : 
     546             : struct TimeDelta
     547           2 : Timestamp_absolute_difference(
     548             :         const struct Timestamp * const self,
     549             :         const struct Timestamp * const other)
     550             : {
     551             :     struct TimeDelta delta;
     552             : 
     553           2 :     assert(self != NULL);
     554           2 :     assert(self->has_error == 0);
     555           2 :     assert(other != NULL);
     556           2 :     assert(other->has_error == 0);
     557             : 
     558           2 :     delta = Timestamp_difference(self, other);
     559           2 :     if (TimeDelta_is_negative(&delta)) {
     560           1 :         TimeDelta_negate(&delta);
     561             :     }
     562           2 :     return delta;
     563             : }
     564             : 
     565             : void
     566          10 : Timestamp_add_TimeDelta(
     567             :         struct Timestamp * const self,
     568             :         const struct TimeDelta * const delta)
     569             : {
     570          10 :     assert(self != NULL);
     571          10 :     assert(self->has_error == 0);
     572          10 :     assert(delta != NULL);
     573             : 
     574          10 :     self->data_.timestamp_seconds += delta->data_.delta_seconds;
     575          10 :     self->data_.additional_nanoseconds += delta->data_.delta_nanoseconds;
     576          10 :     CHECK_DATA(self->data_);
     577          10 : }
     578             : 
     579             : void
     580           8 : Timestamp_add_DayDelta(
     581             :         struct Timestamp * const self,
     582             :         const struct DayDelta * const delta)
     583             : {
     584           8 :     assert(self != NULL);
     585           8 :     assert(self->has_error == 0);
     586           8 :     assert(delta != NULL);
     587             : 
     588           8 :     self->data_.timestamp_seconds += delta->data_.delta_days * SECONDS_IN_DAY;
     589           8 : }
     590             : 
     591             : void
     592           8 : Timestamp_add_MonthDelta(
     593             :         struct Timestamp * const self,
     594             :         const struct MonthDelta * const delta)
     595             : {
     596             :     time_t time;
     597             :     struct tm tm;
     598             : 
     599           8 :     assert(self != NULL);
     600           8 :     assert(self->has_error == 0);
     601           8 :     assert(delta != NULL);
     602             : 
     603           8 :     time = unix_timestamp_to_time_t(self->data_.timestamp_seconds);
     604           8 :     time_t_to_struct_tm(&time, &tm);
     605           8 :     tm.tm_mon += delta->data_.delta_months;
     606          48 :     self->data_.timestamp_seconds = time_t_to_unix_timestamp(to_unix_timestamp(
     607           8 :             tm.tm_year + STRUCT_TM_YEAR_OFFSET,
     608           8 :             tm.tm_mon + STRUCT_TM_MONTH_OFFSET,
     609           8 :             tm.tm_mday,
     610           8 :             tm.tm_hour,
     611           8 :             tm.tm_min,
     612           8 :             tm.tm_sec));
     613           8 : }
     614             : 
     615             : void
     616          38 : Timestamp_subtract_TimeDelta(
     617             :         struct Timestamp * const self,
     618             :         const struct TimeDelta * const delta)
     619             : {
     620          38 :     assert(self != NULL);
     621          38 :     assert(self->has_error == 0);
     622          38 :     assert(delta != NULL);
     623             : 
     624          38 :     self->data_.timestamp_seconds -= delta->data_.delta_seconds;
     625          38 :     self->data_.additional_nanoseconds -= delta->data_.delta_nanoseconds;
     626          38 :     CHECK_DATA(self->data_);
     627          38 : }
     628             : 
     629             : void
     630           6 : Timestamp_subtract_DayDelta(
     631             :         struct Timestamp * const self,
     632             :         const struct DayDelta * const delta)
     633             : {
     634           6 :     assert(self != NULL);
     635           6 :     assert(self->has_error == 0);
     636           6 :     assert(delta != NULL);
     637             : 
     638           6 :     self->data_.timestamp_seconds -= delta->data_.delta_days * SECONDS_IN_DAY;
     639           6 : }
     640             : 
     641             : void
     642           7 : Timestamp_subtract_MonthDelta(
     643             :         struct Timestamp * const self,
     644             :         const struct MonthDelta * const delta)
     645             : {
     646             :     time_t time;
     647             :     struct tm tm;
     648             : 
     649           7 :     assert(self != NULL);
     650           7 :     assert(self->has_error == 0);
     651           7 :     assert(delta != NULL);
     652             : 
     653           7 :     time = unix_timestamp_to_time_t(self->data_.timestamp_seconds);
     654           7 :     time_t_to_struct_tm(&time, &tm);
     655           7 :     tm.tm_mon -= delta->data_.delta_months;
     656          42 :     self->data_.timestamp_seconds = time_t_to_unix_timestamp(to_unix_timestamp(
     657           7 :             tm.tm_year + STRUCT_TM_YEAR_OFFSET,
     658           7 :             tm.tm_mon + STRUCT_TM_MONTH_OFFSET,
     659           7 :             tm.tm_mday,
     660           7 :             tm.tm_hour,
     661           7 :             tm.tm_min,
     662           7 :             tm.tm_sec));
     663           7 : }
     664             : 
     665             : short
     666           0 : Timestamp_compare(
     667             :         const struct Timestamp * const lhs,
     668             :         const struct Timestamp * const rhs)
     669             : {
     670           0 :     assert(lhs != NULL);
     671           0 :     assert(lhs->has_error == 0);
     672           0 :     assert(rhs != NULL);
     673           0 :     assert(rhs->has_error == 0);
     674             : 
     675           0 :     return
     676           0 :         STRUCT_COMPARE(timestamp_seconds,
     677             :             STRUCT_COMPARE(additional_nanoseconds, 0));
     678             : }
     679             : 
     680           0 : STRUCT_COMPARISON_OPERATORS(Timestamp)
     681             : 

Generated by: LCOV version 1.10