OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.17.0/] [newlib/] [libc/] [time/] [strftime.c] - Blame information for rev 158

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/*
2
 * strftime.c
3
 * Original Author:     G. Haley
4
 * Additions from:      Eric Blake
5
 *
6
 * Places characters into the array pointed to by s as controlled by the string
7
 * pointed to by format. If the total number of resulting characters including
8
 * the terminating null character is not more than maxsize, returns the number
9
 * of characters placed into the array pointed to by s (not including the
10
 * terminating null character); otherwise zero is returned and the contents of
11
 * the array indeterminate.
12
 */
13
 
14
/*
15
FUNCTION
16
<<strftime>>---flexible calendar time formatter
17
 
18
INDEX
19
        strftime
20
 
21
ANSI_SYNOPSIS
22
        #include <time.h>
23
        size_t strftime(char *<[s]>, size_t <[maxsize]>,
24
                        const char *<[format]>, const struct tm *<[timp]>);
25
 
26
TRAD_SYNOPSIS
27
        #include <time.h>
28
        size_t strftime(<[s]>, <[maxsize]>, <[format]>, <[timp]>)
29
        char *<[s]>;
30
        size_t <[maxsize]>;
31
        char *<[format]>;
32
        struct tm *<[timp]>;
33
 
34
DESCRIPTION
35
<<strftime>> converts a <<struct tm>> representation of the time (at
36
<[timp]>) into a null-terminated string, starting at <[s]> and occupying
37
no more than <[maxsize]> characters.
38
 
39
You control the format of the output using the string at <[format]>.
40
<<*<[format]>>> can contain two kinds of specifications: text to be
41
copied literally into the formatted string, and time conversion
42
specifications.  Time conversion specifications are two- and
43
three-character sequences beginning with `<<%>>' (use `<<%%>>' to
44
include a percent sign in the output).  Each defined conversion
45
specification selects only the specified field(s) of calendar time
46
data from <<*<[timp]>>>, and converts it to a string in one of the
47
following ways:
48
 
49
o+
50
o %a
51
A three-letter abbreviation for the day of the week. [tm_wday]
52
 
53
o %A
54
The full name for the day of the week, one of `<<Sunday>>',
55
`<<Monday>>', `<<Tuesday>>', `<<Wednesday>>', `<<Thursday>>',
56
`<<Friday>>', or `<<Saturday>>'. [tm_wday]
57
 
58
o %b
59
A three-letter abbreviation for the month name. [tm_mon]
60
 
61
o %B
62
The full name of the month, one of `<<January>>', `<<February>>',
63
`<<March>>', `<<April>>', `<<May>>', `<<June>>', `<<July>>',
64
`<<August>>', `<<September>>', `<<October>>', `<<November>>',
65
`<<December>>'. [tm_mon]
66
 
67
o %c
68
A string representing the complete date and time, in the form
69
`<<"%a %b %e %H:%M:%S %Y">>' (example "Mon Apr 01 13:13:13
70
1992"). [tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year, tm_wday]
71
 
72
o %C
73
The century, that is, the year divided by 100 then truncated.  For
74
4-digit years, the result is zero-padded and exactly two characters;
75
but for other years, there may a negative sign or more digits.  In
76
this way, `<<%C%y>>' is equivalent to `<<%Y>>'. [tm_year]
77
 
78
o %d
79
The day of the month, formatted with two digits (from `<<01>>' to
80
`<<31>>'). [tm_mday]
81
 
82
o %D
83
A string representing the date, in the form `<<"%m/%d/%y">>'.
84
[tm_mday, tm_mon, tm_year]
85
 
86
o %e
87
The day of the month, formatted with leading space if single digit
88
(from `<<1>>' to `<<31>>'). [tm_mday]
89
 
90
o %E<<x>>
91
In some locales, the E modifier selects alternative representations of
92
certain modifiers <<x>>.  But in the "C" locale supported by newlib,
93
it is ignored, and treated as %<<x>>.
94
 
95
o %F
96
A string representing the ISO 8601:2000 date format, in the form
97
`<<"%Y-%m-%d">>'. [tm_mday, tm_mon, tm_year]
98
 
99
o %g
100
The last two digits of the week-based year, see specifier %G (from
101
`<<00>>' to `<<99>>'). [tm_year, tm_wday, tm_yday]
102
 
103
o %G
104
The week-based year. In the ISO 8601:2000 calendar, week 1 of the year
105
includes January 4th, and begin on Mondays. Therefore, if January 1st,
106
2nd, or 3rd falls on a Sunday, that day and earlier belong to the last
107
week of the previous year; and if December 29th, 30th, or 31st falls
108
on Monday, that day and later belong to week 1 of the next year.  For
109
consistency with %Y, it always has at least four characters.
110
Example: "%G" for Saturday 2nd January 1999 gives "1998", and for
111
Tuesday 30th December 1997 gives "1998". [tm_year, tm_wday, tm_yday]
112
 
113
o %h
114
A three-letter abbreviation for the month name (synonym for
115
"%b"). [tm_mon]
116
 
117
o %H
118
The hour (on a 24-hour clock), formatted with two digits (from
119
`<<00>>' to `<<23>>'). [tm_hour]
120
 
121
o %I
122
The hour (on a 12-hour clock), formatted with two digits (from
123
`<<01>>' to `<<12>>'). [tm_hour]
124
 
125
o %j
126
The count of days in the year, formatted with three digits
127
(from `<<001>>' to `<<366>>'). [tm_yday]
128
 
129
o %k
130
The hour (on a 24-hour clock), formatted with leading space if single
131
digit (from `<<0>>' to `<<23>>'). Non-POSIX extension. [tm_hour]
132
 
133
o %l
134
The hour (on a 12-hour clock), formatted with leading space if single
135
digit (from `<<1>>' to `<<12>>'). Non-POSIX extension. [tm_hour]
136
 
137
o %m
138
The month number, formatted with two digits (from `<<01>>' to `<<12>>').
139
[tm_mon]
140
 
141
o %M
142
The minute, formatted with two digits (from `<<00>>' to `<<59>>'). [tm_min]
143
 
144
o %n
145
A newline character (`<<\n>>').
146
 
147
o %O<<x>>
148
In some locales, the O modifier selects alternative digit characters
149
for certain modifiers <<x>>.  But in the "C" locale supported by newlib, it
150
is ignored, and treated as %<<x>>.
151
 
152
o %p
153
Either `<<AM>>' or `<<PM>>' as appropriate. [tm_hour]
154
 
155
o %r
156
The 12-hour time, to the second.  Equivalent to "%I:%M:%S %p". [tm_sec,
157
tm_min, tm_hour]
158
 
159
o %R
160
The 24-hour time, to the minute.  Equivalent to "%H:%M". [tm_min, tm_hour]
161
 
162
o %S
163
The second, formatted with two digits (from `<<00>>' to `<<60>>').  The
164
value 60 accounts for the occasional leap second. [tm_sec]
165
 
166
o %t
167
A tab character (`<<\t>>').
168
 
169
o %T
170
The 24-hour time, to the second.  Equivalent to "%H:%M:%S". [tm_sec,
171
tm_min, tm_hour]
172
 
173
o %u
174
The weekday as a number, 1-based from Monday (from `<<1>>' to
175
`<<7>>'). [tm_wday]
176
 
177
o %U
178
The week number, where weeks start on Sunday, week 1 contains the first
179
Sunday in a year, and earlier days are in week 0.  Formatted with two
180
digits (from `<<00>>' to `<<53>>').  See also <<%W>>. [tm_wday, tm_yday]
181
 
182
o %V
183
The week number, where weeks start on Monday, week 1 contains January 4th,
184
and earlier days are in the previous year.  Formatted with two digits
185
(from `<<01>>' to `<<53>>').  See also <<%G>>. [tm_year, tm_wday, tm_yday]
186
 
187
o %w
188
The weekday as a number, 0-based from Sunday (from `<<0>>' to `<<6>>').
189
[tm_wday]
190
 
191
o %W
192
The week number, where weeks start on Monday, week 1 contains the first
193
Monday in a year, and earlier days are in week 0.  Formatted with two
194
digits (from `<<00>>' to `<<53>>'). [tm_wday, tm_yday]
195
 
196
o %x
197
A string representing the complete date, equivalent to "%m/%d/%y".
198
[tm_mon, tm_mday, tm_year]
199
 
200
o %X
201
A string representing the full time of day (hours, minutes, and
202
seconds), equivalent to "%H:%M:%S". [tm_sec, tm_min, tm_hour]
203
 
204
o %y
205
The last two digits of the year (from `<<00>>' to `<<99>>'). [tm_year]
206
 
207
o %Y
208
The full year, equivalent to <<%C%y>>.  It will always have at least four
209
characters, but may have more.  The year is accurate even when tm_year
210
added to the offset of 1900 overflows an int. [tm_year]
211
 
212
o %z
213
The offset from UTC.  The format consists of a sign (negative is west of
214
Greewich), two characters for hour, then two characters for minutes
215
(-hhmm or +hhmm).  If tm_isdst is negative, the offset is unknown and no
216
output is generated; if it is zero, the offset is the standard offset for
217
the current time zone; and if it is positive, the offset is the daylight
218
savings offset for the current timezone. The offset is determined from
219
the TZ environment variable, as if by calling tzset(). [tm_isdst]
220
 
221
o %Z
222
The time zone name.  If tm_isdst is negative, no output is generated.
223
Otherwise, the time zone name is based on the TZ environment variable,
224
as if by calling tzset(). [tm_isdst]
225
 
226
o %%
227
A single character, `<<%>>'.
228
o-
229
 
230
RETURNS
231
When the formatted time takes up no more than <[maxsize]> characters,
232
the result is the length of the formatted string.  Otherwise, if the
233
formatting operation was abandoned due to lack of room, the result is
234
<<0>>, and the string starting at <[s]> corresponds to just those
235
parts of <<*<[format]>>> that could be completely filled in within the
236
<[maxsize]> limit.
237
 
238
PORTABILITY
239
ANSI C requires <<strftime>>, but does not specify the contents of
240
<<*<[s]>>> when the formatted string would require more than
241
<[maxsize]> characters.  Unrecognized specifiers and fields of
242
<<timp>> that are out of range cause undefined results.  Since some
243
formats expand to 0 bytes, it is wise to set <<*<[s]>>> to a nonzero
244
value beforehand to distinguish between failure and an empty string.
245
This implementation does not support <<s>> being NULL, nor overlapping
246
<<s>> and <<format>>.
247
 
248
<<strftime>> requires no supporting OS subroutines.
249
*/
250
 
251
#include <stddef.h>
252
#include <stdio.h>
253
#include <time.h>
254
#include <string.h>
255
#include <stdlib.h>
256
#include "local.h"
257
 
258
static _CONST int dname_len[7] =
259
{6, 6, 7, 9, 8, 6, 8};
260
 
261
static _CONST char *_CONST dname[7] =
262
{"Sunday", "Monday", "Tuesday", "Wednesday",
263
 "Thursday", "Friday", "Saturday"};
264
 
265
static _CONST int mname_len[12] =
266
{7, 8, 5, 5, 3, 4, 4, 6, 9, 7, 8, 8};
267
 
268
static _CONST char *_CONST mname[12] =
269
{"January", "February", "March", "April",
270
 "May", "June", "July", "August", "September", "October", "November",
271
 "December"};
272
 
273
/* Using the tm_year, tm_wday, and tm_yday components of TIM_P, return
274
   -1, 0, or 1 as the adjustment to add to the year for the ISO week
275
   numbering used in "%g%G%V", avoiding overflow.  */
276
static int
277
_DEFUN (iso_year_adjust, (tim_p),
278
        _CONST struct tm *tim_p)
279
{
280
  /* Account for fact that tm_year==0 is year 1900.  */
281
  int leap = isleap (tim_p->tm_year + (YEAR_BASE
282
                                       - (tim_p->tm_year < 0 ? 0 : 2000)));
283
 
284
  /* Pack the yday, wday, and leap year into a single int since there are so
285
     many disparate cases.  */
286
#define PACK(yd, wd, lp) (((yd) << 4) + (wd << 1) + (lp))
287
  switch (PACK (tim_p->tm_yday, tim_p->tm_wday, leap))
288
    {
289
    case PACK (0, 5, 0): /* Jan 1 is Fri, not leap.  */
290
    case PACK (0, 6, 0): /* Jan 1 is Sat, not leap.  */
291
    case PACK (0, 0, 0): /* Jan 1 is Sun, not leap.  */
292
    case PACK (0, 5, 1): /* Jan 1 is Fri, leap year.  */
293
    case PACK (0, 6, 1): /* Jan 1 is Sat, leap year.  */
294
    case PACK (0, 0, 1): /* Jan 1 is Sun, leap year.  */
295
    case PACK (1, 6, 0): /* Jan 2 is Sat, not leap.  */
296
    case PACK (1, 0, 0): /* Jan 2 is Sun, not leap.  */
297
    case PACK (1, 6, 1): /* Jan 2 is Sat, leap year.  */
298
    case PACK (1, 0, 1): /* Jan 2 is Sun, leap year.  */
299
    case PACK (2, 0, 0): /* Jan 3 is Sun, not leap.  */
300
    case PACK (2, 0, 1): /* Jan 3 is Sun, leap year.  */
301
      return -1; /* Belongs to last week of previous year.  */
302
    case PACK (362, 1, 0): /* Dec 29 is Mon, not leap.  */
303
    case PACK (363, 1, 1): /* Dec 29 is Mon, leap year.  */
304
    case PACK (363, 1, 0): /* Dec 30 is Mon, not leap.  */
305
    case PACK (363, 2, 0): /* Dec 30 is Tue, not leap.  */
306
    case PACK (364, 1, 1): /* Dec 30 is Mon, leap year.  */
307
    case PACK (364, 2, 1): /* Dec 30 is Tue, leap year.  */
308
    case PACK (364, 1, 0): /* Dec 31 is Mon, not leap.  */
309
    case PACK (364, 2, 0): /* Dec 31 is Tue, not leap.  */
310
    case PACK (364, 3, 0): /* Dec 31 is Wed, not leap.  */
311
    case PACK (365, 1, 1): /* Dec 31 is Mon, leap year.  */
312
    case PACK (365, 2, 1): /* Dec 31 is Tue, leap year.  */
313
    case PACK (365, 3, 1): /* Dec 31 is Wed, leap year.  */
314
      return 1; /* Belongs to first week of next year.  */
315
    }
316
  return 0; /* Belongs to specified year.  */
317
#undef PACK
318
}
319
 
320
size_t
321
_DEFUN (strftime, (s, maxsize, format, tim_p),
322
        char *s _AND
323
        size_t maxsize _AND
324
        _CONST char *format _AND
325
        _CONST struct tm *tim_p)
326
{
327
  size_t count = 0;
328
  int i;
329
 
330
  for (;;)
331
    {
332
      while (*format && *format != '%')
333
        {
334
          if (count < maxsize - 1)
335
            s[count++] = *format++;
336
          else
337
            return 0;
338
        }
339
 
340
      if (*format == '\0')
341
        break;
342
 
343
      format++;
344
      if (*format == 'E' || *format == 'O')
345
        format++;
346
 
347
      switch (*format)
348
        {
349
        case 'a':
350
          for (i = 0; i < 3; i++)
351
            {
352
              if (count < maxsize - 1)
353
                s[count++] =
354
                  dname[tim_p->tm_wday][i];
355
              else
356
                return 0;
357
            }
358
          break;
359
        case 'A':
360
          for (i = 0; i < dname_len[tim_p->tm_wday]; i++)
361
            {
362
              if (count < maxsize - 1)
363
                s[count++] =
364
                  dname[tim_p->tm_wday][i];
365
              else
366
                return 0;
367
            }
368
          break;
369
        case 'b':
370
        case 'h':
371
          for (i = 0; i < 3; i++)
372
            {
373
              if (count < maxsize - 1)
374
                s[count++] =
375
                  mname[tim_p->tm_mon][i];
376
              else
377
                return 0;
378
            }
379
          break;
380
        case 'B':
381
          for (i = 0; i < mname_len[tim_p->tm_mon]; i++)
382
            {
383
              if (count < maxsize - 1)
384
                s[count++] =
385
                  mname[tim_p->tm_mon][i];
386
              else
387
                return 0;
388
            }
389
          break;
390
        case 'c':
391
          {
392
            /* Length is not known because of %C%y, so recurse. */
393
            size_t adjust = strftime (&s[count], maxsize - count,
394
                                      "%a %b %e %H:%M:%S %C%y", tim_p);
395
            if (adjust > 0)
396
              count += adjust;
397
            else
398
              return 0;
399
          }
400
          break;
401
        case 'C':
402
          {
403
            /* Examples of (tm_year + YEAR_BASE) that show how %Y == %C%y
404
               with 32-bit int.
405
               %Y               %C              %y
406
               2147485547       21474855        47
407
               10000            100             00
408
               9999             99              99
409
               0999             09              99
410
               0099             00              99
411
               0001             00              01
412
               0000             00              00
413
               -001             -0              01
414
               -099             -0              99
415
               -999             -9              99
416
               -1000            -10             00
417
               -10000           -100            00
418
               -2147481748      -21474817       48
419
 
420
               Be careful of both overflow and sign adjustment due to the
421
               asymmetric range of years.
422
            */
423
            int neg = tim_p->tm_year < -YEAR_BASE;
424
            int century = tim_p->tm_year >= 0
425
              ? tim_p->tm_year / 100 + YEAR_BASE / 100
426
              : abs (tim_p->tm_year + YEAR_BASE) / 100;
427
            count += snprintf (&s[count], maxsize - count, "%s%.*d",
428
                               neg ? "-" : "", 2 - neg, century);
429
            if (count >= maxsize)
430
              return 0;
431
          }
432
          break;
433
        case 'd':
434
        case 'e':
435
          if (count < maxsize - 2)
436
            {
437
              sprintf (&s[count], *format == 'd' ? "%.2d" : "%2d",
438
                       tim_p->tm_mday);
439
              count += 2;
440
            }
441
          else
442
            return 0;
443
          break;
444
        case 'D':
445
        case 'x':
446
          /* %m/%d/%y */
447
          if (count < maxsize - 8)
448
            {
449
              sprintf (&s[count], "%.2d/%.2d/%.2d",
450
                       tim_p->tm_mon + 1, tim_p->tm_mday,
451
                       tim_p->tm_year >= 0 ? tim_p->tm_year % 100
452
                       : abs (tim_p->tm_year + YEAR_BASE) % 100);
453
              count += 8;
454
            }
455
          else
456
            return 0;
457
          break;
458
        case 'F':
459
          {
460
            /* Length is not known because of %C%y, so recurse. */
461
            size_t adjust = strftime (&s[count], maxsize - count,
462
                                      "%C%y-%m-%d", tim_p);
463
            if (adjust > 0)
464
              count += adjust;
465
            else
466
              return 0;
467
          }
468
          break;
469
        case 'g':
470
          if (count < maxsize - 2)
471
            {
472
              /* Be careful of both overflow and negative years, thanks to
473
                 the asymmetric range of years.  */
474
              int adjust = iso_year_adjust (tim_p);
475
              int year = tim_p->tm_year >= 0 ? tim_p->tm_year % 100
476
                : abs (tim_p->tm_year + YEAR_BASE) % 100;
477
              if (adjust < 0 && tim_p->tm_year <= -YEAR_BASE)
478
                adjust = 1;
479
              else if (adjust > 0 && tim_p->tm_year < -YEAR_BASE)
480
                adjust = -1;
481
              sprintf (&s[count], "%.2d",
482
                       ((year + adjust) % 100 + 100) % 100);
483
              count += 2;
484
            }
485
          else
486
            return 0;
487
          break;
488
        case 'G':
489
          {
490
            /* See the comments for 'C' and 'Y'; this is a variable length
491
               field.  Although there is no requirement for a minimum number
492
               of digits, we use 4 for consistency with 'Y'.  */
493
            int neg = tim_p->tm_year < -YEAR_BASE;
494
            int adjust = iso_year_adjust (tim_p);
495
            int century = tim_p->tm_year >= 0
496
              ? tim_p->tm_year / 100 + YEAR_BASE / 100
497
              : abs (tim_p->tm_year + YEAR_BASE) / 100;
498
            int year = tim_p->tm_year >= 0 ? tim_p->tm_year % 100
499
              : abs (tim_p->tm_year + YEAR_BASE) % 100;
500
            if (adjust < 0 && tim_p->tm_year <= -YEAR_BASE)
501
              neg = adjust = 1;
502
            else if (adjust > 0 && neg)
503
              adjust = -1;
504
            year += adjust;
505
            if (year == -1)
506
              {
507
                year = 99;
508
                --century;
509
              }
510
            else if (year == 100)
511
              {
512
                year = 0;
513
                ++century;
514
              }
515
            count += snprintf (&s[count], maxsize - count, "%s%.*d%.2d",
516
                               neg ? "-" : "", 2 - neg, century, year);
517
            if (count >= maxsize)
518
              return 0;
519
          }
520
          break;
521
        case 'H':
522
        case 'k':
523
          if (count < maxsize - 2)
524
            {
525
              sprintf (&s[count], *format == 'k' ? "%2d" : "%.2d",
526
                       tim_p->tm_hour);
527
              count += 2;
528
            }
529
          else
530
            return 0;
531
          break;
532
        case 'I':
533
        case 'l':
534
          if (count < maxsize - 2)
535
            {
536
              if (tim_p->tm_hour == 0 ||
537
                  tim_p->tm_hour == 12)
538
                {
539
                  s[count++] = '1';
540
                  s[count++] = '2';
541
                }
542
              else
543
                {
544
                  sprintf (&s[count], *format == 'I' ? "%.2d" : "%2d",
545
                           tim_p->tm_hour % 12);
546
                  count += 2;
547
                }
548
            }
549
          else
550
            return 0;
551
          break;
552
        case 'j':
553
          if (count < maxsize - 3)
554
            {
555
              sprintf (&s[count], "%.3d",
556
                       tim_p->tm_yday + 1);
557
              count += 3;
558
            }
559
          else
560
            return 0;
561
          break;
562
        case 'm':
563
          if (count < maxsize - 2)
564
            {
565
              sprintf (&s[count], "%.2d",
566
                       tim_p->tm_mon + 1);
567
              count += 2;
568
            }
569
          else
570
            return 0;
571
          break;
572
        case 'M':
573
          if (count < maxsize - 2)
574
            {
575
              sprintf (&s[count], "%.2d",
576
                       tim_p->tm_min);
577
              count += 2;
578
            }
579
          else
580
            return 0;
581
          break;
582
        case 'n':
583
          if (count < maxsize - 1)
584
            s[count++] = '\n';
585
          else
586
            return 0;
587
          break;
588
        case 'p':
589
          if (count < maxsize - 2)
590
            {
591
              if (tim_p->tm_hour < 12)
592
                s[count++] = 'A';
593
              else
594
                s[count++] = 'P';
595
 
596
              s[count++] = 'M';
597
            }
598
          else
599
            return 0;
600
          break;
601
        case 'r':
602
          if (count < maxsize - 11)
603
            {
604
              if (tim_p->tm_hour == 0 ||
605
                  tim_p->tm_hour == 12)
606
                {
607
                  s[count++] = '1';
608
                  s[count++] = '2';
609
                }
610
              else
611
                {
612
                  sprintf (&s[count], "%.2d", tim_p->tm_hour % 12);
613
                  count += 2;
614
                }
615
              s[count++] = ':';
616
              sprintf (&s[count], "%.2d",
617
                       tim_p->tm_min);
618
              count += 2;
619
              s[count++] = ':';
620
              sprintf (&s[count], "%.2d",
621
                       tim_p->tm_sec);
622
              count += 2;
623
              s[count++] = ' ';
624
              if (tim_p->tm_hour < 12)
625
                s[count++] = 'A';
626
              else
627
                s[count++] = 'P';
628
 
629
              s[count++] = 'M';
630
            }
631
          else
632
            return 0;
633
          break;
634
        case 'R':
635
          if (count < maxsize - 5)
636
            {
637
              sprintf (&s[count], "%.2d:%.2d", tim_p->tm_hour, tim_p->tm_min);
638
              count += 5;
639
            }
640
          else
641
            return 0;
642
          break;
643
        case 'S':
644
          if (count < maxsize - 2)
645
            {
646
              sprintf (&s[count], "%.2d",
647
                       tim_p->tm_sec);
648
              count += 2;
649
            }
650
          else
651
            return 0;
652
          break;
653
        case 't':
654
          if (count < maxsize - 1)
655
            s[count++] = '\t';
656
          else
657
            return 0;
658
          break;
659
        case 'T':
660
        case 'X':
661
          if (count < maxsize - 8)
662
            {
663
              sprintf (&s[count], "%.2d:%.2d:%.2d", tim_p->tm_hour,
664
                       tim_p->tm_min, tim_p->tm_sec);
665
              count += 8;
666
            }
667
          else
668
            return 0;
669
          break;
670
        case 'u':
671
          if (count < maxsize - 1)
672
            {
673
              if (tim_p->tm_wday == 0)
674
                s[count++] = '7';
675
              else
676
                s[count++] = '0' + tim_p->tm_wday;
677
            }
678
          else
679
            return 0;
680
          break;
681
        case 'U':
682
          if (count < maxsize - 2)
683
            {
684
              sprintf (&s[count], "%.2d",
685
                       (tim_p->tm_yday + 7 -
686
                        tim_p->tm_wday) / 7);
687
              count += 2;
688
            }
689
          else
690
            return 0;
691
          break;
692
        case 'V':
693
          if (count < maxsize - 2)
694
            {
695
              int adjust = iso_year_adjust (tim_p);
696
              int wday = (tim_p->tm_wday) ? tim_p->tm_wday - 1 : 6;
697
              int week = (tim_p->tm_yday + 10 - wday) / 7;
698
              if (adjust > 0)
699
                week = 1;
700
              else if (adjust < 0)
701
                /* Previous year has 53 weeks if current year starts on
702
                   Fri, and also if current year starts on Sat and
703
                   previous year was leap year.  */
704
                week = 52 + (4 >= (wday - tim_p->tm_yday
705
                                   - isleap (tim_p->tm_year
706
                                             + (YEAR_BASE - 1
707
                                                - (tim_p->tm_year < 0
708
                                                   ? 0 : 2000)))));
709
              sprintf (&s[count], "%.2d", week);
710
              count += 2;
711
            }
712
          else
713
            return 0;
714
          break;
715
        case 'w':
716
          if (count < maxsize - 1)
717
            s[count++] = '0' + tim_p->tm_wday;
718
          else
719
            return 0;
720
          break;
721
        case 'W':
722
          if (count < maxsize - 2)
723
            {
724
              int wday = (tim_p->tm_wday) ? tim_p->tm_wday - 1 : 6;
725
              sprintf (&s[count], "%.2d",
726
                       (tim_p->tm_yday + 7 - wday) / 7);
727
              count += 2;
728
            }
729
          else
730
            return 0;
731
          break;
732
        case 'y':
733
          if (count < maxsize - 2)
734
            {
735
              /* Be careful of both overflow and negative years, thanks to
736
                 the asymmetric range of years.  */
737
              int year = tim_p->tm_year >= 0 ? tim_p->tm_year % 100
738
                : abs (tim_p->tm_year + YEAR_BASE) % 100;
739
              sprintf (&s[count], "%.2d", year);
740
              count += 2;
741
            }
742
          else
743
            return 0;
744
          break;
745
        case 'Y':
746
          {
747
            /* Length is not known because of %C%y, so recurse. */
748
            size_t adjust = strftime (&s[count], maxsize - count,
749
                                      "%C%y", tim_p);
750
            if (adjust > 0)
751
              count += adjust;
752
            else
753
              return 0;
754
          }
755
          break;
756
        case 'z':
757
          if (tim_p->tm_isdst >= 0)
758
            {
759
              if (count < maxsize - 5)
760
                {
761
                  long offset;
762
                  __tzinfo_type *tz = __gettzinfo ();
763
                  TZ_LOCK;
764
                  /* The sign of this is exactly opposite the envvar TZ.  We
765
                     could directly use the global _timezone for tm_isdst==0,
766
                     but have to use __tzrule for daylight savings.  */
767
                  offset = -tz->__tzrule[tim_p->tm_isdst > 0].offset;
768
                  TZ_UNLOCK;
769
                  sprintf (&s[count], "%+03ld%.2ld", offset / SECSPERHOUR,
770
                           labs (offset / SECSPERMIN) % 60L);
771
                  count += 5;
772
                }
773
              else
774
                return 0;
775
            }
776
          break;
777
        case 'Z':
778
          if (tim_p->tm_isdst >= 0)
779
            {
780
              int size;
781
              TZ_LOCK;
782
              size = strlen(_tzname[tim_p->tm_isdst > 0]);
783
              for (i = 0; i < size; i++)
784
                {
785
                  if (count < maxsize - 1)
786
                    s[count++] = _tzname[tim_p->tm_isdst > 0][i];
787
                  else
788
                    {
789
                      TZ_UNLOCK;
790
                      return 0;
791
                    }
792
                }
793
              TZ_UNLOCK;
794
            }
795
          break;
796
        case '%':
797
          if (count < maxsize - 1)
798
            s[count++] = '%';
799
          else
800
            return 0;
801
          break;
802
        }
803
      if (*format)
804
        format++;
805
      else
806
        break;
807
    }
808
  if (maxsize)
809
    s[count] = '\0';
810
 
811
  return count;
812
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.