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中,如果想修改系统启动后 ...
随机推荐
- 面试阿里,字节跳动90%会被问到的Java异常面试题集,史上最全系列!
Java异常架构与异常关键字 Java异常简介 Java异常是Java提供的一种识别及响应错误的一致性机制. Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程 ...
- 深度分析:面试90%被问到的 Session、Cookie、Token,看完这篇你就掌握了!
Cookie 和 Session HTTP 协议是一种无状态协议,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录:Session 和 Cookie 的主要目的 ...
- 如何将IDM中的进程设置进行备份
有时候我们想用浏览器自带的下载管理器进行下载,但是一点下载却被IDM(Internet Download Manager)自动嗅探捕获并下载,还有人因为重装系统使得之前更改IDM的设置都失效,只得重新 ...
- 看完这篇还不会 Elasticsearch 搜索,那我就哭了!
本文主要介绍 ElasticSearch 搜索相关的知识,首先会介绍下 URI Search 和 Request Body Search,同时也会学习什么是搜索的相关性,如何衡量相关性. Search ...
- Java基础教程——泛型
泛型 Generics:泛型,愿意指"无商标的". 泛型,可以理解为"宽泛的数据类型",就是将类型由原来的具体的类型泛化. 泛型在建立对象时不指定类中属性的具体 ...
- 干货分享:盘点那些最常用的Linux命令,需熟记!
- django搭建
1.进入终端使用虚拟环境安装---pip install django==2.2 2.创建新的工程django-admin startproject bookpro 3.创建app或模块 使用djan ...
- Kafka源码环境搭建
github地址:https://github.com/apache/kafka clone下来之后可以看到这样的项目结构: 文件目录说明. 目录 描述 bin Windows 和 Linux 下 K ...
- 蓝桥杯 调手表(bfs解法)
小明买了块高端大气上档次的电子手表,他正准备调时间呢. 在 M78 星云,时间的计量单位和地球上不同,M78 星云的一个小时有 n 分钟. 大家都知道,手表只有一个按钮可以把当前的数加一.在调分钟的时 ...
- 对称加密之---AES加密
工作中常会需要让数据传输前进行加密处理.这次用到的是AES加密.AES加密中,需要注意到坑还是挺多的.对AES也进行了一番了解,发现里面的东西真的是注意的太多了.今天只是整理了一种简单的加密格式,工作 ...