tst-strptime.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* Test for strptime.
  2. Copyright (C) 1998-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <locale.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <time.h>
  20. static const struct
  21. {
  22. const char *locale;
  23. const char *input;
  24. const char *format;
  25. int wday;
  26. int yday;
  27. int mon;
  28. int mday;
  29. } day_tests[] =
  30. {
  31. { "C", "2000-01-01", "%Y-%m-%d", 6, 0, 0, 1 },
  32. { "C", "03/03/00", "%D", 5, 62, 2, 3 },
  33. { "C", "9/9/99", "%x", 4, 251, 8, 9 },
  34. { "C", "19990502123412", "%Y%m%d%H%M%S", 0, 121, 4, 2 },
  35. { "C", "2001 20 Mon", "%Y %U %a", 1, 140, 4, 21 },
  36. { "C", "2001 21 Mon", "%Y %W %a", 1, 140, 4, 21 },
  37. { "C", "2001 21 Mon", "%2000Y %W %a", 1, 140, 4, 21 },
  38. { "C", "2001 21 Mon", "%^Y %W %a", 1, 140, 4, 21 },
  39. { "C", "2001 EST 21 Mon", "%Y %Z %W %a", 1, 140, 4, 21 },
  40. { "C", "2012 00 Sun", "%Y %W %a", 0, 0, 0, 1 },
  41. { "ja_JP.EUC-JP", "2000-01-01 08:12:21 AM", "%Y-%m-%d %I:%M:%S %p",
  42. 6, 0, 0, 1 },
  43. { "en_US.ISO-8859-1", "2000-01-01 08:12:21 PM", "%Y-%m-%d %I:%M:%S %p",
  44. 6, 0, 0, 1 },
  45. { "ja_JP.EUC-JP", "2001 20 \xb7\xee", "%Y %U %a", 1, 140, 4, 21 },
  46. { "ja_JP.EUC-JP", "2001 21 \xb7\xee", "%Y %W %a", 1, 140, 4, 21 },
  47. /* Most of the languages do not need the declension of the month names
  48. and do not distinguish between %B and %OB. */
  49. { "en_US.ISO-8859-1", "November 17, 2017", "%B %e, %Y", 5, 320, 10, 17 },
  50. { "de_DE.ISO-8859-1", "18. Nov 2017", "%d. %b %Y", 6, 321, 10, 18 },
  51. { "fr_FR.UTF-8", "19 novembre 2017", "%d %OB %Y", 0, 322, 10, 19 },
  52. { "es_ES.UTF-8", "20 de nov de 2017", "%d de %Ob de %Y", 1, 323, 10, 20 },
  53. /* Some languages do need the declension of the month names. */
  54. { "pl_PL.UTF-8", "21 lis 2017", "%d %b %Y", 2, 324, 10, 21 },
  55. { "pl_PL.UTF-8", "22 LIS 2017", "%d %B %Y", 3, 325, 10, 22 },
  56. { "pl_PL.UTF-8", "23 listopada 2017", "%d %B %Y", 4, 326, 10, 23 },
  57. /* The nominative case is incorrect here but it is parseable. */
  58. { "pl_PL.UTF-8", "24 listopad 2017", "%d %OB %Y", 5, 327, 10, 24 },
  59. { "pl_PL.UTF-8", "25 lis 2017", "%d %Ob %Y", 6, 328, 10, 25 },
  60. /* ноя - pronounce: 'noya' - "Nov" (abbreviated "November") in Russian. */
  61. { "ru_RU.UTF-8", "26 ноя 2017", "%d %b %Y", 0, 329, 10, 26 },
  62. /* мая - pronounce: 'maya' - "of May" (the genitive case, both full and
  63. abbreviated) in Russian. */
  64. { "ru_RU.UTF-8", "19 мая 2018", "%d %b %Y", 6, 138, 4, 19 },
  65. /* май - pronounce: 'may' - "May" (the nominative case, both full and
  66. abbreviated) in Russian.
  67. The nominative case is incorrect here but it is parseable. */
  68. { "ru_RU.UTF-8", "20 май 2018", "%d %Ob %Y", 0, 139, 4, 20 },
  69. };
  70. static const struct
  71. {
  72. const char *input;
  73. const char *format;
  74. const char *output;
  75. int wday;
  76. int yday;
  77. } tm_tests [] =
  78. {
  79. {"17410105012000", "%H%M%S%d%m%Y", "2000-01-05 17:41:01", 3, 4}
  80. };
  81. static int
  82. test_tm (void)
  83. {
  84. struct tm tm;
  85. size_t i;
  86. int result = 0;
  87. char buf[100];
  88. for (i = 0; i < sizeof (tm_tests) / sizeof (tm_tests[0]); ++i)
  89. {
  90. memset (&tm, '\0', sizeof (tm));
  91. char *ret = strptime (tm_tests[i].input, tm_tests[i].format, &tm);
  92. if (ret == NULL)
  93. {
  94. printf ("strptime returned NULL for `%s'\n", tm_tests[i].input);
  95. result = 1;
  96. continue;
  97. }
  98. else if (*ret != '\0')
  99. {
  100. printf ("not all of `%s' read\n", tm_tests[i].input);
  101. result = 1;
  102. }
  103. strftime (buf, sizeof (buf), "%F %T", &tm);
  104. printf ("strptime (\"%s\", \"%s\", ...)\n"
  105. "\tshould be: %s, wday = %d, yday = %3d\n"
  106. "\t is: %s, wday = %d, yday = %3d\n",
  107. tm_tests[i].input, tm_tests[i].format,
  108. tm_tests[i].output,
  109. tm_tests[i].wday, tm_tests[i].yday,
  110. buf, tm.tm_wday, tm.tm_yday);
  111. if (strcmp (buf, tm_tests[i].output) != 0)
  112. {
  113. printf ("Time and date are not correct.\n");
  114. result = 1;
  115. }
  116. if (tm.tm_wday != tm_tests[i].wday)
  117. {
  118. printf ("weekday for `%s' incorrect: %d instead of %d\n",
  119. tm_tests[i].input, tm.tm_wday, tm_tests[i].wday);
  120. result = 1;
  121. }
  122. if (tm.tm_yday != tm_tests[i].yday)
  123. {
  124. printf ("yearday for `%s' incorrect: %d instead of %d\n",
  125. tm_tests[i].input, tm.tm_yday, tm_tests[i].yday);
  126. result = 1;
  127. }
  128. }
  129. return result;
  130. }
  131. static int
  132. do_test (void)
  133. {
  134. struct tm tm;
  135. size_t i;
  136. int result = 0;
  137. for (i = 0; i < sizeof (day_tests) / sizeof (day_tests[0]); ++i)
  138. {
  139. memset (&tm, '\0', sizeof (tm));
  140. if (setlocale (LC_ALL, day_tests[i].locale) == NULL)
  141. {
  142. printf ("cannot set locale %s: %m\n", day_tests[i].locale);
  143. exit (EXIT_FAILURE);
  144. }
  145. char *ret = strptime (day_tests[i].input, day_tests[i].format, &tm);
  146. if (ret == NULL)
  147. {
  148. printf ("strptime returned NULL for `%s'\n", day_tests[i].input);
  149. result = 1;
  150. continue;
  151. }
  152. else if (*ret != '\0')
  153. {
  154. printf ("not all of `%s' read\n", day_tests[i].input);
  155. result = 1;
  156. }
  157. printf ("strptime (\"%s\", \"%s\", ...)\n"
  158. "\tshould be: wday = %d, yday = %3d, mon = %2d, mday = %2d\n"
  159. "\t is: wday = %d, yday = %3d, mon = %2d, mday = %2d\n",
  160. day_tests[i].input, day_tests[i].format,
  161. day_tests[i].wday, day_tests[i].yday,
  162. day_tests[i].mon, day_tests[i].mday,
  163. tm.tm_wday, tm.tm_yday, tm.tm_mon, tm.tm_mday);
  164. if (tm.tm_wday != day_tests[i].wday)
  165. {
  166. printf ("weekday for `%s' incorrect: %d instead of %d\n",
  167. day_tests[i].input, tm.tm_wday, day_tests[i].wday);
  168. result = 1;
  169. }
  170. if (tm.tm_yday != day_tests[i].yday)
  171. {
  172. printf ("yearday for `%s' incorrect: %d instead of %d\n",
  173. day_tests[i].input, tm.tm_yday, day_tests[i].yday);
  174. result = 1;
  175. }
  176. if (tm.tm_mon != day_tests[i].mon)
  177. {
  178. printf ("month for `%s' incorrect: %d instead of %d\n",
  179. day_tests[i].input, tm.tm_mon, day_tests[i].mon);
  180. result = 1;
  181. }
  182. if (tm.tm_mday != day_tests[i].mday)
  183. {
  184. printf ("monthday for `%s' incorrect: %d instead of %d\n",
  185. day_tests[i].input, tm.tm_mday, day_tests[i].mday);
  186. result = 1;
  187. }
  188. }
  189. setlocale (LC_ALL, "C");
  190. result |= test_tm ();
  191. return result;
  192. }
  193. #define TEST_FUNCTION do_test ()
  194. #include "../test-skeleton.c"