1 /* VMTimeZone.c - Native method for java.util.VMTimeZone
2 Copyright (C) 1999, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
40 #if TIME_WITH_SYS_TIME
41 # include <sys/time.h>
45 # include <sys/time.h>
58 #include "java_util_VMTimeZone.h"
60 static size_t jint_to_charbuf (char *bufend
, jint num
);
63 * This method returns a time zone id string which is in the form
64 * (standard zone name) or (standard zone name)(GMT offset) or
65 * (standard zone name)(GMT offset)(daylight time zone name). The
66 * GMT offset can be in seconds, or where it is evenly divisible by
67 * 3600, then it can be in hours. The offset must be the time to
68 * add to the local time to get GMT. If a offset is given and the
69 * time zone observes daylight saving then the (daylight time zone
70 * name) must also be given (otherwise it is assumed the time zone
71 * does not observe any daylight savings).
73 * The result of this method is given to getDefaultTimeZone(String)
74 * which tries to map the time zone id to a known TimeZone. See
75 * that method on how the returned String is mapped to a real
78 JNIEXPORT jstring JNICALL
79 Java_java_util_VMTimeZone_getSystemTimeZoneId (JNIEnv
* env
,
81 __attribute__ ((__unused__
)))
84 #ifndef HAVE_LOCALTIME_R
92 const char *tz1
, *tz2
;
94 size_t tz1_len
, tz2_len
, tzoff_len
;
99 #ifdef HAVE_LOCALTIME_R
100 localtime_r (¤t_time
, &tim
);
102 /* Fall back on non-thread safe localtime. */
103 lt_tim
= localtime (¤t_time
);
104 memcpy (&tim
, lt_tim
, sizeof (struct tm
));
108 #ifdef HAVE_STRUCT_TM_TM_ZONE
109 /* We will cycle through the months to make sure we hit dst. */
112 while (tz1
== NULL
|| tz2
== NULL
)
114 if (tim
.tm_isdst
> 0)
116 else if (tz1
== NULL
)
122 if (tz1
== NULL
|| tz2
== NULL
)
128 if (tim
.tm_mon
== month
&& tz2
== NULL
)
133 /* We want to make sure the tm struct we use later on is not dst. */
136 #elif defined (HAVE_TZNAME)
137 /* If dst is never used, tzname[1] is the empty string. */
142 /* Some targets have no concept of timezones. Assume GMT without dst. */
147 #ifdef STRUCT_TM_HAS_GMTOFF
148 /* tm_gmtoff is the number of seconds that you must add to GMT to get
149 local time, we need the number of seconds to add to the local time
151 tzoffset
= -1L * tim
.tm_gmtoff
;
152 #elif HAVE_UNDERSCORE_TIMEZONE
153 /* On some systems _timezone is actually defined as time_t. */
154 tzoffset
= (long) _timezone
;
156 /* timezone is secs WEST of UTC. */
159 /* FIXME: there must be another global if neither tm_gmtoff nor timezone
160 is available, esp. if tzname is valid.
161 Richard Earnshaw <rearnsha@arm.com> has suggested using difftime to
162 calculate between gmtime and localtime (and accounting for possible
163 daylight savings time) as an alternative. */
167 if ((tzoffset
% 3600) == 0)
168 tzoffset
= tzoffset
/ 3600;
170 tz1_len
= strlen (tz1
);
171 tz2_len
= strlen (tz2
);
172 tzoff_len
= jint_to_charbuf (tzoff
+ 11, tzoffset
);
173 tzid
= (char *) malloc (tz1_len
+ tz2_len
+ tzoff_len
+ 1);
175 JCL_ThrowException (env
, "java/lang/OutOfMemoryError",
180 memcpy (tzid
, tz1
, tz1_len
);
181 memcpy (tzid
+ tz1_len
, tzoff
+ 11 - tzoff_len
, tzoff_len
);
182 memcpy (tzid
+ tz1_len
+ tzoff_len
, tz2
, tz2_len
);
183 tzid
[tz1_len
+ tzoff_len
+ tz2_len
] = '\0';
185 retval
= (*env
)->NewStringUTF (env
, tzid
);
191 /* Put printed (decimal) representation of NUM in a buffer.
192 BUFEND marks the end of the buffer, which must be at least 11 chars long.
193 Returns the COUNT of chars written. The result is in
194 (BUFEND - COUNT) (inclusive) upto (BUFEND) (exclusive).
196 Note that libgcj has a slightly different version called _Jv_FormatInt
197 that works on jchar buffers.
201 jint_to_charbuf (char *bufend
, jint num
)
203 register char *ptr
= bufend
;
211 /* Must be MIN_VALUE, so handle this special case.
212 FIXME use 'unsigned jint' for num. */
222 *--ptr
= (char) ((int) '0' + (num
% 10));