Java读取系统默认时区
工作中,遇到一个Java读取默认时区的问题,后来看了openjdk的源码,大致整理一下过程
public class Test {
public void test(){
TimeZone.getDefault();
}
}
TimeZone.getDefault()会跳到下面代码:
private static synchronized TimeZone setDefaultZone() {
TimeZone tz;
// get the time zone ID from the system properties
String zoneID = AccessController.doPrivileged(
new GetPropertyAction("user.timezone")); // if the time zone ID is not set (yet), perform the
// platform to Java time zone ID mapping.
if (zoneID == null || zoneID.isEmpty()) {
String javaHome = AccessController.doPrivileged(
new GetPropertyAction("java.home"));
try {
zoneID = getSystemTimeZoneID(javaHome);
if (zoneID == null) {
zoneID = GMT_ID;
}
} catch (NullPointerException e) {
zoneID = GMT_ID;
}
} // Get the time zone for zoneID. But not fall back to
// "GMT" here.
tz = getTimeZone(zoneID, false); if (tz == null) {
// If the given zone ID is unknown in Java, try to
// get the GMT-offset-based time zone ID,
// a.k.a. custom time zone ID (e.g., "GMT-08:00").
String gmtOffsetID = getSystemGMTOffsetID();
if (gmtOffsetID != null) {
zoneID = gmtOffsetID;
}
tz = getTimeZone(zoneID, true);
}
assert tz != null; final String id = zoneID;
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
System.setProperty("user.timezone", id);
return null;
}
}); defaultTimeZone = tz;
return tz;
}
如果没有设置时区的话,会进入一个native方法
zoneID = getSystemTimeZoneID(javaHome);
这个方法的实现,可以参考
openjdk-8u40-src-b25-10_feb_2015\openjdk\jdk\src\share\native\java\util\TimeZone.c
JNIEXPORT jstring JNICALL
Java_java_util_TimeZone_getSystemTimeZoneID(JNIEnv *env, jclass ign,
jstring java_home)
{
const char *java_home_dir;
char *javaTZ;
jstring jstrJavaTZ = NULL; CHECK_NULL_RETURN(java_home, NULL); java_home_dir = JNU_GetStringPlatformChars(env, java_home, 0);
CHECK_NULL_RETURN(java_home_dir, NULL); /*
* Invoke platform dependent mapping function
*/
javaTZ = findJavaTZ_md(java_home_dir);
if (javaTZ != NULL) {
jstrJavaTZ = JNU_NewStringPlatform(env, javaTZ);
free((void *)javaTZ);
} JNU_ReleaseStringPlatformChars(env, java_home, java_home_dir);
return jstrJavaTZ;
}
主要看:
javaTZ = findJavaTZ_md(java_home_dir);
继续参考,下面TimeZone_md.c文件,可以知道find_JavaTZ_md方法的实现
openjdk-8u40-src-b25-10_feb_2015\openjdk\jdk\src\solaris\native\java\util\TimeZone_md.c
char *
findJavaTZ_md(const char *java_home_dir)
{
char *tz;
char *javatz = NULL;
char *freetz = NULL; tz = getenv("TZ"); #if defined(__linux__) || defined(_ALLBSD_SOURCE)
if (tz == NULL) {
#else
#if defined (__solaris__) || defined(_AIX)
if (tz == NULL || *tz == '\0') {
#endif
#endif
tz = getPlatformTimeZoneID();
freetz = tz;
} /*
* Remove any preceding ':'
*/
if (tz != NULL && *tz == ':') {
tz++;
} #ifdef __solaris__
if (tz != NULL && strcmp(tz, "localtime") == 0) {
tz = getSolarisDefaultZoneID();
freetz = tz;
}
#endif if (tz != NULL) {
#ifdef __linux__
/*
* Ignore "posix/" prefix.
*/
if (strncmp(tz, "posix/", 6) == 0) {
tz += 6;
}
#endif
javatz = strdup(tz);
if (freetz != NULL) {
free((void *) freetz);
} #ifdef _AIX
freetz = mapPlatformToJavaTimezone(java_home_dir, javatz);
if (javatz != NULL) {
free((void *) javatz);
}
javatz = freetz;
#endif
} return javatz;
}
tz = getPlatformTimeZoneID(),这个函数内容,就不贴了,可以自己看下,总计起来,在Linux系统上,大概过程为以下几步:
1.先找“TZ”变量,没有,到2,
2.读/etc/timezone,没有到3,
3.比较/etc/localtime文件与"/usr/share/zoneinfo目录下所有时区文件,如果有一致的,就为该时区,如果没有,到4,
4.默认为标准GMT
如有不正确的地方,欢迎指正!
Java读取系统默认时区的更多相关文章
- flash 读取系统默认编码
java有类可以直接读取,但貌似flash没有. Charset.defaultCharset(); 但是浏览器里可以有. document.defaultCharset;//从当前的区域语言中获取默 ...
- 如何在Azure Websites中配置PHP从而改变系统默认时区
Shirley_Wang Tue, Mar 3 2015 7:29 AM Azure Website为我们提供了可高度扩展的网站部署平台.由于Website是PaaS(平台即服务)层的服务,当用户把 ...
- MTK 修改默认时区
首先介绍应用程序修改 : AlarmManager mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); mA ...
- Java用System读取系统相关信息、环境变量——(六)
package Java_Test; public class System1 { public static void main(String[] args) { // TODO Auto-gene ...
- Android系统移植与调试之------->如何修改Android的默认语言、默认时区
修改device/other/TBDG1073/ system.prop文件 1.设置默认语言 找到device/other/TBDG1073/ system.prop文件,修改属性ro.produc ...
- Android 系统默认参数的修改
转自: http://www.th7.cn/Program/Android/201505/447097.shtml 写在前面的话 一般在新项目开始之初,我们需要针对客户需求进行各种系统默认属性的配置, ...
- Java消息系统简单设计与实现
前言:由于导师在我的毕设项目里加了消息系统(本来想水水就过的..),没办法...来稍微研究研究吧..简单简单... 需求分析 我的毕设是一个博客系统,类似于简书这样的,所以消息系统也类似,在用户的消息 ...
- 通过系统自带的内容提供器(ContentResolver)读取系统的通讯录,并设置点击事件
1.布局 主布局只有一个listview,用来显示电话簿的名字和手机号码 <?xml version="1.0" encoding="utf-8"?> ...
- Android系统默认设置
修改Settings源码,可修改系统设置项,Settings数据被存放于com.android.providers.settings/databases/settings.db中,如果想修改系统启动后 ...
随机推荐
- [从源码学设计]蚂蚁金服SOFARegistry之网络封装和操作
[从源码学设计]蚂蚁金服SOFARegistry之网络封装和操作 目录 [从源码学设计]蚂蚁金服SOFARegistry之网络封装和操作 0x00 摘要 0x01 业务领域 1.1 SOFARegis ...
- 系统兼容软件CrossOver和虚拟机软件,哪个好用?
想要在Mac上运行Windows软件的方法有很多种,比较常见的有安装双系统以及虚拟机.但是安装双系统会导致一个很大的问题,就是占用了过多的硬盘空间,这样一来会导致可使用的空间减少. 目前来说,大家都不 ...
- symfony框架中使用service
在config文件里面的service.yml写入自己service 1 chat.group_list: //service的名字 2 class: Chat\Service\GroupListSe ...
- QQ账号测试用例
- harbor私有仓库部署
Harbor 简介 Harbor是构建企业级私有docker镜像的仓库的开源解决方案,它是Docker Registry的更高级封装,它除了提供友好的Web UI界面,角色和用户权限管理,用户 ...
- LeetCode 045 Jump Game II
题目要求:Jump Game II Given an array of non-negative integers, you are initially positioned at the first ...
- LeetCode 028 Implement strStr()
题目要求:Implement strStr() Implement strStr(). Returns the index of the first occurrence of needle in h ...
- UML第一次个人作业
这个作业属于哪个课程 https://api.jihuayu.site/cnblogs 这个作业要求在哪里 https://edu.cnblogs.com/campus/fzzcxy/2018SE1/ ...
- 小米ICPC第一场自闭记
这次终于找到了靠谱队友,比之前我做不出来==队友做不出来好太多了 昨天3人热身赛疯狂杀了8道题,感觉今天稳了 一开始就瞅了A题,发现似乎可以dp,看了看数据,1e7,大概想出了nsqrtn算法,想着肯 ...
- moviepy音视频剪辑:使用fl_time进行时间特效处理报错OSError: Error in file xxxx, Accessing time
☞ ░ 前往老猿Python博文目录 ░ 老猿在使用moviepy音视频剪辑的fl_time进行时间特效处理时,系统报错: OSError: Error in file F:\video\WinBas ...