Home | History | Annotate | Download | only in date
      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