[project @ 1998-04-10 11:04:49 by simonm]
[ghc-hetmet.git] / ghc / lib / std / cbits / toLocalTime.c
1 /* 
2  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
3  *
4  * $Id: toLocalTime.c,v 1.1 1998/04/10 10:54:58 simonm Exp $
5  *
6  * toCalendarTime Runtime Support
7  */
8
9 #include "Rts.h"
10 #include "timezone.h"
11 #include "stgio.h"
12
13 StgAddr
14 toLocalTime(I_ size, StgByteArray d, StgByteArray res)
15 {
16     struct tm *tm,*tmp=(struct tm *)res;
17     time_t t;
18
19     switch(size) {
20         default:
21             return NULL;
22         case 0:
23             t = 0;
24             break;
25         case -1:
26             t = - (time_t) ((StgInt *)d)[0];
27             if (t > 0) 
28                 return NULL;
29             break;
30         case 1:
31             t = (time_t) ((StgInt *)d)[0];
32             if (t < 0) 
33                 return NULL;
34             break;
35         }
36     tm = localtime(&t);
37     
38     if (tm == NULL)
39         return NULL;
40
41     /*
42       localtime() may return a ptr to statically allocated storage,
43       so to make toLocalTime reentrant, we manually copy
44       the structure into the (struct tm *) passed in.
45     */
46     tmp->tm_sec    = tm->tm_sec;
47     tmp->tm_min    = tm->tm_min;
48     tmp->tm_hour   = tm->tm_hour;
49     tmp->tm_mday   = tm->tm_mday;
50     tmp->tm_mon    = tm->tm_mon;
51     tmp->tm_year   = tm->tm_year;
52     tmp->tm_wday   = tm->tm_wday;
53     tmp->tm_yday   = tm->tm_yday;
54     tmp->tm_isdst  = tm->tm_isdst;
55     /*
56       If you don't have tm_zone in (struct tm), but
57       you get at it via the shared tmzone[], you'll
58       lose. Same goes for the tm_gmtoff field.
59     
60     */
61 #if HAVE_TM_ZONE
62     strcpy(tmp->tm_zone,tm->tm_zone);
63     tmp->tm_gmtoff = tm->tm_gmtoff;
64 #endif
65
66     return (StgAddr)res;
67 }