summaryrefslogtreecommitdiff
path: root/ghc/lib/std/cbits/timezone.h
blob: aa28ea69d132ee3796f828f464ecd55ad890d8c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* 
 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
 *
 * $Id: timezone.h,v 1.9 1999/05/05 10:33:17 sof Exp $
 *
 * Time-zone support header
 */

#ifndef TIMEZONE_H
#define TIMEZONE_H

#define _OSF_SOURCE

#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#if linux_TARGET_OS
/* Sigh, RedHat 5 has the TM_ZONE stuff, but only when _BSD_SOURCE is
 * on.  The configure script erroneously says we've got TM_ZONE, so
 * make sure we use the TZNAME stuff instead.
 *
 * Aside: tzname is POSIX, whereas tm_zone is BSD.  We should be using
 *  tzname by preference, but the GNU configure stuff gives us HAVE_TM_ZONE
 *  in preference to HAVE_TZNAME.  More sighs.
 */
# undef  HAVE_TM_ZONE
# define HAVE_TZNAME  1

/* Double sigh.  The timezone variable is only available under Linux
 * when we're compiling NON_POSIX_SOURCE (or _GNU_SOURCE or whatever),
 * but to make that work we have to make sure NON_POSIX_SOURCE is
 * defined before anything from /usr/include is included.  To avoid
 * infecting too much source with NON_POSIX_SOURCE, we frob it
 * below...
 */
#undef HAVE_TIMEZONE

/* The correct solution to this problem would appear to be to ditch
 * the standard GNU configure tests for the time stuff, and hack up
 * our own that test for POSIX-compliant time support first, then
 * BSD-style time stuff.
 */
#endif

#ifdef solaris2_TARGET_OS
#undef HAVE_TIMEZONE
#endif

#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif

#if HAVE_TM_ZONE
#define ZONE(x)	         (((struct tm *)x)->tm_zone)
#define SETZONE(x,z)     (((struct tm *)x)->tm_zone = z)
#define GMTOFF(x)        (((struct tm *)x)->tm_gmtoff)
#else /* ! HAVE_TM_ZONE */
# if HAVE_TZNAME || _WIN32
#  if cygwin32_TARGET_OS
#   define tzname _tzname
#  endif
#  ifndef mingw32_TARGET_OS
extern char *tzname[2];
#  endif

#  define ZONE(x)	 (((struct tm *)x)->tm_isdst ? tzname[1] : tzname[0])
#  define SETZONE(x,z)
# else /* ! HAVE_TZNAME */
/* We're in trouble. If you should end up here, please report this as a bug. */
#  error Dont know how to get at timezone name on your OS.
# endif /* ! HAVE_TZNAME */
/* Get the offset in secs from UTC, if (struct tm) doesn't supply it. */

#ifdef mingw32_TARGET_OS
#define timezone _timezone
#else
# ifdef cygwin32_TARGET_OS
#  define timezone _timezone
# endif
#endif

#ifndef HAVE_TIMEZONE
extern TYPE_TIMEZONE timezone;
#endif

# if HAVE_ALTZONE
extern time_t altzone;
#  define GMTOFF(x)   	 (((struct tm *)x)->tm_isdst ? altzone : timezone )
# else /* ! HAVE_ALTZONE */
/* Assume that DST offset is 1 hour ... */
#  define GMTOFF(x) (((struct tm *)x)->tm_isdst ? (timezone - 3600) : timezone )
# endif /* ! HAVE_ALTZONE */
#endif  /* ! HAVE_TM_ZONE */

#endif /* TIMEZONE_H */