mirror of
https://github.com/gungwald/alarm-clock-6502.git
synced 2024-09-09 18:54:46 +00:00
155 lines
3.6 KiB
C
155 lines
3.6 KiB
C
#include <stdio.h> /* printf, scanf */
|
|
#include <stdbool.h> /* bool */
|
|
#include <string.h> /* strerror */
|
|
#include <time.h> /* time_t, time, localtime */
|
|
#include <ctype.h> /* toupper */
|
|
#include <errno.h> /* errno */
|
|
#include <stdlib.h> /* atoi */
|
|
|
|
#include "time.h"
|
|
|
|
#define TIME_ERR_RESULT ((time_t) -1)
|
|
#define LOCALTIME_ERR_RESULT NULL
|
|
#define ERR_MSG_SIZE 128
|
|
|
|
static const char *AM="AM";
|
|
static const char *PM="PM";
|
|
|
|
static char *to_upper_case(char *s);
|
|
static void set_err_msg(char *prefix, int errno);
|
|
static void copy_struct_tm(struct tm *dest, struct tm *src);
|
|
static const char *convert_24_hour_to_meridiem(uint8_t hours);
|
|
static uint8_t convert_12_hour_to_24_hour(uint8_t twelve_hour, char *meridiem);
|
|
static void convert_24_hour_to_12_hour(uint8_t twenty_four_hour, uint8_t *twelve_hour, char const **meridiem);
|
|
|
|
static char G_err_msg[ERR_MSG_SIZE];
|
|
|
|
void copy_struct_tm(struct tm *dest, struct tm *src)
|
|
{
|
|
dest->tm_sec = src->tm_sec;
|
|
dest->tm_min = src->tm_sec;
|
|
dest->tm_hour = src->tm_hour;
|
|
dest->tm_mday = src->tm_mday;
|
|
dest->tm_mon = src->tm_mon;
|
|
dest->tm_year = src->tm_year;
|
|
dest->tm_wday = src->tm_wday;
|
|
dest->tm_yday = src->tm_wday;
|
|
dest->tm_isdst = src->tm_isdst;
|
|
}
|
|
|
|
static const char *convert_24_hour_to_meridiem(uint8_t hours)
|
|
{
|
|
if (hours < 12) {
|
|
return AM;
|
|
}
|
|
else {
|
|
return PM;
|
|
}
|
|
}
|
|
|
|
static uint8_t convert_12_hour_to_24_hour(uint8_t twelve_hour, char *meridiem)
|
|
{
|
|
uint8_t twenty_four_hour;
|
|
|
|
/* Default */
|
|
twenty_four_hour = twelve_hour;
|
|
|
|
/* Special cases */
|
|
if (strcmp(meridiem, AM) == 0) {
|
|
if (twelve_hour == 12) {
|
|
twenty_four_hour = 0;
|
|
}
|
|
}
|
|
else if (twelve_hour < 12) {
|
|
twenty_four_hour = twelve_hour + 12;
|
|
}
|
|
return twenty_four_hour;
|
|
}
|
|
|
|
void convert_24_hour_to_12_hour(uint8_t twenty_four_hour, uint8_t *twelve_hour, char const **meridiem)
|
|
{
|
|
if (twenty_four_hour == 0) {
|
|
*twelve_hour = 12;
|
|
}
|
|
else if (twenty_four_hour < 12) {
|
|
*meridiem = AM;
|
|
}
|
|
else if (twenty_four_hour == 12) {
|
|
*meridiem = PM;
|
|
}
|
|
else {
|
|
*twelve_hour = twenty_four_hour - 12;
|
|
*meridiem = PM;
|
|
}
|
|
}
|
|
|
|
void set_err_msg(char *what_failed, int err_code)
|
|
{
|
|
snprintf(G_err_msg, ERR_MSG_SIZE, "%s: %s", what_failed, strerror(err_code));
|
|
}
|
|
|
|
bool load_system_time(struct tm *t)
|
|
{
|
|
time_t now;
|
|
struct tm *now_breakdown;
|
|
bool success = false;
|
|
|
|
if (time(&now) != TIME_ERR_RESULT) {
|
|
if ((now_breakdown = localtime(&now)) != LOCALTIME_ERR_RESULT) {
|
|
copy_struct_tm(t, now_breakdown);
|
|
success = true;
|
|
}
|
|
else {
|
|
perror("Localtime failed");
|
|
}
|
|
}
|
|
else {
|
|
perror("Time function failed");
|
|
}
|
|
return success;
|
|
}
|
|
|
|
char *to_upper_case(char *s)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; s[i] != '\0'; ++i) {
|
|
s[i] = toupper(s[i]);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
void read_time_interactively(struct tm *t)
|
|
{
|
|
char line[4];
|
|
int8_t hour;
|
|
int8_t min;
|
|
|
|
printf("Hour:");
|
|
hour = atoi(fgets(line, sizeof(line), stdin));
|
|
printf("Minute:");
|
|
min = atoi(fgets(line, sizeof(line), stdin));
|
|
printf("AM or PM:");
|
|
fgets(line, sizeof(line), stdin);
|
|
|
|
t->tm_hour = convert_12_hour_to_24_hour(hour, line);
|
|
t->tm_min = min;
|
|
t->tm_sec = 0;
|
|
}
|
|
|
|
void print_12_hour_time(struct tm *t)
|
|
{
|
|
uint8_t hour;
|
|
const char *meridiem;
|
|
|
|
convert_24_hour_to_12_hour(t->tm_hour, &hour, &meridiem);
|
|
printf("%2hu:%02d:%02d %2s", hour, t->tm_min, t->tm_sec, meridiem);
|
|
}
|
|
|
|
void reprint_12_hour_time(struct tm *t)
|
|
{
|
|
printf("\b\b\b\b\b\b\b\b\b\b\b");
|
|
print_12_hour_time(t);
|
|
}
|
|
|