[project @ 1998-12-02 13:17:09 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.3 1998/12/02 13:28:02 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 }
68
69 /* Note that we DO NOT return res as a result.
70  * res is typically a MutableByteArray and it seems very dubious
71  * to return a pointer into the middle of it.
72  */
73 StgInt prim_toLocalTime ( StgInt64 d, StgByteArray res)
74 {
75     struct tm *tm,*tmp=(struct tm *)res;
76     time_t t = (time_t) d;
77
78     if (t < 0) 
79         return 0;
80
81     tm = localtime(&t);
82     
83     if (tm == NULL)
84         return 0;
85
86     /*
87       localtime() may return a ptr to statically allocated storage,
88       so to make toLocalTime reentrant, we manually copy
89       the structure into the (struct tm *) passed in.
90     */
91     tmp->tm_sec    = tm->tm_sec;
92     tmp->tm_min    = tm->tm_min;
93     tmp->tm_hour   = tm->tm_hour;
94     tmp->tm_mday   = tm->tm_mday;
95     tmp->tm_mon    = tm->tm_mon;
96     tmp->tm_year   = tm->tm_year;
97     tmp->tm_wday   = tm->tm_wday;
98     tmp->tm_yday   = tm->tm_yday;
99     tmp->tm_isdst  = tm->tm_isdst;
100     /*
101       If you don't have tm_zone in (struct tm), but
102       you get at it via the shared tmzone[], you'll
103       lose. Same goes for the tm_gmtoff field.
104     
105     */
106 #if HAVE_TM_ZONE
107     strcpy(tmp->tm_zone,tm->tm_zone);
108     tmp->tm_gmtoff = tm->tm_gmtoff;
109 #endif
110
111     return 1;
112 }