lsf-times.c revision 1.1 1 /* $NetBSD: lsf-times.c,v 1.1 2024/08/18 20:37:48 christos Exp $ */
2
3 #include "config.h"
4 #include "ntp_calendar.h"
5
6 #include <stdlib.h>
7 #include <errno.h>
8
9 #include "ntp_types.h"
10 #include "ntp_fp.h"
11 #include "vint64ops.h"
12
13 /*
14 * If we're called with 1 arg, it's a u_long timestamp.
15 * If we're called with 3 args, we're expecting YYYY MM DD,
16 * and MM must be 6 or 12, and DD must be 28,
17 * If we're called with 2 args, we're expecting YYYY MM, and
18 * MM mst be 6 or 12, and we assume DD is 28.
19 */
20
21 char *progname;
22 static const char *MONTHS[] =
23 { "January", "February", "March", "April", "May", "June",
24 "July", "August", "September", "October", "November",
25 "December" };
26
27 void usage(void);
28
29 void
30 usage(void)
31 {
32 printf("Usage:\n");
33 printf(" %s nnnnnn\n", progname);
34 printf(" %s YYYY [6|12]\n", progname);
35 printf(" %s YYYY [6|12] 28\n", progname);
36
37 return;
38 }
39
40
41 int
42 main(
43 int argc, /* command line options */
44 char **argv /* poiniter to list of tokens */
45 )
46 {
47 int err = 0;
48 vint64 expires;
49 unsigned int year = 0;
50 unsigned int mon = 0;
51 unsigned int dom = 0;
52 int scount;
53 char *ep;
54 struct calendar cal = {0};
55
56 progname = argv[0];
57
58 switch(argc) {
59 case 2: /* 1 arg, must be a string of digits */
60 expires = strtouv64(argv[1], &ep, 10);
61
62 if (0 == *ep) {
63 ntpcal_ntp64_to_date(&cal, &expires);
64
65 printf("%02u %s %04u %02u:%02u:%02u\n"
66 , cal.monthday
67 , MONTHS[cal.month - 1]
68 , cal.year
69 , cal.hour
70 , cal.minute
71 , cal.second
72 );
73
74 exit(0);
75 } else {
76 printf("1 arg, but not a string of digits: <%s>\n",
77 argv[1]);
78 err = 1;
79 }
80 break;
81 ;;
82 case 3: /* 2 args, must be YY MM, where MM is 6 or 12 */
83 dom = 28;
84 scount = sscanf(argv[1], "%u", &year);
85 if (1 == scount) {
86 // printf("2 args: year %u\n", year);
87 } else {
88 printf("2 args, but #1 is not a string of digits: <%s>\n", argv[1]);
89 err = 1;
90 }
91
92 scount = sscanf(argv[2], "%u", &mon);
93 if (1 == scount) {
94 if (6 == mon || 12 == mon) {
95 // printf("2 args: month %u\n", mon);
96 } else {
97 printf("2 arg, but #2 is not 6 or 12: <%d>\n", mon);
98 err = 1;
99 }
100 } else {
101 printf("2 arg, but #2 is not a string of digits: <%s>\n", argv[2]);
102 err = 1;
103 }
104
105 break;
106 ;;
107 case 4: /* 3 args, YY MM DD, where MM is 6 or 12, DD is 28 */
108 scount = sscanf(argv[1], "%u", &year);
109 if (1 == scount) {
110 // printf("3 args: year %u\n", year);
111 } else {
112 printf("3 args, but #1 is not a string of digits: <%s>\n", argv[1]);
113 err = 1;
114 }
115
116 scount = sscanf(argv[2], "%u", &mon);
117 if (1 == scount) {
118 if (6 == mon || 12 == mon) {
119 // printf("3 args: month %u\n", mon);
120 } else {
121 printf("3 arg, but #2 is not 6 or 12: <%d>\n", mon);
122 err = 1;
123 }
124 } else {
125 printf("3 arg, but #2 is not a string of digits: <%s>\n", argv[2]);
126 err = 1;
127 }
128
129 scount = sscanf(argv[3], "%u", &dom);
130 if (1 == scount) {
131 if (28 == dom) {
132 // printf("3 args: dom %u\n", dom);
133 } else {
134 printf("3 arg, but #3 is not 28: <%d>\n", dom);
135 err = 1;
136 }
137 } else {
138 printf("3 arg, but #3 is not a string of digits: <%s>\n", argv[2]);
139 err = 1;
140 }
141
142 break;
143 ;;
144 default:
145 err = 1;
146 break;
147 ;;
148 }
149
150 if (err) {
151 usage();
152 exit(err);
153 }
154
155 cal.year = year;
156 cal.month = mon;
157 cal.monthday = dom;
158 cal.hour = 0;
159 cal.minute = 0;
160 cal.second = 0;
161
162 printf("%u ", ntpcal_date_to_ntp(&cal));
163
164 printf("%02d %s %04d "
165 , cal.monthday
166 , MONTHS[cal.month - 1]
167 , cal.year
168 );
169 printf("\n");
170
171 exit(err);
172 }
173
174 #if 0
175
176
177 void
178 test_DateGivenMonthDay(void) {
179 // 2010-06-24 12:50:00
180 struct calendar input = {2010, 0, 6, 24, 12, 50, 0};
181
182 u_long expected = 3486372600UL; // This is the timestamp above.
183
184 TEST_ASSERT_EQUAL_UINT(expected, caltontp(&input));
185 }
186
187 void
188 test_DateGivenYearDay(void) {
189 // 2010-06-24 12:50:00
190 // This is the 175th day of 2010.
191 struct calendar input = {2010, 175, 0, 0, 12, 50, 0};
192
193 u_long expected = 3486372600UL; // This is the timestamp above.
194
195 TEST_ASSERT_EQUAL_UINT(expected, caltontp(&input));
196 }
197
198 void
199 test_DateLeapYear(void) {
200 // 2012-06-24 12:00:00
201 // This is the 176th day of 2012 (since 2012 is a leap year).
202 struct calendar inputYd = {2012, 176, 0, 0, 12, 00, 00};
203 struct calendar inputMd = {2012, 0, 6, 24, 12, 00, 00};
204
205 u_long expected = 3549528000UL;
206
207 TEST_ASSERT_EQUAL_UINT(expected, caltontp(&inputYd));
208 TEST_ASSERT_EQUAL_UINT(expected, caltontp(&inputMd));
209 }
210
211 void
212 test_WraparoundDateIn2036(void) {
213 // 2036-02-07 06:28:16
214 // This is (one) wrapping boundary where we go from ULONG_MAX to 0.
215 struct calendar input = {2036, 0, 2, 7, 6, 28, 16};
216
217 u_long expected = 0UL;
218
219 TEST_ASSERT_EQUAL_UINT(expected, caltontp(&input));
220 }
221
222 #endif
223