natVMTimeZone.cc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // natVMTimeZone.cc -- Native side of VMTimeZone class.
  2. /* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
  3. Free Software Foundation
  4. This file is part of libgcj.
  5. This software is copyrighted work licensed under the terms of the
  6. Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
  7. details. */
  8. #include <config.h>
  9. #include <platform.h>
  10. #include <gcj/cni.h>
  11. #include <jvm.h>
  12. #include <java/util/VMTimeZone.h>
  13. #include <java/lang/Character.h>
  14. #include <java/lang/Integer.h>
  15. #include <stdio.h>
  16. #if TIME_WITH_SYS_TIME
  17. # include <sys/time.h>
  18. # include <time.h>
  19. #else
  20. # if HAVE_SYS_TIME_H
  21. # include <sys/time.h>
  22. # else
  23. # include <time.h>
  24. # endif
  25. #endif
  26. #include <string.h>
  27. /**
  28. * This method returns a time zone id string which is in the form
  29. * (standard zone name) or (standard zone name)(GMT offset) or
  30. * (standard zone name)(GMT offset)(daylight time zone name). The
  31. * GMT offset can be in seconds, or where it is evenly divisible by
  32. * 3600, then it can be in hours. The offset must be the time to
  33. * add to the local time to get GMT. If a offset is given and the
  34. * time zone observes daylight saving then the (daylight time zone
  35. * name) must also be given (otherwise it is assumed the time zone
  36. * does not observe any daylight savings).
  37. * <p>
  38. * The result of this method is given to getDefaultTimeZone(String)
  39. * which tries to map the time zone id to a known TimeZone. See
  40. * that method on how the returned String is mapped to a real
  41. * TimeZone object.
  42. */
  43. jstring
  44. java::util::VMTimeZone::getSystemTimeZoneId()
  45. {
  46. struct tm tim;
  47. #if !defined(HAVE_LOCALTIME_R) || !defined(_POSIX_PTHREAD_SEMANTICS)
  48. struct tm *lt_tim;
  49. #endif
  50. #ifdef HAVE_TM_ZONE
  51. int month;
  52. #endif
  53. time_t current_time;
  54. long tzoffset;
  55. const char *tz1, *tz2;
  56. char *tzid;
  57. time(&current_time);
  58. #if defined(HAVE_LOCALTIME_R) && defined(_POSIX_PTHREAD_SEMANTICS)
  59. localtime_r(&current_time, &tim);
  60. #else
  61. /* Fall back on non-thread safe localtime. */
  62. lt_tim = localtime(&current_time);
  63. memcpy(&tim, lt_tim, sizeof (struct tm));
  64. #endif
  65. mktime(&tim);
  66. #ifdef HAVE_TM_ZONE
  67. /* We will cycle through the months to make sure we hit dst. */
  68. month = tim.tm_mon;
  69. tz1 = tz2 = NULL;
  70. while (tz1 == NULL || tz2 == NULL)
  71. {
  72. if (tim.tm_isdst > 0)
  73. tz2 = tim.tm_zone;
  74. else if (tz1 == NULL)
  75. {
  76. tz1 = tim.tm_zone;
  77. month = tim.tm_mon;
  78. }
  79. if (tz1 == NULL || tz2 == NULL)
  80. {
  81. tim.tm_mon++;
  82. tim.tm_mon %= 12;
  83. }
  84. if (tim.tm_mon == month && tz2 == NULL)
  85. tz2 = "";
  86. else
  87. mktime(&tim);
  88. }
  89. /* We want to make sure the tm struct we use later on is not dst. */
  90. tim.tm_mon = month;
  91. mktime(&tim);
  92. #elif defined (HAVE_TZNAME)
  93. /* If dst is never used, tzname[1] is the empty string. */
  94. tzset();
  95. tz1 = tzname[0];
  96. tz2 = tzname[1];
  97. #else
  98. /* Some targets have no concept of timezones. Assume GMT without dst. */
  99. tz1 = "GMT";
  100. tz2 = "";
  101. #endif
  102. #ifdef STRUCT_TM_HAS_GMTOFF
  103. /* tm_gmtoff is the number of seconds that you must add to GMT to get
  104. local time, we need the number of seconds to add to the local time
  105. to get GMT. */
  106. tzoffset = -1L * tim.tm_gmtoff;
  107. #elif HAVE_UNDERSCORE_TIMEZONE
  108. tzoffset = _timezone;
  109. #elif HAVE_TIMEZONE
  110. /* timezone is secs WEST of UTC. */
  111. tzoffset = timezone;
  112. #else
  113. /* FIXME: there must be another global if neither tm_gmtoff nor timezone
  114. is available, esp. if tzname is valid.
  115. Richard Earnshaw <rearnsha@arm.com> has suggested using difftime to
  116. calculate between gmtime and localtime (and accounting for possible
  117. daylight savings time) as an alternative. */
  118. tzoffset = 0L;
  119. #endif
  120. if ((tzoffset % 3600) == 0)
  121. tzoffset = tzoffset / 3600;
  122. tzid = (char*) _Jv_Malloc (strlen(tz1) + strlen(tz2) + 6);
  123. sprintf(tzid, "%s%ld%s", tz1, tzoffset, tz2);
  124. jstring retval = JvNewStringUTF (tzid);
  125. _Jv_Free (tzid);
  126. return retval;
  127. }