11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
25f564540a953a670925e058dabc521f68ffb997cElliott Hughes** Based on the UCB version with the copyright notice and sccsid
35f564540a953a670925e058dabc521f68ffb997cElliott Hughes** appearing below.
45f564540a953a670925e058dabc521f68ffb997cElliott Hughes**
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** This is ANSIish only when "multibyte character == plain character".
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "private.h"
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** Copyright (c) 1989 The Regents of the University of California.
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** All rights reserved.
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project**
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** Redistribution and use in source and binary forms are permitted
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** provided that the above copyright notice and this paragraph are
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** duplicated in all such forms and that any documentation,
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** advertising materials, and other materials related to such
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** distribution and use acknowledge that the software was developed
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** by the University of California, Berkeley. The name of the
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** University may not be used to endorse or promote products derived
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** from this software without specific prior written permission.
225f564540a953a670925e058dabc521f68ffb997cElliott Hughes** THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "tzfile.h"
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "fcntl.h"
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "locale.h"
305f564540a953a670925e058dabc521f68ffb997cElliott Hughes
315f564540a953a670925e058dabc521f68ffb997cElliott Hughes#if __ANDROID__
32905e6d58aaf515bf237e62078f8a321920fe4c6bElliott Hughes
33905e6d58aaf515bf237e62078f8a321920fe4c6bElliott Hughes/* LP32 had a 32-bit time_t, so we need to work around that here. */
3452defb7c702306d4e81c7089cbadd7a6da1d7b6bElliott Hughes#if defined(__LP64__)
3552defb7c702306d4e81c7089cbadd7a6da1d7b6bElliott Hughes#define time64_t time_t
3652defb7c702306d4e81c7089cbadd7a6da1d7b6bElliott Hughes#define mktime64 mktime
3752defb7c702306d4e81c7089cbadd7a6da1d7b6bElliott Hughes#else
38edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#include <time64.h>
3952defb7c702306d4e81c7089cbadd7a6da1d7b6bElliott Hughes#endif
40905e6d58aaf515bf237e62078f8a321920fe4c6bElliott Hughes
415f564540a953a670925e058dabc521f68ffb997cElliott Hughes#include <ctype.h>
42905e6d58aaf515bf237e62078f8a321920fe4c6bElliott Hughes
4339d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes#endif
44905e6d58aaf515bf237e62078f8a321920fe4c6bElliott Hughes
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct lc_time_T {
46edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *    mon[MONSPERYEAR];
47edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *    month[MONSPERYEAR];
48edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *    wday[DAYSPERWEEK];
49edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *    weekday[DAYSPERWEEK];
50edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *    X_fmt;
51edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *    x_fmt;
52edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *    c_fmt;
53edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *    am;
54edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *    pm;
55edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    const char *    date_fmt;
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project};
57edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
58edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define Locale  (&C_time_locale)
59edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
60edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Projectstatic const struct lc_time_T   C_time_locale = {
61edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    {
62edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
63edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
64edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    }, {
65edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "January", "February", "March", "April", "May", "June",
66edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "July", "August", "September", "October", "November", "December"
67edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    }, {
68edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Sun", "Mon", "Tue", "Wed",
69edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Thu", "Fri", "Sat"
70edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    }, {
71edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Sunday", "Monday", "Tuesday", "Wednesday",
72edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        "Thursday", "Friday", "Saturday"
73edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    },
74edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
75edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    /* X_fmt */
76edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    "%H:%M:%S",
77edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
78edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    /*
79edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    ** x_fmt
80edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    ** C99 requires this format.
81edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    ** Using just numbers (as here) makes Quakers happier;
82edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    ** it's also compatible with SVR4.
83edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    */
84edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    "%m/%d/%y",
85edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
86edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    /*
87edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    ** c_fmt
88edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    ** C99 requires this format.
89edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    ** Previously this code used "%D %X", but we now conform to C99.
90edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    ** Note that
91edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    **  "%a %b %d %H:%M:%S %Y"
92edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    ** is used by Solaris 2.3.
93edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    */
94edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    "%a %b %e %T %Y",
95edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
96edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    /* am */
97edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    "AM",
98edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
99edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    /* pm */
100edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    "PM",
101edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
102edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    /* date_fmt */
103edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    "%a %b %e %H:%M:%S %Z %Y"
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project};
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
106ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughesstatic char *   _add(const char *, char *, const char *, int);
107ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughesstatic char *   _conv(int, const char *, char *, const char *);
108ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughesstatic char *   _fmt(const char *, const struct tm *, char *, const char *,
10939d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes            int *);
1109fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughesstatic char *   _yconv(int, int, bool, bool, char *, const char *, int);
111ce4783ce76a4ef888466e02e4c6f3a0a3910bce8Elliott Hughesstatic char *   getformat(int, char *, char *, char *, char *);
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
113edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Projectextern char *   tzname[];
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef YEAR_2000_NAME
116edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define YEAR_2000_NAME  "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS"
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !defined YEAR_2000_NAME */
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
119edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define IN_NONE 0
120edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define IN_SOME 1
121edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define IN_THIS 2
122edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define IN_ALL  3
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define FORCE_LOWER_CASE 0x100
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsize_t
1279fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughesstrftime(char *s, size_t maxsize, const char *format, const struct tm *t)
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
129edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    char *  p;
130edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    int warn;
131edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
132edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    tzset();
133edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    warn = IN_NONE;
13439d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes    p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
1359a5a3e8e74e2c6d7850ab29711189acf0f7378a2Elliott Hughes#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
136edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
1379fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes        fprintf(stderr, "\n");
138edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        if (format == NULL)
1399fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes            fprintf(stderr, "NULL strftime format ");
1409fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes        else    fprintf(stderr, "strftime format \"%s\" ",
141edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                format);
1429fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes        fprintf(stderr, "yields only two digits of years in ");
143edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        if (warn == IN_SOME)
1449fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes            fprintf(stderr, "some locales");
145edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        else if (warn == IN_THIS)
1469fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes            fprintf(stderr, "the current locale");
1479fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes        else    fprintf(stderr, "all locales");
1489fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes        fprintf(stderr, "\n");
149edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    }
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */
151edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    if (p == s + maxsize)
152edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        return 0;
153edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    *p = '\0';
154edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    return p - s;
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char *getformat(int modifier, char *normal, char *underscore,
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                       char *dash, char *zero) {
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    switch (modifier) {
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    case '_':
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        return underscore;
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    case '-':
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        return dash;
1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    case '0':
1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        return zero;
1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    return normal;
1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char *
1719fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes_fmt(const char *format, const struct tm *t, char *pt,
1729fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes        const char *ptlim, int *warnp)
1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
174edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    for ( ; *format; ++format) {
175edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        if (*format == '%') {
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            int modifier = 0;
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectlabel:
178edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            switch (*++format) {
179edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case '\0':
180edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                --format;
181edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                break;
182edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'A':
183edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _add((t->tm_wday < 0 ||
184edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    t->tm_wday >= DAYSPERWEEK) ?
18539d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                    "?" : Locale->weekday[t->tm_wday],
186edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    pt, ptlim, modifier);
187edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
188edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'a':
189edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _add((t->tm_wday < 0 ||
190edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    t->tm_wday >= DAYSPERWEEK) ?
19139d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                    "?" : Locale->wday[t->tm_wday],
192edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    pt, ptlim, modifier);
193edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
194edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'B':
19539d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _add((t->tm_mon < 0 ||
196a48fa7f4deb6ba703e1da55143771476d4e668ceEric Fischer                                t->tm_mon >= MONSPERYEAR) ?
19739d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                                "?" : Locale->month[t->tm_mon],
198a48fa7f4deb6ba703e1da55143771476d4e668ceEric Fischer                                pt, ptlim, modifier);
199edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
200edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'b':
201edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'h':
202edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _add((t->tm_mon < 0 ||
203edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    t->tm_mon >= MONSPERYEAR) ?
20439d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                    "?" : Locale->mon[t->tm_mon],
205edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    pt, ptlim, modifier);
206edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
207edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'C':
208edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /*
209edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** %C used to do a...
210edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                **  _fmt("%a %b %e %X %Y", t);
211edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** ...whereas now POSIX 1003.2 calls for
212edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** something completely different.
213edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** (ado, 1993-05-24)
214edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                */
2159fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _yconv(t->tm_year, TM_YEAR_BASE,
2169fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    true, false, pt, ptlim, modifier);
217edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
218edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'c':
219edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                {
220edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                int warn2 = IN_SOME;
221edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
22239d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2);
223edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (warn2 == IN_ALL)
224edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    warn2 = IN_THIS;
225edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (warn2 > *warnp)
226edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    *warnp = warn2;
227edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                }
228edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
229edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'D':
23039d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                                pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
231edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
232edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'd':
2339fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                                pt = _conv(t->tm_mday, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
234edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
235edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'E':
236edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'O':
237edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /*
238edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** C99 locale modifiers.
239edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** The sequences
240edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                **  %Ec %EC %Ex %EX %Ey %EY
241edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                **  %Od %oe %OH %OI %Om %OM
242edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                **  %OS %Ou %OU %OV %Ow %OW %Oy
243edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** are supposed to provide alternate
244edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** representations.
245edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                */
246edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                goto label;
2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            case '_':
2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            case '-':
2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            case '0':
2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            case '^':
2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            case '#':
2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                modifier = *format;
2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                goto label;
254edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'e':
2559fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _conv(t->tm_mday, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
256edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
257edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'F':
25839d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
259edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
260edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'H':
2619fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _conv(t->tm_hour, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
262edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
263edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'I':
264edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _conv((t->tm_hour % 12) ?
265edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    (t->tm_hour % 12) : 12,
2669fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
267edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
268edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'j':
2699fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _conv(t->tm_yday + 1, getformat(modifier, "%03d", "%3d", "%d", "%03d"), pt, ptlim);
270edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
271edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'k':
272edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /*
273edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** This used to be...
274edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                **  _conv(t->tm_hour % 12 ?
275edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                **      t->tm_hour % 12 : 12, 2, ' ');
276edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** ...and has been changed to the below to
277edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** match SunOS 4.1.1 and Arnold Robbins'
278edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** strftime version 3.0. That is, "%k" and
279edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** "%l" have been swapped.
280edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** (ado, 1993-05-24)
281edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                */
2829fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _conv(t->tm_hour, getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
283edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef KITCHEN_SINK
285edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'K':
286edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /*
287edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** After all this time, still unclaimed!
288edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                */
28939d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _add("kitchen sink", pt, ptlim);
290edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* defined KITCHEN_SINK */
292edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'l':
293edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /*
294edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** This used to be...
295edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                **  _conv(t->tm_hour, 2, ' ');
296edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** ...and has been changed to the below to
297edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** match SunOS 4.1.1 and Arnold Robbin's
298edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** strftime version 3.0. That is, "%k" and
299edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** "%l" have been swapped.
300edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** (ado, 1993-05-24)
301edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                */
302edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _conv((t->tm_hour % 12) ?
303edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    (t->tm_hour % 12) : 12,
3049fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    getformat(modifier, "%2d", "%2d", "%d", "%02d"), pt, ptlim);
305edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
306edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'M':
3079fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _conv(t->tm_min, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
308edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
309edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'm':
3109fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _conv(t->tm_mon + 1, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
311edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
312edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'n':
313edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _add("\n", pt, ptlim, modifier);
314edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
315edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'P':
3169fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes            case 'p':
317edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ?
31839d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                    Locale->pm :
31939d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                    Locale->am,
3209fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    pt, ptlim, (*format == 'P') ? FORCE_LOWER_CASE : modifier);
321edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
322edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'R':
32339d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _fmt("%H:%M", t, pt, ptlim, warnp);
324edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
325edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'r':
32639d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
327edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
328edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'S':
3299fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _conv(t->tm_sec, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
330edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
331edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 's':
332edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                {
333edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    struct tm   tm;
334edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    char        buf[INT_STRLEN_MAXIMUM(
335edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                                time64_t) + 1];
336edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    time64_t    mkt;
337edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
338edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    tm = *t;
339edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    mkt = mktime64(&tm);
340edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    if (TYPE_SIGNED(time64_t))
3419fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                        snprintf(buf, sizeof(buf), "%"PRIdMAX,
3429fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                                 (intmax_t) mkt);
3439fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    else    snprintf(buf, sizeof(buf), "%"PRIuMAX,
3449fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                                     (uintmax_t) mkt);
345edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    pt = _add(buf, pt, ptlim, modifier);
346edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                }
347edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
348edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'T':
34939d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
350edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
351edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 't':
352edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _add("\t", pt, ptlim, modifier);
353edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
354edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'U':
355edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _conv((t->tm_yday + DAYSPERWEEK -
356edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    t->tm_wday) / DAYSPERWEEK,
3579fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
358edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
359edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'u':
360edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /*
361edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** From Arnold Robbins' strftime version 3.0:
362edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** "ISO 8601: Weekday as a decimal number
363edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** [1 (Monday) - 7]"
364edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** (ado, 1993-05-24)
365edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                */
366edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _conv((t->tm_wday == 0) ?
3679fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    DAYSPERWEEK : t->tm_wday,
3689fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    "%d", pt, ptlim);
369edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
370edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'V':   /* ISO 8601 week number */
371edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'G':   /* ISO 8601 year (four digits) */
372edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'g':   /* ISO 8601 year (two digits) */
3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** From Arnold Robbins' strftime version 3.0: "the week number of the
3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** year (the first Monday as the first day of week 1) as a decimal number
3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** (01-53)."
3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** (ado, 1993-05-24)
3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project**
37939d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes** From <http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html> by Markus Kuhn:
3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** "Week 01 of a year is per definition the first week which has the
3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** Thursday in this year, which is equivalent to the week which contains
3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** the fourth day of January. In other words, the first week of a new year
3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** is the week which has the majority of its days in the new year. Week 01
3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** might also contain days from the previous year and the week before week
3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** 01 of a year is the last week (52 or 53) of the previous year even if
3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** it contains days from the new year. A week starts with Monday (day 1)
3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** and ends with Sunday (day 7). For example, the first week of the year
3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** 1997 lasts from 1996-12-30 to 1997-01-05..."
3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** (ado, 1996-01-02)
3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/
391edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                {
392edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    int year;
393edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    int base;
394edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    int yday;
395edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    int wday;
396edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    int w;
397edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
398edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    year = t->tm_year;
399edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    base = TM_YEAR_BASE;
400edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    yday = t->tm_yday;
401edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    wday = t->tm_wday;
402edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    for ( ; ; ) {
403edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        int len;
404edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        int bot;
405edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        int top;
406edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
407edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        len = isleap_sum(year, base) ?
408edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            DAYSPERLYEAR :
409edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            DAYSPERNYEAR;
410edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        /*
411edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        ** What yday (-3 ... 3) does
412edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        ** the ISO year begin on?
413edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        */
414edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        bot = ((yday + 11 - wday) %
415edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            DAYSPERWEEK) - 3;
416edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        /*
417edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        ** What yday does the NEXT
418edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        ** ISO year begin on?
419edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        */
420edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        top = bot -
421edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            (len % DAYSPERWEEK);
422edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        if (top < -3)
423edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            top += DAYSPERWEEK;
424edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        top += len;
425edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        if (yday >= top) {
426edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            ++base;
427edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            w = 1;
428edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            break;
429edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        }
430edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        if (yday >= bot) {
431edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            w = 1 + ((yday - bot) /
432edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                                DAYSPERWEEK);
433edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            break;
434edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        }
435edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        --base;
436edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        yday += isleap_sum(year, base) ?
437edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            DAYSPERLYEAR :
438edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            DAYSPERNYEAR;
439edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    }
4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef XPG4_1994_04_09
441edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    if ((w == 52 &&
442edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        t->tm_mon == TM_JANUARY) ||
443edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        (w == 1 &&
444edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        t->tm_mon == TM_DECEMBER))
445edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            w = 53;
4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* defined XPG4_1994_04_09 */
447edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    if (*format == 'V')
4489fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                        pt = _conv(w, getformat(modifier, "%02d", "%2d", "%d", "%02d"),
449edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                               pt, ptlim);
450edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    else if (*format == 'g') {
451edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                        *warnp = IN_ALL;
4529fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                        pt = _yconv(year, base,
4539fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                            false, true,
454edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            pt, ptlim, modifier);
4559fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    } else  pt = _yconv(year, base,
4569fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                            true, true,
457edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                            pt, ptlim, modifier);
458edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                }
459edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
460edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'v':
461edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /*
462edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** From Arnold Robbins' strftime version 3.0:
463edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** "date as dd-bbb-YYYY"
464edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** (ado, 1993-05-24)
465edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                */
46639d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
467edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
468edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'W':
469edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _conv((t->tm_yday + DAYSPERWEEK -
470edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    (t->tm_wday ?
471edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    (t->tm_wday - 1) :
472edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    (DAYSPERWEEK - 1))) / DAYSPERWEEK,
4739fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
474edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
475edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'w':
476edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _conv(t->tm_wday, "%d", pt, ptlim);
477edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
478edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'X':
47939d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
480edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
481edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'x':
482edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                {
483edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                int warn2 = IN_SOME;
484edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
48539d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
486edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (warn2 == IN_ALL)
487edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    warn2 = IN_THIS;
488edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (warn2 > *warnp)
489edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    *warnp = warn2;
490edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                }
491edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
492edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'y':
493edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                *warnp = IN_ALL;
4949fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _yconv(t->tm_year, TM_YEAR_BASE,
4959fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    false, true,
496edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    pt, ptlim, modifier);
497edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
498edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'Y':
4999fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _yconv(t->tm_year, TM_YEAR_BASE,
5009fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                    true, true,
501edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    pt, ptlim, modifier);
502edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
503edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'Z':
5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef TM_ZONE
505a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                // BEGIN: Android-changed.
506a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                {
507a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                    const char* zone = t->TM_ZONE;
508a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                    if (!zone || !*zone) {
509a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                        // "The value of tm_isdst shall be positive if Daylight Savings Time is
510a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                        // in effect, 0 if Daylight Savings Time is not in effect, and negative
511a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                        // if the information is not available."
512a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                        if (t->tm_isdst == 0) zone = tzname[0];
513a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                        else if (t->tm_isdst > 0) zone = tzname[1];
514a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes
515a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                        // "Replaced by the timezone name or abbreviation, or by no bytes if no
516a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                        // timezone information exists."
517a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                        if (!zone || !*zone) zone = "";
518a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                    }
519a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                    pt = _add(zone, pt, ptlim, modifier);
520a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                }
521a9cac4c87a4ea3e6d1c0a1159909bf0e209a61a7Elliott Hughes                // END: Android-changed.
5229fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes#else
523edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (t->tm_isdst >= 0)
524edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    pt = _add(tzname[t->tm_isdst != 0],
5259fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                        pt, ptlim);
5269fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes#endif
527edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /*
528edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** C99 says that %Z must be replaced by the
529edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** empty string if the time zone is not
530edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** determinable.
531edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                */
532edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
533edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case 'z':
534edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                {
535e0d0b15de6eaee6c3975e13ad2b0e1238d0fdd8fElliott Hughes                long     diff;
536edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                char const *    sign;
537edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
538edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (t->tm_isdst < 0)
539edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    continue;
5401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef TM_GMTOFF
541edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                diff = t->TM_GMTOFF;
5421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* !defined TM_GMTOFF */
543edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                /*
544e0d0b15de6eaee6c3975e13ad2b0e1238d0fdd8fElliott Hughes                ** C99 says that the UT offset must
545edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** be computed by looking only at
546edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** tm_isdst. This requirement is
547edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** incorrect, since it means the code
548edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** must rely on magic (in this case
549edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** altzone and timezone), and the
550edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** magic might not have the correct
551edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** offset. Doing things correctly is
552edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** tricky and requires disobeying C99;
553edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** see GNU C strftime for details.
554edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** For now, punt and conform to the
555edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** standard, even though it's incorrect.
556edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                **
557edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** C99 says that %z must be replaced by the
558edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** empty string if the time zone is not
559edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** determinable, so output nothing if the
560edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                ** appropriate variables are not available.
561edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                */
562edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (t->tm_isdst == 0)
5631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef USG_COMPAT
564edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    diff = -timezone;
5651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* !defined USG_COMPAT */
566edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    continue;
5671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !defined USG_COMPAT */
568edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                else
5691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef ALTZONE
570edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    diff = -altzone;
5711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else /* !defined ALTZONE */
572edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    continue;
5731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !defined ALTZONE */
5741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* !defined TM_GMTOFF */
575edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                if (diff < 0) {
576edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    sign = "-";
577edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    diff = -diff;
578edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                } else  sign = "+";
579edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                pt = _add(sign, pt, ptlim, modifier);
580edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                diff /= SECSPERMIN;
581edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                diff = (diff / MINSPERHOUR) * 100 +
582edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                    (diff % MINSPERHOUR);
5839fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes                pt = _conv(diff, getformat(modifier, "%04d", "%4d", "%d", "%04d"), pt, ptlim);
584edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                }
585edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
586edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case '+':
58739d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                pt = _fmt(Locale->date_fmt, t, pt, ptlim,
58839d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes                    warnp);
589edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                continue;
590edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            case '%':
591edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            /*
592edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            ** X311J/88-090 (4.12.3.5): if conversion char is
593edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            ** undefined, behavior is undefined. Print out the
594edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            ** character itself as printf(3) also does.
595edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            */
596edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            default:
597edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project                break;
598edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            }
599edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        }
600edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        if (pt == ptlim)
601edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            break;
602edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        *pt++ = *format;
603edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    }
604edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    return pt;
6051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
6061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char *
6089fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes_conv(int n, const char *format, char *pt, const char *ptlim)
6091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
6109fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes	char	buf[INT_STRLEN_MAXIMUM(int) + 1];
6111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6129fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes	snprintf(buf, sizeof(buf), format, n);
6139fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes	return _add(buf, pt, ptlim, 0);
6141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
6151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char *
61739d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes_add(const char *str, char *pt, const char *const ptlim, int modifier)
6181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
6191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        int c;
6201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        switch (modifier) {
6221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        case FORCE_LOWER_CASE:
6231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                while (pt < ptlim && (*pt = tolower(*str++)) != '\0') {
6241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        ++pt;
6251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
6261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                break;
6271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        case '^':
6291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                while (pt < ptlim && (*pt = toupper(*str++)) != '\0') {
6301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        ++pt;
6311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
6321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                break;
6331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        case '#':
6351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                while (pt < ptlim && (c = *str++) != '\0') {
6361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        if (isupper(c)) {
6371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                                c = tolower(c);
6381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        } else if (islower(c)) {
6391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                                c = toupper(c);
6401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        }
6411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        *pt = c;
6421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        ++pt;
6431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
6441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                break;
6461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        default:
6481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                while (pt < ptlim && (*pt = *str++) != '\0') {
6491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        ++pt;
6501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                }
6511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
6521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
653edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    return pt;
6541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
6551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
6571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** POSIX and the C Standard are unclear or inconsistent about
6581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** what %C and %y do if the year is negative or exceeds 9999.
6591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** Use the convention that %C concatenated with %y yields the
6601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** same output as %Y, and that %Y contains at least 4 bytes,
6611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project** with more only if necessary.
6621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project*/
6631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
6641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char *
6659fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes_yconv(int a, int b, bool convert_top, bool convert_yy,
6669fb22a3ec4ec5217fc29bb3ee3a0f1076098151fElliott Hughes       char *pt, const char *ptlim, int modifier)
6671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
668edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    register int    lead;
669edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    register int    trail;
670edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project
671edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project#define DIVISOR 100
672edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    trail = a % DIVISOR + b % DIVISOR;
673edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR;
674edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    trail %= DIVISOR;
675edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    if (trail < 0 && lead > 0) {
676edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        trail += DIVISOR;
677edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        --lead;
678edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    } else if (lead < 0 && trail > 0) {
679edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        trail -= DIVISOR;
680edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        ++lead;
681edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    }
682edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    if (convert_top) {
683edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project        if (lead == 0 && trail < 0)
684edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project            pt = _add("-0", pt, ptlim, modifier);
68539d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes        else    pt = _conv(lead, getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
686edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    }
687edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    if (convert_yy)
68839d903aea901cd29a4eef3a82c2dbda59b5bc292Elliott Hughes        pt = _conv(((trail < 0) ? -trail : trail), getformat(modifier, "%02d", "%2d", "%d", "%02d"), pt, ptlim);
689edbe7fc97bab7ff0684053d1be564330689bf3adThe Android Open Source Project    return pt;
6901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
691