backout 29799f914cab, Bug 917642 - [Helix] Please update the helix blobs
[gecko.git] / nsprpub / pr / tests / timetest.c
blobc9bdf9c27adf3bf101799ca3963fb4059b507446
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /*
7 * file: timetest.c
8 * description: test time and date routines
9 */
10 /***********************************************************************
11 ** Includes
12 ***********************************************************************/
13 /* Used to get the command line option */
14 #include "plgetopt.h"
16 #include "prinit.h"
17 #include "prtime.h"
18 #include "prprf.h"
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
24 int failed_already=0;
25 PRBool debug_mode = PR_FALSE;
27 static char *dayOfWeek[] =
28 { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "???" };
29 static char *month[] =
30 { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
31 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "???" };
33 static void PrintExplodedTime(const PRExplodedTime *et) {
34 PRInt32 totalOffset;
35 PRInt32 hourOffset, minOffset;
36 const char *sign;
38 /* Print day of the week, month, day, hour, minute, and second */
39 if (debug_mode) printf("%s %s %ld %02ld:%02ld:%02ld ",
40 dayOfWeek[et->tm_wday], month[et->tm_month], et->tm_mday,
41 et->tm_hour, et->tm_min, et->tm_sec);
43 /* Print time zone */
44 totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
45 if (totalOffset == 0) {
46 if (debug_mode) printf("UTC ");
47 } else {
48 sign = "+";
49 if (totalOffset < 0) {
50 totalOffset = -totalOffset;
51 sign = "-";
53 hourOffset = totalOffset / 3600;
54 minOffset = (totalOffset % 3600) / 60;
55 if (debug_mode)
56 printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
59 /* Print year */
60 if (debug_mode) printf("%hd", et->tm_year);
63 static int ExplodedTimeIsEqual(const PRExplodedTime *et1,
64 const PRExplodedTime *et2)
66 if (et1->tm_usec == et2->tm_usec &&
67 et1->tm_sec == et2->tm_sec &&
68 et1->tm_min == et2->tm_min &&
69 et1->tm_hour == et2->tm_hour &&
70 et1->tm_mday == et2->tm_mday &&
71 et1->tm_month == et2->tm_month &&
72 et1->tm_year == et2->tm_year &&
73 et1->tm_wday == et2->tm_wday &&
74 et1->tm_yday == et2->tm_yday &&
75 et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset &&
76 et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) {
77 return 1;
78 } else {
79 return 0;
83 static void
84 testParseTimeString(PRTime t)
86 PRExplodedTime et;
87 PRTime t2;
88 char timeString[128];
89 char buf[128];
90 PRInt32 totalOffset;
91 PRInt32 hourOffset, minOffset;
92 const char *sign;
93 PRInt64 usec_per_sec;
95 /* Truncate the microsecond part of PRTime */
96 LL_I2L(usec_per_sec, PR_USEC_PER_SEC);
97 LL_DIV(t, t, usec_per_sec);
98 LL_MUL(t, t, usec_per_sec);
100 PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
102 /* Print day of the week, month, day, hour, minute, and second */
103 PR_snprintf(timeString, 128, "%s %s %ld %02ld:%02ld:%02ld ",
104 dayOfWeek[et.tm_wday], month[et.tm_month], et.tm_mday,
105 et.tm_hour, et.tm_min, et.tm_sec);
106 /* Print time zone */
107 totalOffset = et.tm_params.tp_gmt_offset + et.tm_params.tp_dst_offset;
108 if (totalOffset == 0) {
109 strcat(timeString, "GMT "); /* I wanted to use "UTC" here, but
110 * PR_ParseTimeString doesn't
111 * understand "UTC". */
112 } else {
113 sign = "+";
114 if (totalOffset < 0) {
115 totalOffset = -totalOffset;
116 sign = "-";
118 hourOffset = totalOffset / 3600;
119 minOffset = (totalOffset % 3600) / 60;
120 PR_snprintf(buf, 128, "%s%02ld%02ld ", sign, hourOffset, minOffset);
121 strcat(timeString, buf);
123 /* Print year */
124 PR_snprintf(buf, 128, "%hd", et.tm_year);
125 strcat(timeString, buf);
127 if (PR_ParseTimeString(timeString, PR_FALSE, &t2) == PR_FAILURE) {
128 fprintf(stderr, "PR_ParseTimeString() failed\n");
129 exit(1);
131 if (LL_NE(t, t2)) {
132 fprintf(stderr, "PR_ParseTimeString() incorrect\n");
133 PR_snprintf(buf, 128, "t is %lld, t2 is %lld, time string is %s\n",
134 t, t2, timeString);
135 fprintf(stderr, "%s\n", buf);
136 exit(1);
140 int main(int argc, char** argv)
142 /* The command line argument: -d is used to determine if the test is being run
143 in debug mode. The regress tool requires only one line output:PASS or FAIL.
144 All of the printfs associated with this test has been handled with a if (debug_mode)
145 test.
146 Usage: test_name -d
148 PLOptStatus os;
149 PLOptState *opt;
151 PR_STDIO_INIT();
152 opt = PL_CreateOptState(argc, argv, "d");
153 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
155 if (PL_OPT_BAD == os) continue;
156 switch (opt->option)
158 case 'd': /* debug mode */
159 debug_mode = PR_TRUE;
160 break;
161 default:
162 break;
165 PL_DestroyOptState(opt);
167 /* main test */
169 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
171 /* Testing zero PRTime (the epoch) */
173 PRTime t;
174 PRExplodedTime et;
176 LL_I2L(t, 0);
177 if (debug_mode) printf("The NSPR epoch is:\n");
178 PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
179 PrintExplodedTime(&et);
180 if (debug_mode) printf("\n");
181 PR_ExplodeTime(t, PR_GMTParameters, &et);
182 PrintExplodedTime(&et);
183 if (debug_mode) printf("\n\n");
184 testParseTimeString(t);
188 *************************************************************
190 ** Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime
191 ** on the current time
193 *************************************************************
197 PRTime t1, t2;
198 PRExplodedTime et;
200 if (debug_mode) {
201 printf("*********************************************\n");
202 printf("** **\n");
203 printf("** Testing PR_Now(), PR_ExplodeTime, and **\n");
204 printf("** PR_ImplodeTime on the current time **\n");
205 printf("** **\n");
206 printf("*********************************************\n\n");
208 t1 = PR_Now();
210 /* First try converting to UTC */
212 PR_ExplodeTime(t1, PR_GMTParameters, &et);
213 if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) {
214 if (debug_mode) printf("ERROR: UTC has nonzero gmt or dst offset.\n");
215 else failed_already=1;
216 return 1;
218 if (debug_mode) printf("Current UTC is ");
219 PrintExplodedTime(&et);
220 if (debug_mode) printf("\n");
222 t2 = PR_ImplodeTime(&et);
223 if (LL_NE(t1, t2)) {
224 if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
225 else printf("FAIL\n");
226 return 1;
229 /* Next, try converting to local (US Pacific) time */
231 PR_ExplodeTime(t1, PR_LocalTimeParameters, &et);
232 if (debug_mode) printf("Current local time is ");
233 PrintExplodedTime(&et);
234 if (debug_mode) printf("\n");
235 if (debug_mode) printf("GMT offset is %ld, DST offset is %ld\n",
236 et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset);
237 t2 = PR_ImplodeTime(&et);
238 if (LL_NE(t1, t2)) {
239 if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
240 return 1;
243 if (debug_mode) printf("Please examine the results\n");
244 testParseTimeString(t1);
249 *******************************************
251 ** Testing PR_NormalizeTime()
253 *******************************************
256 /* July 4, 2001 is Wednesday */
258 PRExplodedTime et;
260 if (debug_mode) {
261 printf("\n");
262 printf("**********************************\n");
263 printf("** **\n");
264 printf("** Testing PR_NormalizeTime() **\n");
265 printf("** **\n");
266 printf("**********************************\n\n");
268 et.tm_year = 2001;
269 et.tm_month = 7 - 1;
270 et.tm_mday = 4;
271 et.tm_hour = 0;
272 et.tm_min = 0;
273 et.tm_sec = 0;
274 et.tm_usec = 0;
275 et.tm_params = PR_GMTParameters(&et);
277 PR_NormalizeTime(&et, PR_GMTParameters);
279 if (debug_mode) printf("July 4, 2001 is %s.\n", dayOfWeek[et.tm_wday]);
280 if (et.tm_wday == 3) {
281 if (debug_mode) printf("PASS\n");
282 } else {
283 if (debug_mode) printf("ERROR: It should be Wednesday\n");
284 else failed_already=1;
285 return 1;
287 testParseTimeString(PR_ImplodeTime(&et));
289 /* June 12, 1997 23:00 PST == June 13, 1997 00:00 PDT */
290 et.tm_year = 1997;
291 et.tm_month = 6 - 1;
292 et.tm_mday = 12;
293 et.tm_hour = 23;
294 et.tm_min = 0;
295 et.tm_sec = 0;
296 et.tm_usec = 0;
297 et.tm_params.tp_gmt_offset = -8 * 3600;
298 et.tm_params.tp_dst_offset = 0;
300 PR_NormalizeTime(&et, PR_USPacificTimeParameters);
302 if (debug_mode) {
303 printf("Thu Jun 12, 1997 23:00:00 PST is ");
305 PrintExplodedTime(&et);
306 if (debug_mode) printf(".\n");
307 if (et.tm_wday == 5) {
308 if (debug_mode) printf("PASS\n");
309 } else {
310 if (debug_mode) printf("ERROR: It should be Friday\n");
311 else failed_already=1;
312 return 1;
314 testParseTimeString(PR_ImplodeTime(&et));
316 /* Feb 14, 1997 00:00:00 PDT == Feb 13, 1997 23:00:00 PST */
317 et.tm_year = 1997;
318 et.tm_month = 2 - 1;
319 et.tm_mday = 14;
320 et.tm_hour = 0;
321 et.tm_min = 0;
322 et.tm_sec = 0;
323 et.tm_usec = 0;
324 et.tm_params.tp_gmt_offset = -8 * 3600;
325 et.tm_params.tp_dst_offset = 3600;
327 PR_NormalizeTime(&et, PR_USPacificTimeParameters);
329 if (debug_mode) {
330 printf("Fri Feb 14, 1997 00:00:00 PDT is ");
332 PrintExplodedTime(&et);
333 if (debug_mode) printf(".\n");
334 if (et.tm_wday == 4) {
335 if (debug_mode) printf("PASS\n");
336 } else {
337 if (debug_mode) printf("ERROR: It should be Thursday\n");
338 else failed_already=1;
339 return 1;
341 testParseTimeString(PR_ImplodeTime(&et));
343 /* What time is Nov. 7, 1996, 18:29:23 PDT? */
344 et.tm_year = 1996;
345 et.tm_month = 11 - 1;
346 et.tm_mday = 7;
347 et.tm_hour = 18;
348 et.tm_min = 29;
349 et.tm_sec = 23;
350 et.tm_usec = 0;
351 et.tm_params.tp_gmt_offset = -8 * 3600; /* PDT */
352 et.tm_params.tp_dst_offset = 3600;
354 PR_NormalizeTime(&et, PR_LocalTimeParameters);
355 if (debug_mode) printf("Nov 7 18:29:23 PDT 1996 is ");
356 PrintExplodedTime(&et);
357 if (debug_mode) printf(".\n");
358 testParseTimeString(PR_ImplodeTime(&et));
360 /* What time is Oct. 7, 1995, 18:29:23 PST? */
361 et.tm_year = 1995;
362 et.tm_month = 10 - 1;
363 et.tm_mday = 7;
364 et.tm_hour = 18;
365 et.tm_min = 29;
366 et.tm_sec = 23;
367 et.tm_params.tp_gmt_offset = -8 * 3600; /* PST */
368 et.tm_params.tp_dst_offset = 0;
370 PR_NormalizeTime(&et, PR_LocalTimeParameters);
371 if (debug_mode) printf("Oct 7 18:29:23 PST 1995 is ");
372 PrintExplodedTime(&et);
373 if (debug_mode) printf(".\n");
374 testParseTimeString(PR_ImplodeTime(&et));
376 if (debug_mode) printf("Please examine the results\n");
380 **************************************************************
382 ** Testing range of years
384 **************************************************************
388 PRExplodedTime et1, et2;
389 PRTime ttt;
390 PRTime secs;
392 if (debug_mode) {
393 printf("\n");
394 printf("***************************************\n");
395 printf("** **\n");
396 printf("** Testing range of years **\n");
397 printf("** **\n");
398 printf("***************************************\n\n");
400 /* April 4, 1917 GMT */
401 et1.tm_usec = 0;
402 et1.tm_sec = 0;
403 et1.tm_min = 0;
404 et1.tm_hour = 0;
405 et1.tm_mday = 4;
406 et1.tm_month = 4 - 1;
407 et1.tm_year = 1917;
408 et1.tm_params = PR_GMTParameters(&et1);
409 PR_NormalizeTime(&et1, PR_LocalTimeParameters);
410 secs = PR_ImplodeTime(&et1);
411 if (LL_GE_ZERO(secs)) {
412 if (debug_mode)
413 printf("ERROR: April 4, 1917 GMT returns a nonnegative second count\n");
414 failed_already = 1;
415 return 1;
417 PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
418 if (!ExplodedTimeIsEqual(&et1, &et2)) {
419 if (debug_mode)
420 printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for April 4, 1917 GMT\n");
421 failed_already=1;
422 return 1;
424 ttt = PR_ImplodeTime(&et1);
425 testParseTimeString( ttt );
427 if (debug_mode) printf("Test passed for April 4, 1917\n");
429 /* July 4, 2050 */
430 et1.tm_usec = 0;
431 et1.tm_sec = 0;
432 et1.tm_min = 0;
433 et1.tm_hour = 0;
434 et1.tm_mday = 4;
435 et1.tm_month = 7 - 1;
436 et1.tm_year = 2050;
437 et1.tm_params = PR_GMTParameters(&et1);
438 PR_NormalizeTime(&et1, PR_LocalTimeParameters);
439 secs = PR_ImplodeTime(&et1);
440 if (!LL_GE_ZERO(secs)) {
441 if (debug_mode)
442 printf("ERROR: July 4, 2050 GMT returns a negative second count\n");
443 failed_already = 1;
444 return 1;
446 PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
447 if (!ExplodedTimeIsEqual(&et1, &et2)) {
448 if (debug_mode)
449 printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for July 4, 2050 GMT\n");
450 failed_already=1;
451 return 1;
453 testParseTimeString(PR_ImplodeTime(&et1));
455 if (debug_mode) printf("Test passed for July 4, 2050\n");
460 **************************************************************
462 ** Stress test
464 ** Go through four years, starting from
465 ** 00:00:00 PST Jan. 1, 2005, incrementing
466 ** every 10 minutes.
468 **************************************************************
472 PRExplodedTime et, et1, et2;
473 PRInt64 usecPer10Min;
474 int day, hour, min;
475 PRTime usecs;
476 int dstInEffect = 0;
478 if (debug_mode) {
479 printf("\n");
480 printf("*******************************************************\n");
481 printf("** **\n");
482 printf("** Stress test Pacific Time **\n");
483 printf("** Starting from midnight Jan. 1, 2005 PST, **\n");
484 printf("** going through four years in 10-minute increment **\n");
485 printf("** **\n");
486 printf("*******************************************************\n\n");
488 LL_I2L(usecPer10Min, 600000000L);
490 /* 00:00:00 PST Jan. 1, 2005 */
491 et.tm_usec = 0;
492 et.tm_sec = 0;
493 et.tm_min = 0;
494 et.tm_hour = 0;
495 et.tm_mday = 1;
496 et.tm_month = 0;
497 et.tm_year = 2005;
498 et.tm_params.tp_gmt_offset = -8 * 3600;
499 et.tm_params.tp_dst_offset = 0;
500 usecs = PR_ImplodeTime(&et);
502 for (day = 0; day < 4 * 365 + 1; day++) {
503 for (hour = 0; hour < 24; hour++) {
504 for (min = 0; min < 60; min += 10) {
505 LL_ADD(usecs, usecs, usecPer10Min);
506 PR_ExplodeTime(usecs, PR_USPacificTimeParameters, &et1);
508 et2 = et;
509 et2.tm_usec += 600000000L;
510 PR_NormalizeTime(&et2, PR_USPacificTimeParameters);
512 if (!ExplodedTimeIsEqual(&et1, &et2)) {
513 printf("ERROR: componentwise comparison failed\n");
514 PrintExplodedTime(&et1);
515 printf("\n");
516 PrintExplodedTime(&et2);
517 printf("\n");
518 failed_already=1;
519 return 1;
522 if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
523 printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
524 PrintExplodedTime(&et1);
525 printf("\n");
526 failed_already=1;
527 return 1;
529 testParseTimeString(usecs);
531 if (!dstInEffect && et1.tm_params.tp_dst_offset) {
532 dstInEffect = 1;
533 if (debug_mode) {
534 printf("DST changeover from ");
535 PrintExplodedTime(&et);
536 printf(" to ");
537 PrintExplodedTime(&et1);
538 printf(".\n");
540 } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
541 dstInEffect = 0;
542 if (debug_mode) {
543 printf("DST changeover from ");
544 PrintExplodedTime(&et);
545 printf(" to ");
546 PrintExplodedTime(&et1);
547 printf(".\n");
551 et = et1;
555 if (debug_mode) printf("Test passed\n");
559 /* Same stress test, but with PR_LocalTimeParameters */
562 PRExplodedTime et, et1, et2;
563 PRInt64 usecPer10Min;
564 int day, hour, min;
565 PRTime usecs;
566 int dstInEffect = 0;
568 if (debug_mode) {
569 printf("\n");
570 printf("*******************************************************\n");
571 printf("** **\n");
572 printf("** Stress test Local Time **\n");
573 printf("** Starting from midnight Jan. 1, 2005 PST, **\n");
574 printf("** going through four years in 10-minute increment **\n");
575 printf("** **\n");
576 printf("*******************************************************\n\n");
579 LL_I2L(usecPer10Min, 600000000L);
581 /* 00:00:00 PST Jan. 1, 2005 */
582 et.tm_usec = 0;
583 et.tm_sec = 0;
584 et.tm_min = 0;
585 et.tm_hour = 0;
586 et.tm_mday = 1;
587 et.tm_month = 0;
588 et.tm_year = 2005;
589 et.tm_params.tp_gmt_offset = -8 * 3600;
590 et.tm_params.tp_dst_offset = 0;
591 usecs = PR_ImplodeTime(&et);
593 for (day = 0; day < 4 * 365 + 1; day++) {
594 for (hour = 0; hour < 24; hour++) {
595 for (min = 0; min < 60; min += 10) {
596 LL_ADD(usecs, usecs, usecPer10Min);
597 PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);
599 et2 = et;
600 et2.tm_usec += 600000000L;
601 PR_NormalizeTime(&et2, PR_LocalTimeParameters);
603 if (!ExplodedTimeIsEqual(&et1, &et2)) {
604 printf("ERROR: componentwise comparison failed\n");
605 PrintExplodedTime(&et1);
606 printf("\n");
607 PrintExplodedTime(&et2);
608 printf("\n");
609 return 1;
612 if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
613 printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
614 PrintExplodedTime(&et1);
615 printf("\n");
616 failed_already=1;
617 return 1;
619 testParseTimeString(usecs);
621 if (!dstInEffect && et1.tm_params.tp_dst_offset) {
622 dstInEffect = 1;
623 if (debug_mode) {
624 printf("DST changeover from ");
625 PrintExplodedTime(&et);
626 printf(" to ");
627 PrintExplodedTime(&et1);
628 printf(".\n");
630 } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
631 dstInEffect = 0;
632 if (debug_mode) {
633 printf("DST changeover from ");
634 PrintExplodedTime(&et);
635 printf(" to ");
636 PrintExplodedTime(&et1);
637 printf(".\n");
641 et = et1;
645 if (debug_mode) printf("Test passed\n");
648 /* Same stress test, but with PR_LocalTimeParameters and going backward */
651 PRExplodedTime et, et1, et2;
652 PRInt64 usecPer10Min;
653 int day, hour, min;
654 PRTime usecs;
655 int dstInEffect = 0;
657 if (debug_mode) {
658 printf("\n");
659 printf("*******************************************************\n");
660 printf("** **\n");
661 printf("** Stress test Local Time **\n");
662 printf("** Starting from midnight Jan. 1, 2009 PST, **\n");
663 printf("** going back four years in 10-minute increment **\n");
664 printf("** **\n");
665 printf("*******************************************************\n\n");
668 LL_I2L(usecPer10Min, 600000000L);
670 /* 00:00:00 PST Jan. 1, 2009 */
671 et.tm_usec = 0;
672 et.tm_sec = 0;
673 et.tm_min = 0;
674 et.tm_hour = 0;
675 et.tm_mday = 1;
676 et.tm_month = 0;
677 et.tm_year = 2009;
678 et.tm_params.tp_gmt_offset = -8 * 3600;
679 et.tm_params.tp_dst_offset = 0;
680 usecs = PR_ImplodeTime(&et);
682 for (day = 0; day < 4 * 365 + 1; day++) {
683 for (hour = 0; hour < 24; hour++) {
684 for (min = 0; min < 60; min += 10) {
685 LL_SUB(usecs, usecs, usecPer10Min);
686 PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);
688 et2 = et;
689 et2.tm_usec -= 600000000L;
690 PR_NormalizeTime(&et2, PR_LocalTimeParameters);
692 if (!ExplodedTimeIsEqual(&et1, &et2)) {
693 printf("ERROR: componentwise comparison failed\n");
694 PrintExplodedTime(&et1);
695 printf("\n");
696 PrintExplodedTime(&et2);
697 printf("\n");
698 return 1;
701 if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
702 printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
703 PrintExplodedTime(&et1);
704 printf("\n");
705 failed_already=1;
706 return 1;
708 testParseTimeString(usecs);
710 if (!dstInEffect && et1.tm_params.tp_dst_offset) {
711 dstInEffect = 1;
712 if (debug_mode) {
713 printf("DST changeover from ");
714 PrintExplodedTime(&et);
715 printf(" to ");
716 PrintExplodedTime(&et1);
717 printf(".\n");
719 } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
720 dstInEffect = 0;
721 if (debug_mode) {
722 printf("DST changeover from ");
723 PrintExplodedTime(&et);
724 printf(" to ");
725 PrintExplodedTime(&et1);
726 printf(".\n");
730 et = et1;
736 if (failed_already) return 1;
737 else return 0;