1 /* 2 * Copyright 2003-2009, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <SupportDefs.h> 8 #include <parsedate.h> 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 13 14 #define ABSOLUTE 0 15 #define UNKNOWN 0 16 #define DAY_RELATIVE PARSEDATE_RELATIVE_TIME 17 #define MINUTE_RELATIVE (PARSEDATE_RELATIVE_TIME \ 18 | PARSEDATE_MINUTE_RELATIVE_TIME) 19 #define INVALID PARSEDATE_INVALID_DATE 20 21 22 const char* 23 parsedate_flags_to_string(time_t result, int flags) 24 { 25 if (result == -1) { 26 if ((flags & PARSEDATE_INVALID_DATE) != 0) 27 return "invalid"; 28 return "unknown"; 29 } 30 31 if ((flags & PARSEDATE_RELATIVE_TIME) != 0) { 32 if ((flags & PARSEDATE_MINUTE_RELATIVE_TIME) != 0) 33 return "minute relative"; 34 35 return "day relative"; 36 } 37 38 return "absolute"; 39 } 40 41 42 int 43 main(int argc, char** argv) 44 { 45 time_t now = 1249471430; 46 // August 5th, 2009, 11:23:50 GMT 47 48 struct test { 49 time_t result; 50 const char* date; 51 int flags; 52 bool uses_dst; 53 bool requires_zone_shift; 54 }; 55 static const test kDates[] = { 56 {1248739200, "last tuesday", DAY_RELATIVE, true, true}, 57 {1249430400, "today", DAY_RELATIVE, true, true}, 58 {1249948800, "next tuesday", DAY_RELATIVE, true, true}, 59 {1249344000, "tuesday", DAY_RELATIVE, true, true}, 60 {1249467830, "last hour", MINUTE_RELATIVE, true, false}, 61 {1249475030, "1 hour", MINUTE_RELATIVE, true, false}, 62 {now, "now", MINUTE_RELATIVE, true, false}, 63 {219456000, "1976-12-15", ABSOLUTE, false, true}, 64 {219456000, "12/15/1976", ABSOLUTE, false, true}, 65 {219456000, "1976/12/15", ABSOLUTE, false, true}, 66 {219456000, "15.12.1976", ABSOLUTE, false, true}, 67 {1061596800, "Sat, 08/23/2003", ABSOLUTE, true, true}, 68 {1061596800, "Sun, 08/23/2003", ABSOLUTE, true, true}, 69 {-1, "", INVALID, false, false}, 70 {1249873200, "next monday 3:00", DAY_RELATIVE, true, true}, 71 {1249533720, "thursday 4:42", DAY_RELATIVE, true, true}, 72 {1249533740, "thursday +4:42:20", DAY_RELATIVE, true, true}, 73 {1249533720, "this thursday 4:42", DAY_RELATIVE, true, true}, 74 {1249473950, "42 minutes", MINUTE_RELATIVE, true, false}, 75 {1250640000, "2 weeks", DAY_RELATIVE, true, true}, 76 {1249471730, "next 5 minutes", MINUTE_RELATIVE, true, false}, 77 {1249470530, "last 15 minutes", MINUTE_RELATIVE, true, false}, 78 {1249470530, "-15 minutes", MINUTE_RELATIVE, true, false}, 79 {1249486380, "3:33pm GMT", DAY_RELATIVE, true, false}, 80 {739706403, "Mon, June 10th, 1993 10:00:03 am GMT", ABSOLUTE, true, false}, 81 {-1, "Sat, 16 Aug Ìîñêîâñêîå âðåìÿ (çèìà)", INVALID, false, false}, 82 {739706403, "Mon, June 10th, 1993 10:00:03 am UTC", ABSOLUTE, true, false}, 83 {739699203, "Mon, June 10th, 1993 10:00:03 am CEST", ABSOLUTE, true, false}, 84 {739706403, "Mon, June 10th, 1993 10:00:03 am +0000", ABSOLUTE, true, false}, 85 {-1, "Mon, June 10th, 1993 10:00:03 am 0000", UNKNOWN, true, false}, 86 {739702803, "Mon, June 10th, 1993 10:00:03 am +0100", ABSOLUTE, true, false}, 87 {739731603, "Mon, June 10th, 1993 10:00:03 am -0700", ABSOLUTE, true, false}, 88 {739654203, "Mon, June 10th, 1993 06:00:03 am ACDT", ABSOLUTE, true, false}, 89 {1291204800, "01 Dec 10 12:00", ABSOLUTE, false, true}, 90 {-1, NULL, 0, false} 91 }; 92 93 bool verbose = argc > 1; 94 95 if (verbose) 96 printf("All times relative to: %s (%ld)\n", ctime(&now), now); 97 98 struct TzInfo { 99 const char* timezone; 100 time_t std_offset; 101 time_t dst_offset; 102 }; 103 TzInfo tzInfo[] = { 104 { "GMT", 0 }, 105 { "Europe/Berlin", -1 * 3600, -2 * 3600 }, 106 { "Asia/Tokyo", -9 * 3600, -9 * 3600 }, 107 { "America/Los_Angeles", 8 * 3600, 7 * 3600 }, 108 { NULL, 0, 0 } 109 }; 110 111 for (int tz = 0; tzInfo[tz].timezone != NULL; tz++) { 112 printf("timezone: %s ...\n", tzInfo[tz].timezone); 113 setenv("TZ", tzInfo[tz].timezone, 1); 114 tzset(); 115 116 for (int32 i = 0; kDates[i].date; i++) { 117 int flags = 0; 118 time_t result = parsedate_etc(kDates[i].date, now, &flags); 119 120 time_t expectedResult = kDates[i].result; 121 if (kDates[i].requires_zone_shift) { 122 expectedResult += 123 kDates[i].uses_dst 124 ? tzInfo[tz].dst_offset 125 : tzInfo[tz].std_offset; 126 } 127 bool failure = false; 128 if (flags != kDates[i].flags || result != expectedResult) 129 failure = true; 130 if (failure) { 131 printf( 132 "FAILURE: parsing time at index %ld (should be %ld, %s)\n", 133 i, expectedResult, 134 parsedate_flags_to_string(expectedResult, flags)); 135 } 136 137 if (verbose || failure) { 138 printf("\"%s\" = %ld (%s) -> %s", kDates[i].date, result, 139 parsedate_flags_to_string(result, flags), result == -1 140 ? "-\n" : ctime(&result)); 141 } 142 } 143 } 144 145 return 0; 146 } 147