你执行一下这段代码,看看输出是什么:Calendar c = Calendar.getInstance(); System.out.println(c.getTimeZone());如果正常的话,输出应该是:sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null]
to bao110908 谢谢,不过这种方法我已经试过了,改了时区之后,得到的系统时间还是格林威治时间
to bao110908sun.util.calendar.ZoneInfo[id="GMT",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]我郁闷啊
那就奇怪了,刚才看了一下 Windows JVM 的源代码,JVM 在初始化时没有设置过 user.timezone 属性:%OPEN_JDK_HOME%/jdk/src/windows/native/java/lang/java_props_md.c : Line.947/* User TIMEZONE */ { /* * We defer setting up timezone until it's actually necessary. * Refer to TimeZone.getDefault(). However, the system * property is necessary to be able to be set by the command * line interface -D. Here temporarily set a null string to * timezone. */ sprops.timezone = ""; }另外,JVM 所使用系统时区会通过 Win32 API 的 GetTimeZoneInformation 函数获得:#include <iostream> #include <windows.h>using namespace std;int main(int argc, char* argv[]) { TIME_ZONE_INFORMATION zoneInfo; setlocale(LC_ALL, ".936"); GetTimeZoneInformation(&zoneInfo); wprintf(L"Standard Name: %s\n", zoneInfo.StandardName); printf("Bias: %ld\n", zoneInfo.Bias); }上面代码,在我机器上输出:Standard Name: 中国标准时间 Bias: -480
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation我是win7,貌似只有这两个,另外那个搜索不到
会不会你的 jDk 不是 international 版本没带一些区域设置。
to bao110908 感谢解答按你的代码,输出为null但是那个目录下的tzmapping中,确实包含那三项
如果为 null 的话,至止已经完全排除了 Java 的问题,可以断定是 Windows 系统注册表的问题了。看一下系统注册表节点:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones 内部是否有 China Standard Time 子节点。再看一下 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation 节点中 StandardName 值是什么(Windows 6.0 及以上版本的查看 TimeZoneKeyName 值)在 http://jeremymurray.org/doku.php/blog 找到一段批处理程序,你执行一下看看输出是什么(复制成为 now.bat 文件,在控制台中执行):[code=BatchFile]@echo off setlocal FOR %%A IN (%Date%) do ( set CURRENTDATE=%%A )
for /f "tokens=1,2" %%A in ('time /t') do ( set CURRENTTIME=%%A %%B )set TIMEZONEKEYNAME= for /f "tokens=1,2*" %%K in ('reg query HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation') do ( if %%K==ActiveTimeBias set /a ACTIVETIMEBIAS=%%M if %%K==Bias set /a BIAS=%%M if %%K==DaylightName set DAYLIGHTTIMEZONE=%%M if %%K==StandardName set STANDARDTIMEZONE=%%M if %%K==TimeZoneKeyName set TIMEZONEKEYNAME=%%M )rem This changed in Vista/Win 7. The info in the registry are now references to tzres.dll. rem Key off of the TimeZoneKeyName in the registry to see if we're on a system that supports it. rem This second lookup is because TIMEZONEKEYNAME is always non-DST - this other registry entry gives both. if not ("%TIMEZONEKEYNAME%") == ("") for /f "tokens=1,2*" %%K in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\%TIMEZONEKEYNAME%"') do ( if %%K==Dlt set DAYLIGHTTIMEZONE=%%M if %%K==Slt set STANDARDTIMEZONE=%%M )
if ("%ACTIVETIMEBIAS%") == ("%BIAS%") set CURRENTTIMEZONE=%STANDARDTIMEZONE% if not ("%ACTIVETIMEBIAS%") == ("%BIAS%") set CURRENTTIMEZONE=%DAYLIGHTTIMEZONE%
时间和时区的设置是没有问题的to: huntor
还是不行补充:user.timezone是GMT+8这个是没问题的,一开始我描述错了
http://topic.csdn.net/u/20080923/17/b93f6c68-92f0-4479-bcf0-ac056860b15a.html
System.out.println(c.getTimeZone());如果正常的话,输出应该是:sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null]
谢谢,不过这种方法我已经试过了,改了时区之后,得到的系统时间还是格林威治时间
System.out.println(" user.country = " + System.getProperty("user.country"));
System.out.println(" java.home = " + System.getProperty("java.home"));
TimeZone.setDefault(tz);
然后再获取时间,是可以的,但这只是一个折中的办法,况且其他机器上的客户端如果用这样的代码肯定会出问题的
user.country = CN
java.home = D:\Program Files\Java\jre1.5.0_09就时区有问题,其他都没问题
命令行也有问题,我试一下你的方法
String d= date.tolocalString();
这个d就是正确的
然后运行方法试下,应该就设好了
http://java.sun.com/javase/tzupdater_README.html
{
/*
* We defer setting up timezone until it's actually necessary.
* Refer to TimeZone.getDefault(). However, the system
* property is necessary to be able to be set by the command
* line interface -D. Here temporarily set a null string to
* timezone.
*/
sprops.timezone = "";
}另外,JVM 所使用系统时区会通过 Win32 API 的 GetTimeZoneInformation 函数获得:#include <iostream>
#include <windows.h>using namespace std;int main(int argc, char* argv[]) {
TIME_ZONE_INFORMATION zoneInfo;
setlocale(LC_ALL, ".936");
GetTimeZoneInformation(&zoneInfo);
wprintf(L"Standard Name: %s\n", zoneInfo.StandardName);
printf("Bias: %ld\n", zoneInfo.Bias);
}上面代码,在我机器上输出:Standard Name: 中国标准时间
Bias: -480
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformationJAVA 使用 TimeZone.getSystemTimeZoneID 这个 private 的方法获得 user.timezone 值的。你把下面的代码执行一下,看看结果是什么:import java.lang.reflect.Method;
import java.util.TimeZone;public class ZoneInfoTest { public static void main(String[] str) throws Exception {
Method getSystemTimeZoneID = TimeZone.class.getDeclaredMethod("getSystemTimeZoneID", String.class, String.class);
getSystemTimeZoneID.setAccessible(true);
String javaHome = System.getProperty("java.home");
String userCountry = System.getProperty("user.country");
Object obj = getSystemTimeZoneID.invoke(null, javaHome, userCountry);
System.out.println("user.timezone = " + obj);
}
}如果输出的是 null 的话,那看看 System.getProperty("java.home")/jre/lib/tzmappings 文件中有没有这些:Beijing:-1,75::Asia/Shanghai:
China:-1,75::Asia/Shanghai:
China Standard Time:-1,75::Asia/Shanghai:tzmappings 是个只读文件。如果我把这三行全部用 # 注释,在我机器上执行 TimeZone.getDefault(); 后,那系统属性 user.timezone 的值也为 GMT
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation我是win7,貌似只有这两个,另外那个搜索不到
感谢解答按你的代码,输出为null但是那个目录下的tzmapping中,确实包含那三项
如果为 null 的话,至止已经完全排除了 Java 的问题,可以断定是 Windows 系统注册表的问题了。看一下系统注册表节点:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones 内部是否有 China Standard Time 子节点。再看一下 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation 节点中 StandardName 值是什么(Windows 6.0 及以上版本的查看 TimeZoneKeyName 值)在 http://jeremymurray.org/doku.php/blog 找到一段批处理程序,你执行一下看看输出是什么(复制成为 now.bat 文件,在控制台中执行):[code=BatchFile]@echo off
setlocal
FOR %%A IN (%Date%) do (
set CURRENTDATE=%%A
)
for /f "tokens=1,2" %%A in ('time /t') do (
set CURRENTTIME=%%A %%B
)set TIMEZONEKEYNAME=
for /f "tokens=1,2*" %%K in ('reg query HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation') do (
if %%K==ActiveTimeBias set /a ACTIVETIMEBIAS=%%M
if %%K==Bias set /a BIAS=%%M
if %%K==DaylightName set DAYLIGHTTIMEZONE=%%M
if %%K==StandardName set STANDARDTIMEZONE=%%M
if %%K==TimeZoneKeyName set TIMEZONEKEYNAME=%%M
)rem This changed in Vista/Win 7. The info in the registry are now references to tzres.dll.
rem Key off of the TimeZoneKeyName in the registry to see if we're on a system that supports it.
rem This second lookup is because TIMEZONEKEYNAME is always non-DST - this other registry entry gives both.
if not ("%TIMEZONEKEYNAME%") == ("") for /f "tokens=1,2*" %%K in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\%TIMEZONEKEYNAME%"') do (
if %%K==Dlt set DAYLIGHTTIMEZONE=%%M
if %%K==Slt set STANDARDTIMEZONE=%%M
)
if ("%ACTIVETIMEBIAS%") == ("%BIAS%") set CURRENTTIMEZONE=%STANDARDTIMEZONE%
if not ("%ACTIVETIMEBIAS%") == ("%BIAS%") set CURRENTTIMEZONE=%DAYLIGHTTIMEZONE%
echo %CURRENTDATE% %CURRENTTIME% %CURRENTTIMEZONE%
endlocal[/code]我机器上的输出是:E:\>now
星期一 12:10 中国标准时间
Windows 2008 需要 1.5.0_19 及以后版本
Windows Vista 需要 1.5.0_14 及以后版本JDK 1.6 系统支持最小的版本号Windows 7 需要 1.6.0_14 及以后版本
Windows Server 2008 R2 需要 1.6.0_16 及以后版本你检查一下 JDK 的版本,JDK 5 的输出结果必须是大于等于 1.5.0_21 的。
我的JDK是1.5.0_09,不是Win7的最小版本,不过我同事的机器上JDK也是1.5.0_09,没有这个问题。
注册表也导入了一份,还是没解决
import java.util.TimeZone;
import java.util.Date;
import java.text.DateFormat;public class ForTest {public static void main(String[] args) {DateFormat dateFormatterChina = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM);//格式化输出
TimeZone timeZoneChina = TimeZone.getTimeZone("Asia/Shanghai");//获取时区
dateFormatterChina.setTimeZone(timeZoneChina);//设置系统时区
Date curDate = new Date();//获取系统时间System.out.println(dateFormatterChina.format(curDate));
}
}
同样的用JDK1.6就显示正常。这个问题我还在解决中