-
Notifications
You must be signed in to change notification settings - Fork 1
/
fuzzyclock.c
141 lines (123 loc) · 2.34 KB
/
fuzzyclock.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* See LICENSE file for license details. */
#include "fuzzyclock.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ARR_LEN(var) (sizeof(var)/sizeof((var)[0]))
typedef enum {
FULL_PAST = 0,
QUARTER_PAST,
HALF,
QUARTER_BEFORE,
FULL
} clock_state_t;
typedef struct {
int hour;
int minute;
} fuzzy_clock_t;
static inline int
clock_increment_hour(int hour)
{
if (hour >= 23) return 0;
else return ++hour;
}
static char *
clock_get_hour_name(int hour)
{
char *hournames[] = {
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve"
};
if (hour == 0) {
return strdup(hournames[11]);
}
else if (hour > 0 && hour <= 12) {
return strdup(hournames[hour-1]);
}
else if (hour > 12 && hour <= 23) {
return strdup(hournames[hour-13]);
}
else {
return NULL;
}
}
static clock_state_t
clock_get_state(fuzzy_clock_t *clock)
{
int minute = clock->minute;
if (minute >= 0 && minute < 7) {
return FULL_PAST;
}
else if (minute >= 7 && minute <= 23) {
return QUARTER_PAST;
}
else if (minute > 23 && minute <= 38) {
return HALF;
}
else if (minute > 38 && minute <= 53) {
return QUARTER_BEFORE;
}
else {
return FULL;
}
}
static char *
clock_get_fuzzy_hour(fuzzy_clock_t *clock)
{
clock_state_t state = clock_get_state(clock);
if (state >= QUARTER_BEFORE) {
return clock_get_hour_name(clock_increment_hour(clock->hour));
}
else {
return clock_get_hour_name(clock->hour);
}
}
char *
fuzzytime(struct tm *tm)
{
struct tm *timeinfo;
clock_state_t state;
char timestring[64];
char *fuzzyhour;
if (tm == NULL) {
time_t rawtime;
time(&rawtime);
timeinfo = localtime(&rawtime);
}
else {
timeinfo = tm;
}
fuzzy_clock_t clock = {
.hour = timeinfo->tm_hour,
.minute = timeinfo->tm_min
};
state = clock_get_state(&clock);
fuzzyhour = clock_get_fuzzy_hour(&clock);
switch(state) {
case QUARTER_PAST:
snprintf(timestring, ARR_LEN(timestring), "quarter past %s", fuzzyhour);
break;
case HALF:
snprintf(timestring, ARR_LEN(timestring), "half past %s", fuzzyhour);
break;
case QUARTER_BEFORE:
snprintf(timestring, ARR_LEN(timestring), "quarter before %s", fuzzyhour);
break;
case FULL_PAST:
case FULL:
snprintf(timestring, ARR_LEN(timestring), "%s o'clock", fuzzyhour);
break;
}
free(fuzzyhour);
return strdup(timestring);
}