1 /* 2 ********************************************************************** 3 * Copyright (C) 1998-2012, International Business Machines 4 * Corporation and others. All Rights Reserved. 5 ********************************************************************** 6 * 7 * File date.c 8 * 9 * Modification History: 10 * 11 * Date Name Description 12 * 06/11/99 stephen Creation. 13 * 06/16/99 stephen Modified to use uprint. 14 * 08/11/11 srl added Parse and milli/second in/out 15 ******************************************************************************* 16 */ 17 18 #include <stdlib.h> 19 #include <stdio.h> 20 #include <string.h> 21 22 #include "unicode/utypes.h" 23 #include "unicode/ustring.h" 24 #include "unicode/uclean.h" 25 26 #include "unicode/ucnv.h" 27 #include "unicode/udat.h" 28 #include "unicode/ucal.h" 29 30 #include "uprint.h" 31 32 int main(int argc, char **argv); 33 34 #if UCONFIG_NO_FORMATTING || UCONFIG_NO_CONVERSION 35 36 int main(int argc, char **argv) 37 { 38 printf("%s: Sorry, UCONFIG_NO_FORMATTING or UCONFIG_NO_CONVERSION was turned on (see uconfig.h). No formatting can be done. \n", argv[0]); 39 return 0; 40 } 41 #else 42 43 44 /* Protos */ 45 static void usage(void); 46 static void version(void); 47 static void date(UDate when, const UChar *tz, UDateFormatStyle style, const char *format, UErrorCode *status); 48 static UDate getWhen(const char *millis, const char *seconds, const char *format, UDateFormatStyle style, const char *parse, const UChar *tz, UErrorCode *status); 49 50 UConverter *cnv = NULL; 51 52 /* The version of date */ 53 #define DATE_VERSION "1.0" 54 55 /* "GMT" */ 56 static const UChar GMT_ID [] = { 0x0047, 0x004d, 0x0054, 0x0000 }; 57 58 #define FORMAT_MILLIS "%" 59 #define FORMAT_SECONDS "%%" 60 61 int 62 main(int argc, 63 char **argv) 64 { 65 int printUsage = 0; 66 int printVersion = 0; 67 int optInd = 1; 68 char *arg; 69 const UChar *tz = 0; 70 UDateFormatStyle style = UDAT_DEFAULT; 71 UErrorCode status = U_ZERO_ERROR; 72 const char *format = NULL; 73 char *parse = NULL; 74 char *seconds = NULL; 75 char *millis = NULL; 76 UDate when; 77 78 /* parse the options */ 79 for(optInd = 1; optInd < argc; ++optInd) { 80 arg = argv[optInd]; 81 82 /* version info */ 83 if(strcmp(arg, "-v") == 0 || strcmp(arg, "--version") == 0) { 84 printVersion = 1; 85 } 86 /* usage info */ 87 else if(strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) { 88 printUsage = 1; 89 } 90 /* display date in gmt */ 91 else if(strcmp(arg, "-u") == 0 || strcmp(arg, "--gmt") == 0) { 92 tz = GMT_ID; 93 } 94 /* display date in gmt */ 95 else if(strcmp(arg, "-f") == 0 || strcmp(arg, "--full") == 0) { 96 style = UDAT_FULL; 97 } 98 /* display date in long format */ 99 else if(strcmp(arg, "-l") == 0 || strcmp(arg, "--long") == 0) { 100 style = UDAT_LONG; 101 } 102 /* display date in medium format */ 103 else if(strcmp(arg, "-m") == 0 || strcmp(arg, "--medium") == 0) { 104 style = UDAT_MEDIUM; 105 } 106 /* display date in short format */ 107 else if(strcmp(arg, "-s") == 0 || strcmp(arg, "--short") == 0) { 108 style = UDAT_SHORT; 109 } 110 else if(strcmp(arg, "-F") == 0 || strcmp(arg, "--format") == 0) { 111 if ( optInd + 1 < argc ) { 112 optInd++; 113 format = argv[optInd]; 114 } 115 } else if(strcmp(arg, "-r") == 0) { 116 if ( optInd + 1 < argc ) { 117 optInd++; 118 seconds = argv[optInd]; 119 } 120 } else if(strcmp(arg, "-R") == 0) { 121 if ( optInd + 1 < argc ) { 122 optInd++; 123 millis = argv[optInd]; 124 } 125 } else if(strcmp(arg, "-P") == 0) { 126 if ( optInd + 1 < argc ) { 127 optInd++; 128 parse = argv[optInd]; 129 } 130 } 131 /* POSIX.1 says all arguments after -- are not options */ 132 else if(strcmp(arg, "--") == 0) { 133 /* skip the -- */ 134 ++optInd; 135 break; 136 } 137 /* unrecognized option */ 138 else if(strncmp(arg, "-", strlen("-")) == 0) { 139 printf("icudate: invalid option -- %s\n", arg+1); 140 printUsage = 1; 141 } 142 /* done with options, display date */ 143 else { 144 break; 145 } 146 } 147 148 /* print usage info */ 149 if(printUsage) { 150 usage(); 151 return 0; 152 } 153 154 /* print version info */ 155 if(printVersion) { 156 version(); 157 return 0; 158 } 159 160 /* get the 'when' (or now) */ 161 when = getWhen(millis, seconds, format, style, parse, tz, &status); 162 if(parse != NULL) { 163 format = FORMAT_MILLIS; /* output in millis */ 164 } 165 166 /* print the date */ 167 date(when, tz, style, format, &status); 168 169 ucnv_close(cnv); 170 171 u_cleanup(); 172 return (U_FAILURE(status) ? 1 : 0); 173 } 174 175 /* Usage information */ 176 static void 177 usage() 178 { 179 puts("Usage: icudate [OPTIONS]"); 180 puts("Options:"); 181 puts(" -h, --help Print this message and exit."); 182 puts(" -v, --version Print the version number of date and exit."); 183 puts(" -u, --gmt Display the date in Greenwich Mean Time."); 184 puts(" -f, --full Use full display format."); 185 puts(" -l, --long Use long display format."); 186 puts(" -m, --medium Use medium display format."); 187 puts(" -s, --short Use short display format."); 188 puts(" -F <format>, --format <format> Use <format> as the display format."); 189 puts(" (Special formats: \"%\" alone is Millis since 1970, \"%%\" alone is Seconds since 1970)"); 190 puts(" -r <seconds> Use <seconds> as the time (Epoch 1970) rather than now."); 191 puts(" -R <millis> Use <millis> as the time (Epoch 1970) rather than now."); 192 puts(" -P <string> Parse <string> as the time, output in millis format."); 193 } 194 195 /* Version information */ 196 static void 197 version() 198 { 199 UErrorCode status = U_ZERO_ERROR; 200 const char *tzVer; 201 int len = 256; 202 UChar tzName[256]; 203 printf("icudate version %s, created by Stephen F. Booth.\n", 204 DATE_VERSION); 205 puts(U_COPYRIGHT_STRING); 206 tzVer = ucal_getTZDataVersion(&status); 207 if(U_FAILURE(status)) { 208 tzVer = u_errorName(status); 209 } 210 printf("\n"); 211 printf("ICU Version: %s\n", U_ICU_VERSION); 212 printf("ICU Data (major+min): %s\n", U_ICUDATA_NAME); 213 printf("Default Locale: %s\n", uloc_getDefault()); 214 printf("Time Zone Data Version: %s\n", tzVer); 215 printf("Default Time Zone: "); 216 status = U_ZERO_ERROR; 217 u_init(&status); 218 len = ucal_getDefaultTimeZone(tzName, len, &status); 219 if(U_FAILURE(status)) { 220 fprintf(stderr, " ** Error getting default zone: %s\n", u_errorName(status)); 221 } 222 uprint(tzName, stdout, &status); 223 printf("\n\n"); 224 } 225 226 static int32_t charsToUCharsDefault(UChar *uchars, int32_t ucharsSize, const char*chars, int32_t charsSize, UErrorCode *status) { 227 int32_t len=-1; 228 if(U_FAILURE(*status)) return len; 229 if(cnv==NULL) { 230 cnv = ucnv_open(NULL, status); 231 } 232 if(cnv&&U_SUCCESS(*status)) { 233 len = ucnv_toUChars(cnv, uchars, ucharsSize, chars,charsSize, status); 234 } 235 return len; 236 } 237 238 /* Format the date */ 239 static void 240 date(UDate when, 241 const UChar *tz, 242 UDateFormatStyle style, 243 const char *format, 244 UErrorCode *status ) 245 { 246 UChar *s = 0; 247 int32_t len = 0; 248 UDateFormat *fmt; 249 UChar uFormat[100]; 250 251 if(U_FAILURE(*status)) return; 252 253 if( format != NULL ) { 254 if(!strcmp(format,FORMAT_MILLIS)) { 255 printf("%.0f\n", when); 256 return; 257 } else if(!strcmp(format, FORMAT_SECONDS)) { 258 printf("%.3f\n", when/1000.0); 259 return; 260 } 261 } 262 263 fmt = udat_open(style, style, 0, tz, -1,NULL,0, status); 264 if ( format != NULL ) { 265 charsToUCharsDefault(uFormat,sizeof(uFormat)/sizeof(uFormat[0]),format,-1,status); 266 udat_applyPattern(fmt,FALSE,uFormat,-1); 267 } 268 len = udat_format(fmt, when, 0, len, 0, status); 269 if(*status == U_BUFFER_OVERFLOW_ERROR) { 270 *status = U_ZERO_ERROR; 271 s = (UChar*) malloc(sizeof(UChar) * (len+1)); 272 if(s == 0) goto finish; 273 udat_format(fmt, when, s, len + 1, 0, status); 274 } 275 if(U_FAILURE(*status)) goto finish; 276 277 /* print the date string */ 278 uprint(s, stdout, status); 279 280 /* print a trailing newline */ 281 printf("\n"); 282 283 finish: 284 if(U_FAILURE(*status)) { 285 fprintf(stderr, "Error in Print: %s\n", u_errorName(*status)); 286 } 287 udat_close(fmt); 288 free(s); 289 } 290 291 static UDate getWhen(const char *millis, const char *seconds, const char *format, 292 UDateFormatStyle style, const char *parse, const UChar *tz, UErrorCode *status) { 293 UDateFormat *fmt = NULL; 294 UChar uFormat[100]; 295 UChar uParse[256]; 296 UDate when=0; 297 int32_t parsepos = 0; 298 299 if(millis != NULL) { 300 sscanf(millis, "%lf", &when); 301 return when; 302 } else if(seconds != NULL) { 303 sscanf(seconds, "%lf", &when); 304 return when*1000.0; 305 } 306 307 if(parse!=NULL) { 308 if( format != NULL ) { 309 if(!strcmp(format,FORMAT_MILLIS)) { 310 sscanf(parse, "%lf", &when); 311 return when; 312 } else if(!strcmp(format, FORMAT_SECONDS)) { 313 sscanf(parse, "%lf", &when); 314 return when*1000.0; 315 } 316 } 317 318 fmt = udat_open(style, style, 0, tz, -1,NULL,0, status); 319 if ( format != NULL ) { 320 charsToUCharsDefault(uFormat,sizeof(uFormat)/sizeof(uFormat[0]), format,-1,status); 321 udat_applyPattern(fmt,FALSE,uFormat,-1); 322 } 323 324 charsToUCharsDefault(uParse,sizeof(uParse)/sizeof(uParse[0]), parse,-1,status); 325 when = udat_parse(fmt, uParse, -1, &parsepos, status); 326 if(U_FAILURE(*status)) { 327 fprintf(stderr, "Error in Parse: %s\n", u_errorName(*status)); 328 if(parsepos > 0 && parsepos <= (int32_t)strlen(parse)) { 329 fprintf(stderr, "ERR>\"%s\" @%d\n" 330 "ERR> %*s^\n", 331 parse,parsepos,parsepos,""); 332 333 } 334 } 335 336 udat_close(fmt); 337 return when; 338 } else { 339 return ucal_getNow(); 340 } 341 } 342 343 #endif 344