os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/compat/strftime.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* 
sl@0
     2
 * strftime.c --
sl@0
     3
 *
sl@0
     4
 *	This file contains a modified version of the BSD 4.4 strftime
sl@0
     5
 *	function.
sl@0
     6
 *
sl@0
     7
 * This file is a modified version of the strftime.c file from the BSD 4.4
sl@0
     8
 * source.  See the copyright notice below for details on redistribution
sl@0
     9
 * restrictions.  The "license.terms" file does not apply to this file.
sl@0
    10
 *
sl@0
    11
 * Changes 2002 Copyright (c) 2002 ActiveState Corporation.
sl@0
    12
 *
sl@0
    13
 * RCS: @(#) $Id: strftime.c,v 1.10.2.3 2005/11/04 18:18:04 kennykb Exp $
sl@0
    14
 */
sl@0
    15
sl@0
    16
/*
sl@0
    17
 * Copyright (c) 1989 The Regents of the University of California.
sl@0
    18
 * All rights reserved.
sl@0
    19
 *
sl@0
    20
 * Redistribution and use in source and binary forms, with or without
sl@0
    21
 * modification, are permitted provided that the following conditions
sl@0
    22
 * are met:
sl@0
    23
 * 1. Redistributions of source code must retain the above copyright
sl@0
    24
 *    notice, this list of conditions and the following disclaimer.
sl@0
    25
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    26
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    27
 *    documentation and/or other materials provided with the distribution.
sl@0
    28
 * 3. All advertising materials mentioning features or use of this software
sl@0
    29
 *    must display the following acknowledgement:
sl@0
    30
 *	This product includes software developed by the University of
sl@0
    31
 *	California, Berkeley and its contributors.
sl@0
    32
 * 4. Neither the name of the University nor the names of its contributors
sl@0
    33
 *    may be used to endorse or promote products derived from this software
sl@0
    34
 *    without specific prior written permission.
sl@0
    35
 *
sl@0
    36
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
sl@0
    37
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    38
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sl@0
    39
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
sl@0
    40
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sl@0
    41
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sl@0
    42
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    43
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
sl@0
    44
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
sl@0
    45
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
sl@0
    46
 * SUCH DAMAGE.
sl@0
    47
 */
sl@0
    48
sl@0
    49
#if defined(LIBC_SCCS)
sl@0
    50
static char *rcsid = "$Id: strftime.c,v 1.10.2.3 2005/11/04 18:18:04 kennykb Exp $";
sl@0
    51
#endif /* LIBC_SCCS */
sl@0
    52
sl@0
    53
#include <time.h>
sl@0
    54
#include <string.h>
sl@0
    55
#include <locale.h>
sl@0
    56
#include "tclInt.h"
sl@0
    57
#include "tclPort.h"
sl@0
    58
sl@0
    59
#define TM_YEAR_BASE   1900
sl@0
    60
#define IsLeapYear(x)   ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
sl@0
    61
sl@0
    62
typedef struct {
sl@0
    63
    const char *abday[7];
sl@0
    64
    const char *day[7];
sl@0
    65
    const char *abmon[12];
sl@0
    66
    const char *mon[12];
sl@0
    67
    const char *am_pm[2];
sl@0
    68
    const char *d_t_fmt;
sl@0
    69
    const char *d_fmt;
sl@0
    70
    const char *t_fmt;
sl@0
    71
    const char *t_fmt_ampm;
sl@0
    72
} _TimeLocale;
sl@0
    73
sl@0
    74
/*
sl@0
    75
 * This is the C locale default.  On Windows, if we wanted to make this
sl@0
    76
 * localized, we would use GetLocaleInfo to get the correct values.
sl@0
    77
 * It may be acceptable to do localization of month/day names, as the
sl@0
    78
 * numerical values would be considered the locale-independent versions.
sl@0
    79
 */
sl@0
    80
static const _TimeLocale _DefaultTimeLocale = 
sl@0
    81
{
sl@0
    82
    {
sl@0
    83
	"Sun","Mon","Tue","Wed","Thu","Fri","Sat",
sl@0
    84
    },
sl@0
    85
    {
sl@0
    86
	"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
sl@0
    87
	"Friday", "Saturday"
sl@0
    88
    },
sl@0
    89
    {
sl@0
    90
	"Jan", "Feb", "Mar", "Apr", "May", "Jun",
sl@0
    91
	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
sl@0
    92
    },
sl@0
    93
    {
sl@0
    94
	"January", "February", "March", "April", "May", "June", "July",
sl@0
    95
	"August", "September", "October", "November", "December"
sl@0
    96
    },
sl@0
    97
    {
sl@0
    98
	"AM", "PM"
sl@0
    99
    },
sl@0
   100
    "%a %b %d %H:%M:%S %Y",
sl@0
   101
    "%m/%d/%y",
sl@0
   102
    "%H:%M:%S",
sl@0
   103
    "%I:%M:%S %p"
sl@0
   104
};
sl@0
   105
sl@0
   106
static const _TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale;
sl@0
   107
sl@0
   108
static int isGMT;
sl@0
   109
static size_t gsize;
sl@0
   110
static char *pt;
sl@0
   111
static int		 _add _ANSI_ARGS_((const char* str));
sl@0
   112
static int		_conv _ANSI_ARGS_((int n, int digits, int pad));
sl@0
   113
static int		_secs _ANSI_ARGS_((const struct tm *t));
sl@0
   114
static size_t		_fmt _ANSI_ARGS_((const char *format,
sl@0
   115
			    const struct tm *t));
sl@0
   116
static int ISO8601Week _ANSI_ARGS_((CONST struct tm* t, int *year ));
sl@0
   117
sl@0
   118
size_t
sl@0
   119
TclpStrftime(s, maxsize, format, t, useGMT)
sl@0
   120
    char *s;
sl@0
   121
    size_t maxsize;
sl@0
   122
    const char *format;
sl@0
   123
    const struct tm *t;
sl@0
   124
    int useGMT;
sl@0
   125
{
sl@0
   126
    if (format[0] == '%' && format[1] == 'Q') {
sl@0
   127
	/* Format as a stardate */
sl@0
   128
	sprintf(s, "Stardate %2d%03d.%01d",
sl@0
   129
		(((t->tm_year + TM_YEAR_BASE) + 377) - 2323),
sl@0
   130
		(((t->tm_yday + 1) * 1000) /
sl@0
   131
			(365 + IsLeapYear((t->tm_year + TM_YEAR_BASE)))),
sl@0
   132
		(((t->tm_hour * 60) + t->tm_min)/144));
sl@0
   133
	return(strlen(s));
sl@0
   134
    }
sl@0
   135
sl@0
   136
    isGMT = useGMT;
sl@0
   137
    /*
sl@0
   138
     * We may be able to skip this for useGMT, but it should be harmless.
sl@0
   139
     * -- hobbs
sl@0
   140
     */
sl@0
   141
    tzset();
sl@0
   142
sl@0
   143
    pt = s;
sl@0
   144
    if ((gsize = maxsize) < 1)
sl@0
   145
	return(0);
sl@0
   146
    if (_fmt(format, t)) {
sl@0
   147
	*pt = '\0';
sl@0
   148
	return(maxsize - gsize);
sl@0
   149
    }
sl@0
   150
    return(0);
sl@0
   151
}
sl@0
   152
sl@0
   153
#define SUN_WEEK(t)	(((t)->tm_yday + 7 - \
sl@0
   154
				((t)->tm_wday)) / 7)
sl@0
   155
#define MON_WEEK(t)	(((t)->tm_yday + 7 - \
sl@0
   156
				((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
sl@0
   157
sl@0
   158
static size_t
sl@0
   159
_fmt(format, t)
sl@0
   160
    const char *format;
sl@0
   161
    const struct tm *t;
sl@0
   162
{
sl@0
   163
#ifdef WIN32
sl@0
   164
#define BUF_SIZ 256
sl@0
   165
    TCHAR buf[BUF_SIZ];
sl@0
   166
    SYSTEMTIME syst = {
sl@0
   167
	t->tm_year + 1900,
sl@0
   168
	t->tm_mon + 1,
sl@0
   169
	t->tm_wday,
sl@0
   170
	t->tm_mday,
sl@0
   171
	t->tm_hour,
sl@0
   172
	t->tm_min,
sl@0
   173
	t->tm_sec,
sl@0
   174
	0,
sl@0
   175
    };
sl@0
   176
#endif
sl@0
   177
    for (; *format; ++format) {
sl@0
   178
	if (*format == '%') {
sl@0
   179
	    ++format;
sl@0
   180
	    if (*format == 'E') {
sl@0
   181
				/* Alternate Era */
sl@0
   182
		++format;
sl@0
   183
	    } else if (*format == 'O') {
sl@0
   184
				/* Alternate numeric symbols */
sl@0
   185
		++format;
sl@0
   186
	    }
sl@0
   187
	    switch(*format) {
sl@0
   188
		case '\0':
sl@0
   189
		    --format;
sl@0
   190
		    break;
sl@0
   191
		case 'A':
sl@0
   192
		    if (t->tm_wday < 0 || t->tm_wday > 6)
sl@0
   193
			return(0);
sl@0
   194
		    if (!_add(_CurrentTimeLocale->day[t->tm_wday]))
sl@0
   195
			return(0);
sl@0
   196
		    continue;
sl@0
   197
		case 'a':
sl@0
   198
		    if (t->tm_wday < 0 || t->tm_wday > 6)
sl@0
   199
			return(0);
sl@0
   200
		    if (!_add(_CurrentTimeLocale->abday[t->tm_wday]))
sl@0
   201
			return(0);
sl@0
   202
		    continue;
sl@0
   203
		case 'B':
sl@0
   204
		    if (t->tm_mon < 0 || t->tm_mon > 11)
sl@0
   205
			return(0);
sl@0
   206
		    if (!_add(_CurrentTimeLocale->mon[t->tm_mon]))
sl@0
   207
			return(0);
sl@0
   208
		    continue;
sl@0
   209
		case 'b':
sl@0
   210
		case 'h':
sl@0
   211
		    if (t->tm_mon < 0 || t->tm_mon > 11)
sl@0
   212
			return(0);
sl@0
   213
		    if (!_add(_CurrentTimeLocale->abmon[t->tm_mon]))
sl@0
   214
			return(0);
sl@0
   215
		    continue;
sl@0
   216
		case 'C':
sl@0
   217
		    if (!_conv((t->tm_year + TM_YEAR_BASE) / 100,
sl@0
   218
			    2, '0'))
sl@0
   219
			return(0);
sl@0
   220
		    continue;
sl@0
   221
		case 'D':
sl@0
   222
		    if (!_fmt("%m/%d/%y", t))
sl@0
   223
			return(0);
sl@0
   224
		    continue;
sl@0
   225
		case 'd':
sl@0
   226
		    if (!_conv(t->tm_mday, 2, '0'))
sl@0
   227
			return(0);
sl@0
   228
		    continue;
sl@0
   229
		case 'e':
sl@0
   230
		    if (!_conv(t->tm_mday, 2, ' '))
sl@0
   231
			return(0);
sl@0
   232
		    continue;
sl@0
   233
	        case 'g':
sl@0
   234
		    {
sl@0
   235
			int year;
sl@0
   236
			ISO8601Week( t, &year );
sl@0
   237
			if ( !_conv( year%100, 2, '0' ) ) {
sl@0
   238
			    return( 0 );
sl@0
   239
			}
sl@0
   240
			continue;
sl@0
   241
		    }
sl@0
   242
	        case 'G':
sl@0
   243
		    {
sl@0
   244
			int year;
sl@0
   245
			ISO8601Week( t, &year );
sl@0
   246
			if ( !_conv( year, 4, '0' ) ) {
sl@0
   247
			    return( 0 );
sl@0
   248
			}
sl@0
   249
			continue;
sl@0
   250
		    }
sl@0
   251
		case 'H':
sl@0
   252
		    if (!_conv(t->tm_hour, 2, '0'))
sl@0
   253
			return(0);
sl@0
   254
		    continue;
sl@0
   255
		case 'I':
sl@0
   256
		    if (!_conv(t->tm_hour % 12 ?
sl@0
   257
			    t->tm_hour % 12 : 12, 2, '0'))
sl@0
   258
			return(0);
sl@0
   259
		    continue;
sl@0
   260
		case 'j':
sl@0
   261
		    if (!_conv(t->tm_yday + 1, 3, '0'))
sl@0
   262
			return(0);
sl@0
   263
		    continue;
sl@0
   264
		case 'k':
sl@0
   265
		    if (!_conv(t->tm_hour, 2, ' '))
sl@0
   266
			return(0);
sl@0
   267
		    continue;
sl@0
   268
		case 'l':
sl@0
   269
		    if (!_conv(t->tm_hour % 12 ?
sl@0
   270
			    t->tm_hour % 12: 12, 2, ' '))
sl@0
   271
			return(0);
sl@0
   272
		    continue;
sl@0
   273
		case 'M':
sl@0
   274
		    if (!_conv(t->tm_min, 2, '0'))
sl@0
   275
			return(0);
sl@0
   276
		    continue;
sl@0
   277
		case 'm':
sl@0
   278
		    if (!_conv(t->tm_mon + 1, 2, '0'))
sl@0
   279
			return(0);
sl@0
   280
		    continue;
sl@0
   281
		case 'n':
sl@0
   282
		    if (!_add("\n"))
sl@0
   283
			return(0);
sl@0
   284
		    continue;
sl@0
   285
		case 'p':
sl@0
   286
		    if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour >= 12]))
sl@0
   287
			return(0);
sl@0
   288
		    continue;
sl@0
   289
		case 'R':
sl@0
   290
		    if (!_fmt("%H:%M", t))
sl@0
   291
			return(0);
sl@0
   292
		    continue;
sl@0
   293
		case 'r':
sl@0
   294
		    if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t))
sl@0
   295
			return(0);
sl@0
   296
		    continue;
sl@0
   297
		case 'S':
sl@0
   298
		    if (!_conv(t->tm_sec, 2, '0'))
sl@0
   299
			return(0);
sl@0
   300
		    continue;
sl@0
   301
		case 's':
sl@0
   302
		    if (!_secs(t))
sl@0
   303
			return(0);
sl@0
   304
		    continue;
sl@0
   305
		case 'T':
sl@0
   306
		    if (!_fmt("%H:%M:%S", t))
sl@0
   307
			return(0);
sl@0
   308
		    continue;
sl@0
   309
		case 't':
sl@0
   310
		    if (!_add("\t"))
sl@0
   311
			return(0);
sl@0
   312
		    continue;
sl@0
   313
		case 'U':
sl@0
   314
		    if (!_conv(SUN_WEEK(t), 2, '0'))
sl@0
   315
			return(0);
sl@0
   316
		    continue;
sl@0
   317
		case 'u':
sl@0
   318
		    if (!_conv(t->tm_wday ? t->tm_wday : 7, 1, '0'))
sl@0
   319
			return(0);
sl@0
   320
		    continue;
sl@0
   321
		case 'V':
sl@0
   322
		{
sl@0
   323
		    int week = ISO8601Week( t, NULL );
sl@0
   324
		    if (!_conv(week, 2, '0'))
sl@0
   325
			return(0);
sl@0
   326
		    continue;
sl@0
   327
		}
sl@0
   328
		case 'W':
sl@0
   329
		    if (!_conv(MON_WEEK(t), 2, '0'))
sl@0
   330
			return(0);
sl@0
   331
		    continue;
sl@0
   332
		case 'w':
sl@0
   333
		    if (!_conv(t->tm_wday, 1, '0'))
sl@0
   334
			return(0);
sl@0
   335
		    continue;
sl@0
   336
#ifdef WIN32
sl@0
   337
		/*
sl@0
   338
		 * To properly handle the localized time routines on Windows,
sl@0
   339
		 * we must make use of the special localized calls.
sl@0
   340
		 */
sl@0
   341
		case 'c':
sl@0
   342
		    if (!GetDateFormat(LOCALE_USER_DEFAULT,
sl@0
   343
				       DATE_LONGDATE | LOCALE_USE_CP_ACP,
sl@0
   344
				       &syst, NULL, buf, BUF_SIZ)
sl@0
   345
			|| !_add(buf)
sl@0
   346
			|| !_add(" ")) {
sl@0
   347
			return(0);
sl@0
   348
		    }
sl@0
   349
		    /*
sl@0
   350
		     * %c is created with LONGDATE + " " + TIME on Windows,
sl@0
   351
		     * so continue to %X case here.
sl@0
   352
		     */
sl@0
   353
		case 'X':
sl@0
   354
		    if (!GetTimeFormat(LOCALE_USER_DEFAULT,
sl@0
   355
				       LOCALE_USE_CP_ACP,
sl@0
   356
				       &syst, NULL, buf, BUF_SIZ)
sl@0
   357
			|| !_add(buf)) {
sl@0
   358
			return(0);
sl@0
   359
		    }
sl@0
   360
		    continue;
sl@0
   361
		case 'x':
sl@0
   362
		    if (!GetDateFormat(LOCALE_USER_DEFAULT,
sl@0
   363
				       DATE_SHORTDATE | LOCALE_USE_CP_ACP,
sl@0
   364
				       &syst, NULL, buf, BUF_SIZ)
sl@0
   365
			|| !_add(buf)) {
sl@0
   366
			return(0);
sl@0
   367
		    }
sl@0
   368
		    continue;
sl@0
   369
#else
sl@0
   370
		case 'c':
sl@0
   371
		    if (!_fmt(_CurrentTimeLocale->d_t_fmt, t))
sl@0
   372
			return(0);
sl@0
   373
		    continue;
sl@0
   374
		case 'x':
sl@0
   375
		    if (!_fmt(_CurrentTimeLocale->d_fmt, t))
sl@0
   376
			return(0);
sl@0
   377
		    continue;
sl@0
   378
		case 'X':
sl@0
   379
		    if (!_fmt(_CurrentTimeLocale->t_fmt, t))
sl@0
   380
			return(0);
sl@0
   381
		    continue;
sl@0
   382
#endif
sl@0
   383
		case 'y':
sl@0
   384
		    if (!_conv((t->tm_year + TM_YEAR_BASE) % 100,
sl@0
   385
			    2, '0'))
sl@0
   386
			return(0);
sl@0
   387
		    continue;
sl@0
   388
		case 'Y':
sl@0
   389
		    if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0'))
sl@0
   390
			return(0);
sl@0
   391
		    continue;
sl@0
   392
		case 'Z': {
sl@0
   393
		    char *name = (isGMT ? "GMT" : TclpGetTZName(t->tm_isdst));
sl@0
   394
		    int wrote;
sl@0
   395
		    Tcl_UtfToExternal(NULL, NULL, name, -1, 0, NULL,
sl@0
   396
				      pt, gsize, NULL, &wrote, NULL);
sl@0
   397
		    pt += wrote;
sl@0
   398
		    gsize -= wrote;
sl@0
   399
		    continue;
sl@0
   400
		}
sl@0
   401
		case '%':
sl@0
   402
		    /*
sl@0
   403
		     * X311J/88-090 (4.12.3.5): if conversion char is
sl@0
   404
		     * undefined, behavior is undefined.  Print out the
sl@0
   405
		     * character itself as printf(3) does.
sl@0
   406
		     */
sl@0
   407
		default:
sl@0
   408
		    break;
sl@0
   409
	    }
sl@0
   410
	}
sl@0
   411
	if (!gsize--)
sl@0
   412
	    return(0);
sl@0
   413
	*pt++ = *format;
sl@0
   414
    }
sl@0
   415
    return(gsize);
sl@0
   416
}
sl@0
   417
sl@0
   418
static int
sl@0
   419
_secs(t)
sl@0
   420
    const struct tm *t;
sl@0
   421
{
sl@0
   422
    static char buf[15];
sl@0
   423
    register time_t s;
sl@0
   424
    register char *p;
sl@0
   425
    struct tm tmp;
sl@0
   426
sl@0
   427
    /* Make a copy, mktime(3) modifies the tm struct. */
sl@0
   428
    tmp = *t;
sl@0
   429
    s = mktime(&tmp);
sl@0
   430
    for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10)
sl@0
   431
	*p-- = (char)(s % 10 + '0');
sl@0
   432
    return(_add(++p));
sl@0
   433
}
sl@0
   434
sl@0
   435
static int
sl@0
   436
_conv(n, digits, pad)
sl@0
   437
    int n, digits;
sl@0
   438
    int pad;
sl@0
   439
{
sl@0
   440
    static char buf[10];
sl@0
   441
    register char *p;
sl@0
   442
sl@0
   443
    p = buf + sizeof( buf ) - 1;
sl@0
   444
    *p-- = '\0';
sl@0
   445
    if ( n == 0 ) {
sl@0
   446
	*p-- = '0'; --digits;
sl@0
   447
    } else {
sl@0
   448
	for (; n > 0 && p > buf; n /= 10, --digits)
sl@0
   449
	    *p-- = (char)(n % 10 + '0');
sl@0
   450
    }
sl@0
   451
    while (p > buf && digits-- > 0)
sl@0
   452
	*p-- = (char) pad;
sl@0
   453
    return(_add(++p));
sl@0
   454
}
sl@0
   455
sl@0
   456
static int
sl@0
   457
_add(str)
sl@0
   458
    const char *str;
sl@0
   459
{
sl@0
   460
    for (;; ++pt, --gsize) {
sl@0
   461
	if (!gsize)
sl@0
   462
	    return(0);
sl@0
   463
	if (!(*pt = *str++))
sl@0
   464
	    return(1);
sl@0
   465
    }
sl@0
   466
}
sl@0
   467
sl@0
   468
static int
sl@0
   469
ISO8601Week( t, year )
sl@0
   470
    CONST struct tm* t;
sl@0
   471
    int* year;
sl@0
   472
{
sl@0
   473
    /* Find the day-of-year of the Thursday in
sl@0
   474
     * the week in question. */
sl@0
   475
    
sl@0
   476
    int ydayThursday;
sl@0
   477
    int week;
sl@0
   478
    if ( t->tm_wday == 0 ) {
sl@0
   479
	ydayThursday = t->tm_yday - 3;
sl@0
   480
    } else {
sl@0
   481
	ydayThursday = t->tm_yday - t->tm_wday + 4;
sl@0
   482
    }
sl@0
   483
    
sl@0
   484
    if ( ydayThursday < 0 ) {
sl@0
   485
	
sl@0
   486
	/* This is the last week of the previous year. */
sl@0
   487
	if ( IsLeapYear(( t->tm_year + TM_YEAR_BASE - 1 )) ) {
sl@0
   488
	    ydayThursday += 366;
sl@0
   489
	} else {
sl@0
   490
	    ydayThursday += 365;
sl@0
   491
	}
sl@0
   492
	week = ydayThursday / 7 + 1;
sl@0
   493
	if ( year != NULL ) {
sl@0
   494
	    *year = t->tm_year + 1899;
sl@0
   495
	}
sl@0
   496
	
sl@0
   497
    } else if ( ( IsLeapYear(( t -> tm_year + TM_YEAR_BASE ))
sl@0
   498
		  && ydayThursday >= 366 )
sl@0
   499
		|| ( !IsLeapYear(( t -> tm_year
sl@0
   500
				   + TM_YEAR_BASE ))
sl@0
   501
		     && ydayThursday >= 365 ) ) {
sl@0
   502
	
sl@0
   503
	/* This is week 1 of the following year */
sl@0
   504
	
sl@0
   505
	week = 1;
sl@0
   506
	if ( year != NULL ) {
sl@0
   507
	    *year = t->tm_year + 1901;
sl@0
   508
	}
sl@0
   509
	
sl@0
   510
    } else {
sl@0
   511
	
sl@0
   512
	week = ydayThursday / 7 + 1;
sl@0
   513
	if ( year != NULL ) {
sl@0
   514
	    *year = t->tm_year + 1900;
sl@0
   515
	}
sl@0
   516
	
sl@0
   517
    }
sl@0
   518
sl@0
   519
    return week;
sl@0
   520
    
sl@0
   521
}