@@ -20,9 +20,9 @@ extern "C"
2020#include "rcutils/time.h"
2121
2222#include <inttypes.h>
23- #include <stdint.h>
2423#include <stdio.h>
2524#include <stdlib.h>
25+ #include <time.h>
2626
2727#include "rcutils/allocator.h"
2828#include "rcutils/error_handling.h"
@@ -46,6 +46,61 @@ rcutils_time_point_value_as_nanoseconds_string(
4646 return RCUTILS_RET_OK ;
4747}
4848
49+ rcutils_ret_t
50+ rcutils_time_point_value_as_date_string (
51+ const rcutils_time_point_value_t * time_point ,
52+ char * str ,
53+ size_t str_size )
54+ {
55+ RCUTILS_CHECK_ARGUMENT_FOR_NULL (time_point , RCUTILS_RET_INVALID_ARGUMENT );
56+ RCUTILS_CHECK_ARGUMENT_FOR_NULL (str , RCUTILS_RET_INVALID_ARGUMENT );
57+ if (0 == str_size ) {
58+ return RCUTILS_RET_OK ;
59+ }
60+ // best to abs it to avoid issues with negative values in C89, see:
61+ // https://stackoverflow.com/a/3604984/671658
62+ uint64_t abs_time_point = (uint64_t )llabs (* time_point );
63+ // break into two parts to avoid floating point error
64+ uint64_t seconds = abs_time_point / (1000u * 1000u * 1000u );
65+ uint64_t nanoseconds = abs_time_point % (1000u * 1000u * 1000u );
66+ // Make sure the buffer is large enough to hold the largest possible uint64_t
67+ char nanoseconds_str [21 ];
68+
69+ if (rcutils_snprintf (nanoseconds_str , sizeof (nanoseconds_str ), "%" PRIu64 , nanoseconds ) < 0 ) {
70+ RCUTILS_SET_ERROR_MSG ("failed to format time point nanoseconds into string" );
71+ return RCUTILS_RET_ERROR ;
72+ }
73+
74+ time_t now_t = (time_t )(seconds );
75+ struct tm ptm = {.tm_year = 0 , .tm_mday = 0 };
76+ #ifdef _WIN32
77+ if (localtime_s (& ptm , & now_t ) != 0 ) {
78+ RCUTILS_SET_ERROR_MSG ("failed to get localtime" );
79+ return RCUTILS_RET_ERROR ;
80+ }
81+ #else
82+ if (localtime_r (& now_t , & ptm ) == NULL ) {
83+ RCUTILS_SET_ERROR_MSG ("failed to get localtime" );
84+ return RCUTILS_RET_ERROR ;
85+ }
86+ #endif
87+
88+ if (str_size < 32 || strftime (str , 32 , "%Y-%m-%d %H:%M:%S" , & ptm ) == 0 ) {
89+ RCUTILS_SET_ERROR_MSG ("failed to format time point into string as iso8601_date" );
90+ return RCUTILS_RET_ERROR ;
91+ }
92+ static const int date_end_position = 19 ;
93+ if (rcutils_snprintf (
94+ & str [date_end_position ], str_size - date_end_position , ".%.3s" ,
95+ nanoseconds_str ) < 0 )
96+ {
97+ RCUTILS_SET_ERROR_MSG ("failed to format time point into string as date_time_with_ms" );
98+ return RCUTILS_RET_ERROR ;
99+ }
100+
101+ return RCUTILS_RET_OK ;
102+ }
103+
49104rcutils_ret_t
50105rcutils_time_point_value_as_seconds_string (
51106 const rcutils_time_point_value_t * time_point ,
0 commit comments