| // natVMTimeZone.cc -- Native side of VMTimeZone class. |
| |
| /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 |
| Free Software Foundation |
| |
| This file is part of libgcj. |
| |
| This software is copyrighted work licensed under the terms of the |
| Libgcj License. Please consult the file "LIBGCJ_LICENSE" for |
| details. */ |
| |
| #include <config.h> |
| #include <platform.h> |
| |
| #include <gcj/cni.h> |
| #include <jvm.h> |
| |
| #include <java/util/VMTimeZone.h> |
| #include <java/lang/Character.h> |
| #include <java/lang/Integer.h> |
| |
| #include <stdio.h> |
| |
| #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 |
| |
| #include <string.h> |
| |
| /** |
| * This method returns a time zone id string which is in the form |
| * (standard zone name) or (standard zone name)(GMT offset) or |
| * (standard zone name)(GMT offset)(daylight time zone name). The |
| * GMT offset can be in seconds, or where it is evenly divisible by |
| * 3600, then it can be in hours. The offset must be the time to |
| * add to the local time to get GMT. If a offset is given and the |
| * time zone observes daylight saving then the (daylight time zone |
| * name) must also be given (otherwise it is assumed the time zone |
| * does not observe any daylight savings). |
| * <p> |
| * The result of this method is given to getDefaultTimeZone(String) |
| * which tries to map the time zone id to a known TimeZone. See |
| * that method on how the returned String is mapped to a real |
| * TimeZone object. |
| */ |
| jstring |
| java::util::VMTimeZone::getSystemTimeZoneId() |
| { |
| struct tm tim; |
| #if !defined(HAVE_LOCALTIME_R) || !defined(_POSIX_PTHREAD_SEMANTICS) |
| struct tm *lt_tim; |
| #endif |
| #ifdef HAVE_TM_ZONE |
| int month; |
| #endif |
| time_t current_time; |
| long tzoffset; |
| const char *tz1, *tz2; |
| char *tzid; |
| |
| time(¤t_time); |
| #if defined(HAVE_LOCALTIME_R) && defined(_POSIX_PTHREAD_SEMANTICS) |
| localtime_r(¤t_time, &tim); |
| #else |
| /* Fall back on non-thread safe localtime. */ |
| lt_tim = localtime(¤t_time); |
| memcpy(&tim, lt_tim, sizeof (struct tm)); |
| #endif |
| mktime(&tim); |
| |
| #ifdef HAVE_TM_ZONE |
| /* We will cycle through the months to make sure we hit dst. */ |
| month = tim.tm_mon; |
| tz1 = tz2 = NULL; |
| while (tz1 == NULL || tz2 == NULL) |
| { |
| if (tim.tm_isdst > 0) |
| tz2 = tim.tm_zone; |
| else if (tz1 == NULL) |
| { |
| tz1 = tim.tm_zone; |
| month = tim.tm_mon; |
| } |
| |
| if (tz1 == NULL || tz2 == NULL) |
| { |
| tim.tm_mon++; |
| tim.tm_mon %= 12; |
| } |
| |
| if (tim.tm_mon == month && tz2 == NULL) |
| tz2 = ""; |
| else |
| mktime(&tim); |
| } |
| /* We want to make sure the tm struct we use later on is not dst. */ |
| tim.tm_mon = month; |
| mktime(&tim); |
| #elif defined (HAVE_TZNAME) |
| /* If dst is never used, tzname[1] is the empty string. */ |
| tzset(); |
| tz1 = tzname[0]; |
| tz2 = tzname[1]; |
| #else |
| /* Some targets have no concept of timezones. Assume GMT without dst. */ |
| tz1 = "GMT"; |
| tz2 = ""; |
| #endif |
| |
| #ifdef STRUCT_TM_HAS_GMTOFF |
| /* tm_gmtoff is the number of seconds that you must add to GMT to get |
| local time, we need the number of seconds to add to the local time |
| to get GMT. */ |
| tzoffset = -1L * tim.tm_gmtoff; |
| #elif HAVE_UNDERSCORE_TIMEZONE |
| tzoffset = _timezone; |
| #elif HAVE_TIMEZONE |
| /* timezone is secs WEST of UTC. */ |
| tzoffset = timezone; |
| #else |
| /* FIXME: there must be another global if neither tm_gmtoff nor timezone |
| is available, esp. if tzname is valid. |
| Richard Earnshaw <rearnsha@arm.com> has suggested using difftime to |
| calculate between gmtime and localtime (and accounting for possible |
| daylight savings time) as an alternative. */ |
| tzoffset = 0L; |
| #endif |
| |
| if ((tzoffset % 3600) == 0) |
| tzoffset = tzoffset / 3600; |
| |
| tzid = (char*) _Jv_Malloc (strlen(tz1) + strlen(tz2) + 6); |
| sprintf(tzid, "%s%ld%s", tz1, tzoffset, tz2); |
| jstring retval = JvNewStringUTF (tzid); |
| _Jv_Free (tzid); |
| |
| return retval; |
| } |