Line data Source code
1 : /*
2 : * Test conversions to date and CS_DT_CONVFMT
3 : */
4 : #include "common.h"
5 :
6 : #include <freetds/replacements.h>
7 :
8 : static CS_CONTEXT *ctx;
9 : static bool failed = false;
10 : static const char *test_name = NULL;
11 :
12 : typedef struct
13 : {
14 : CS_INT convfmt;
15 : const char *convfmt_name;
16 : const char *datetime;
17 : const char *date;
18 : const char *time;
19 : } TEST;
20 :
21 : #define ONE(convfmt, datetime, date, time) \
22 : { convfmt, #convfmt, datetime, date, time }
23 : static const TEST tests[] = {
24 : ONE(CS_DATES_SHORT, "Sep 7 2025 4:32PM", "Sep 7 2025", " 4:32PM"),
25 : ONE(CS_DATES_MDY1, "09/07/25", "09/07/25", ""),
26 : ONE(CS_DATES_YMD1, "25.09.07", "25.09.07", ""),
27 : ONE(CS_DATES_DMY1, "07/09/25", "07/09/25", ""),
28 : ONE(CS_DATES_DMY2, "07.09.25", "07.09.25", ""),
29 : ONE(CS_DATES_DMY3, "07-09-25", "07-09-25", ""),
30 : ONE(CS_DATES_DMY4, "07 Sep 25", "07 Sep 25", ""),
31 : ONE(CS_DATES_MDY2, "Sep 07, 25", "Sep 07, 25", ""),
32 : ONE(CS_DATES_HMS, "16:32:53", "00:00:00", "16:32:53"),
33 : ONE(CS_DATES_LONG, "Sep 7 2025 4:32:53:490PM", "Sep 7 2025", " 4:32:53:490PM"),
34 : ONE(CS_DATES_MDY3, "09-07-25", "09-07-25", ""),
35 : ONE(CS_DATES_YMD2, "25/09/07", "25/09/07", ""),
36 : ONE(CS_DATES_YMD3, "250907", "250907", ""),
37 : ONE(CS_DATES_YDM1, "25/07/09", "25/07/09", ""),
38 : ONE(CS_DATES_MYD1, "09/25/07", "09/25/07", ""),
39 : ONE(CS_DATES_DYM1, "07/25/09", "07/25/09", ""),
40 : ONE(CS_DATES_MDYHMS, "Sep 7 2025 16:32:53", "Sep 7 2025 00:00:00", "Jan 1 1900 16:32:53"),
41 : ONE(CS_DATES_HMA, " 4:32PM", "12:00AM", " 4:32PM"),
42 : ONE(CS_DATES_HM, "16:32", "00:00", "16:32"),
43 : ONE(CS_DATES_HMSZA, " 4:32:53:490PM", "12:00:00:000AM", " 4:32:53:490PM"),
44 : ONE(CS_DATES_HMSZ, "16:32:53:490", "00:00:00:000", "16:32:53:490"),
45 : ONE(CS_DATES_YMDHMS, "25/09/07 16:32:53", "25/09/07 00:00:00", "00/01/01 16:32:53"),
46 : ONE(CS_DATES_YMDHMA, "25/09/07 4:32PM", "25/09/07 12:00AM", "00/01/01 4:32PM"),
47 : ONE(CS_DATES_YMDTHMS, "2025-09-07T16:32:53", "2025-09-07T00:00:00", "1900-01-01T16:32:53"),
48 : ONE(CS_DATES_HMSUSA, " 4:32:53.490000PM", "12:00:00.000000AM", " 4:32:53.490000PM"),
49 : ONE(CS_DATES_HMSUS, "16:32:53.490000", "00:00:00.000000", "16:32:53.490000"),
50 : ONE(CS_DATES_LONGUSA, "Sep 7 25 4:32:53.490000PM", "Sep 7 25 12:00:00.000000AM", "Jan 1 00 4:32:53.490000PM"),
51 : ONE(CS_DATES_LONGUS, "Sep 7 25 16:32:53.490000", "Sep 7 25 00:00:00.000000", "Jan 1 00 16:32:53.490000"),
52 : ONE(CS_DATES_YMDHMSUS, "25-09-07 16:32:53.490000", "25-09-07 00:00:00.000000", "00-01-01 16:32:53.490000"),
53 : ONE(CS_DATES_SHORT_ALT, "Sep 7 2025 4:32PM", "Sep 7 2025 12:00AM", "Jan 1 1900 4:32PM"),
54 : ONE(CS_DATES_MDY1_YYYY, "09/07/2025", "09/07/2025", ""),
55 : ONE(CS_DATES_YMD1_YYYY, "2025.09.07", "2025.09.07", ""),
56 : ONE(CS_DATES_DMY1_YYYY, "07/09/2025", "07/09/2025", ""),
57 : ONE(CS_DATES_DMY2_YYYY, "07.09.2025", "07.09.2025", ""),
58 : ONE(CS_DATES_DMY3_YYYY, "07-09-2025", "07-09-2025", ""),
59 : ONE(CS_DATES_DMY4_YYYY, "07 Sep 2025", "07 Sep 2025", ""),
60 : ONE(CS_DATES_MDY2_YYYY, "Sep 07, 2025", "Sep 07, 2025", ""),
61 : ONE(CS_DATES_HMS_ALT, "16:32:53", "00:00:00", "16:32:53"),
62 : ONE(CS_DATES_LONG_ALT, "Sep 7 2025 4:32:53:490PM", "Sep 7 2025 12:00:00:000AM", "Jan 1 1900 4:32:53:490PM"),
63 : ONE(CS_DATES_MDY3_YYYY, "09-07-2025", "09-07-2025", ""),
64 : ONE(CS_DATES_YMD2_YYYY, "2025/09/07", "2025/09/07", ""),
65 : ONE(CS_DATES_YMD3_YYYY, "20250907", "20250907", ""),
66 : ONE(CS_DATES_YDM1_YYYY, "2025/07/09", "2025/07/09", ""),
67 : ONE(CS_DATES_MYD1_YYYY, "09/2025/07", "09/2025/07", ""),
68 : ONE(CS_DATES_DYM1_YYYY, "07/2025/09", "07/2025/09", ""),
69 : ONE(CS_DATES_MDYHMS_ALT, "Sep 7 2025 16:32:53", "Sep 7 2025 00:00:00", "Jan 1 1900 16:32:53"),
70 : ONE(CS_DATES_HMA_ALT, " 4:32PM", "12:00AM", " 4:32PM"),
71 : ONE(CS_DATES_HM_ALT, "16:32", "00:00", "16:32"),
72 : ONE(CS_DATES_YMDHMS_YYYY, "2025/09/07 16:32:53", "2025/09/07 00:00:00", "1900/01/01 16:32:53"),
73 : ONE(CS_DATES_YMDHMA_YYYY, "2025/09/07 4:32PM", "2025/09/07 12:00AM", "1900/01/01 4:32PM"),
74 : ONE(CS_DATES_HMSUSA_YYYY, " 4:32:53.490000PM", "12:00:00.000000AM", " 4:32:53.490000PM"),
75 : ONE(CS_DATES_HMSUS_YYYY, "16:32:53.490000", "00:00:00.000000", "16:32:53.490000"),
76 : ONE(CS_DATES_LONGUSA_YYYY, "Sep 7 2025 4:32:53.490000PM", "Sep 7 2025 12:00:00.000000AM",
77 : "Jan 1 1900 4:32:53.490000PM"),
78 : ONE(CS_DATES_LONGUS_YYYY, "Sep 7 2025 16:32:53.490000", "Sep 7 2025 00:00:00.000000", "Jan 1 1900 16:32:53.490000"),
79 : ONE(CS_DATES_YMDHMSUS_YYYY, "2025-09-07 16:32:53.490000", "2025-09-07 00:00:00.000000", "1900-01-01 16:32:53.490000"),
80 : {0, NULL, NULL, NULL, NULL}
81 : };
82 :
83 : static void
84 1650 : single_value(CS_INT type, void *input, size_t input_size, const char *expected)
85 : {
86 : CS_DATAFMT destfmt, srcfmt;
87 : CS_INT reslen;
88 : char buffer[1024];
89 :
90 1650 : memset(&destfmt, 0, sizeof(destfmt));
91 : destfmt.datatype = CS_CHAR_TYPE;
92 1650 : destfmt.maxlength = sizeof(buffer);
93 : destfmt.format = CS_FMT_UNUSED;
94 :
95 1650 : memset(&srcfmt, 0, sizeof(srcfmt));
96 1650 : srcfmt.datatype = type;
97 1650 : srcfmt.maxlength = (CS_INT) input_size;
98 :
99 : /*
100 : * FIXME this fix some thing but if error cs_convert should return
101 : * CS_UNUSED; note that this is defined 5.. a valid result ...
102 : */
103 1650 : reslen = 0;
104 :
105 : /* do convert */
106 1650 : memset(buffer, 23, sizeof(buffer));
107 1650 : check_call(cs_convert, (ctx, &srcfmt, input, &destfmt, buffer, &reslen));
108 :
109 1650 : assert(reslen >= 0 && reslen < sizeof(buffer));
110 1650 : buffer[reslen] = 0;
111 :
112 1650 : if (strcmp(buffer, expected) != 0) {
113 0 : fprintf(stderr, "Wrong result test %s type %d:\ngot %s\nexp %s\n", test_name, type, buffer, expected);
114 0 : failed = true;
115 : }
116 1650 : }
117 :
118 : static void
119 550 : single_test(const TEST *test)
120 : {
121 : /* 2025-09-07 16:32:53.490000
122 : * This date was chosen for different reasons:
123 : * - all components are different;
124 : * - all components are not zero;
125 : * - month and day are different so we can distinguish the order;
126 : * - month and day are one digit so we can distinguish padding.
127 : */
128 550 : CS_DATETIME date = { 45905, ((16 * 60 + 32) * 60 + 53) * 300 + 147 };
129 : CS_INT i_value;
130 :
131 550 : test_name = test->convfmt_name;
132 :
133 550 : i_value = test->convfmt;
134 550 : check_call(cs_dt_info, (ctx, CS_SET, NULL, CS_DT_CONVFMT, CS_UNUSED, &i_value, sizeof(i_value), NULL));
135 :
136 550 : single_value(CS_DATETIME_TYPE, &date, sizeof(date), test->datetime);
137 550 : single_value(CS_DATE_TYPE, &date.dtdays, sizeof(date.dtdays), test->date);
138 550 : single_value(CS_TIME_TYPE, &date.dttime, sizeof(date.dttime), test->time);
139 550 : }
140 :
141 10 : TEST_MAIN()
142 : {
143 10 : int verbose = 1;
144 : const TEST *test;
145 :
146 : /* Force default us_enlish */
147 10 : unsetenv("LC_ALL");
148 10 : setenv("LANG", "C", 1);
149 :
150 10 : printf("%s: Testing date conversions\n", __FILE__);
151 :
152 10 : check_call(cs_ctx_alloc, (CS_VERSION_100, &ctx));
153 :
154 560 : for (test = tests; test->convfmt_name != NULL; ++test)
155 550 : single_test(test);
156 :
157 10 : check_call(cs_ctx_drop, (ctx));
158 :
159 10 : if (verbose && !failed)
160 10 : printf("Test succeded\n");
161 :
162 10 : return failed ? 1 : 0;
163 : }
|