Sat Apr 20 17:07:17 1996 Ulrich Drepper <drepper@cygnus.com>
[kopensolaris-gnu/glibc.git] / time / localtime.c
1 /* Copyright (C) 1991, 1992, 1993, 1995 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB.  If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA.  */
18
19 #include <errno.h>
20 #include <time.h>
21
22 /* The C Standard says that localtime and gmtime return the same pointer.  */
23 struct tm _tmbuf;
24
25 /* Return the `struct tm' representation of *TIMER in the local timezone.  */
26 struct tm *
27 localtime (timer)
28      const time_t *timer;
29 {
30   return __localtime_r (timer, &_tmbuf);
31 }
32
33 struct tm *
34 __localtime_r (timer, tp)
35      const time_t *timer;
36      struct tm *tp;
37 {
38   extern int __use_tzfile;
39   extern int __tz_compute __P ((time_t timer, struct tm *tp));
40   extern int __tzfile_compute __P ((time_t timer,
41                                     long int *leap_correct, int *leap_hit));
42   long int leap_correction;
43   int leap_extra_secs;
44
45   if (timer == NULL)
46     {
47       errno = EINVAL;
48       return NULL;
49     }
50
51   {
52     /* Make sure the database is initialized.  */
53     extern int __tzset_run;
54     if (! __tzset_run)
55       __tzset ();
56   }
57
58   if (__use_tzfile)
59     {
60       if (! __tzfile_compute (*timer, &leap_correction, &leap_extra_secs))
61         return NULL;
62     }
63   else
64     {
65       struct tm *gmtp = __gmtime_r (timer, tp);
66       if (gmtp == NULL)
67         return NULL;
68
69       if (! __tz_compute (*timer, gmtp))
70         return NULL;
71
72       leap_correction = 0L;
73       leap_extra_secs = 0;
74     }
75
76   __offtime (timer, __timezone - leap_correction, tp);
77   tp->tm_sec += leap_extra_secs;
78   tp->tm_isdst = __daylight;
79   tp->tm_gmtoff = __timezone;
80   tp->tm_zone = __tzname[__daylight];
81   return tp;
82 }
83 weak_alias (__localtime_r, localtime_r)