• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
main(int argc,char ** argv)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
main(int argc,char ** argv)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
usage()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
version()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 
charsToUCharsDefault(UChar * uchars,int32_t ucharsSize,const char * chars,int32_t charsSize,UErrorCode * status)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
date(UDate when,const UChar * tz,UDateFormatStyle style,const char * format,UErrorCode * status)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 
getWhen(const char * millis,const char * seconds,const char * format,UDateFormatStyle style,const char * parse,const UChar * tz,UErrorCode * status)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