1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2006,2008 Oracle.  All rights reserved.
5 *
6 * $Id: localtime.c,v 1.10 2008/01/08 20:58:44 bostic Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13/*
14 * localtime --
15 *
16 * PUBLIC: #ifndef HAVE_LOCALTIME
17 * PUBLIC: struct tm *localtime __P((const time_t *));
18 * PUBLIC: #endif
19 */
20struct tm *
21localtime(tod)
22	const time_t *tod;
23{
24	JulianType jt;
25	boolean is_ds;					/* Daylight savings. */
26	time_t tt;
27	int increment;
28
29	/*
30	 * Berkeley DB uses POSIX time values internally, convert to a BREW
31	 * time value.
32	 */
33	is_ds = 0;
34	tt = *tod - BREW_EPOCH_OFFSET + LOCALTIMEOFFSET(&is_ds);
35
36	GETJULIANDATE(tt, &jt);
37
38	DB_GLOBAL(ltm).tm_sec = jt.wSecond;	/* seconds (0 - 60) */
39	DB_GLOBAL(ltm).tm_min = jt.wMinute;	/* minutes (0 - 59) */
40	DB_GLOBAL(ltm).tm_hour = jt.wHour;	/* hours (0 - 23) */
41	DB_GLOBAL(ltm).tm_mday = jt.wDay;	/* day of month (1 - 31) */
42	DB_GLOBAL(ltm).tm_mon = jt.wMonth - 1;	/* month of year (0 - 11) */
43						/* year - 1900 */
44	DB_GLOBAL(ltm).tm_year = jt.wYear - 1900;
45						/* day of week (Sunday = 0) */
46	DB_GLOBAL(ltm).tm_wday = (jt.wWeekDay + 1) % 7;
47						/* day of year (0 - 365) */
48	switch (DB_GLOBAL(ltm).tm_mon) {
49	default:
50	case  0: increment =   0; break;
51	case  1: increment =  31; break;
52	case  2: increment =  59; break;	/* Feb = 28 */
53	case  3: increment =  90; break;
54	case  4: increment = 120; break;
55	case  5: increment = 151; break;
56	case  6: increment = 181; break;
57	case  7: increment = 212; break;
58	case  8: increment = 243; break;
59	case  9: increment = 273; break;
60	case 10: increment = 304; break;
61	case 11: increment = 334; break;
62	}
63	DB_GLOBAL(ltm).tm_yday = increment + DB_GLOBAL(ltm).tm_mday - 1;
64
65	if (DB_GLOBAL(ltm).tm_mon > 1 &&	/* +1 leap years after Feb. */
66	    jt.wYear % 4 == 0 && (jt.wYear % 100 != 0 || jt.wYear % 400 == 0))
67		DB_GLOBAL(ltm).tm_yday += 1;
68
69	DB_GLOBAL(ltm).tm_isdst = is_ds;	/* daylight savings time */
70
71	/*
72	 * !!!
73	 * This routine is not thread-safe.  Berkeley DB should convert
74	 * to using localtime_r() where it's available, and this routine
75	 * should be re-written in the form of localtime_r().
76	 */
77	return (&DB_GLOBAL(ltm));
78}
79