trainlog/tui/src/timeutil.c

116 lines
3.4 KiB
C

/**
* @file timeutil.c
* @brief Local RFC3339 timestamp generation.
*/
#include "trainlog/timeutil.h"
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdint.h>
#include "timestamp.h"
TrainlogStatus trainlog_time_now_rfc3339(
char *output,
size_t output_size
)
{
time_t now;
struct tm local;
char date_part[32];
char offset_part[8];
char offset_with_colon[7];
int written;
if (output == NULL || output_size < 26U) {
return TRAINLOG_STATUS_INVALID_ARGUMENT;
}
now = time(NULL);
if (now == (time_t)-1) {
return TRAINLOG_STATUS_SYSTEM_ERROR;
}
if (localtime_r(&now, &local) == NULL) {
return TRAINLOG_STATUS_SYSTEM_ERROR;
}
if (strftime(
date_part,
sizeof(date_part),
"%Y-%m-%dT%H:%M:%S",
&local
) == 0U) {
return TRAINLOG_STATUS_SYSTEM_ERROR;
}
if (strftime(
offset_part,
sizeof(offset_part),
"%z",
&local
) != 5U) {
return TRAINLOG_STATUS_SYSTEM_ERROR;
}
offset_with_colon[0] = offset_part[0];
offset_with_colon[1] = offset_part[1];
offset_with_colon[2] = offset_part[2];
offset_with_colon[3] = ':';
offset_with_colon[4] = offset_part[3];
offset_with_colon[5] = offset_part[4];
offset_with_colon[6] = '\0';
written = snprintf(
output,
output_size,
"%s%s",
date_part,
offset_with_colon
);
if (written < 0 || (size_t)written >= output_size) {
return TRAINLOG_STATUS_SYSTEM_ERROR;
}
return TRAINLOG_STATUS_OK;
}
TrainlogStatus trainlog_feedback_relative_label(
const char *ended_at, const char *started_at, const char *observed_at,
bool exercise_feedback,
char *output, size_t output_size)
{
TrainlogTimestampKey ended, started, observed;
int written;
int64_t elapsed;
if (observed_at == NULL || output == NULL || output_size == 0U)
return TRAINLOG_STATUS_INVALID_ARGUMENT;
if (!trainlog_timestamp_parse(observed_at, strlen(observed_at), &observed)) {
written = snprintf(output, output_size, "H+?");
} else if (ended_at == NULL || ended_at[0] == '\0' ||
!trainlog_timestamp_parse(ended_at, strlen(ended_at), &ended)) {
if (started_at != NULL && started_at[0] != '\0' &&
trainlog_timestamp_parse(started_at, strlen(started_at), &started) &&
observed.utc_second >= started.utc_second) {
elapsed = observed.utc_second - started.utc_second;
written = snprintf(output, output_size, "≈H+%lld",
(long long)(elapsed / INT64_C(3600)));
} else written = snprintf(output, output_size, "H+?");
} else if (observed.utc_second < ended.utc_second) {
bool within_session = exercise_feedback && started_at != NULL &&
started_at[0] != '\0' &&
trainlog_timestamp_parse(started_at, strlen(started_at), &started) &&
observed.utc_second >= started.utc_second;
written = snprintf(output, output_size, "%s",
within_session ? "Pendant la séance" : "H+?");
} else {
elapsed = observed.utc_second - ended.utc_second;
written = snprintf(output, output_size, "H+%lld",
(long long)(elapsed / INT64_C(3600)));
}
return written >= 0 && (size_t)written < output_size
? TRAINLOG_STATUS_OK : TRAINLOG_STATUS_INVALID_ARGUMENT;
}