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