时区设置- Windows 平台
www.diybl.com 时间 : 2009-03-02 作者:匿名 编辑:sky 点击: 896 [ 评论 ]
-
-
最近研究了一下Windows 上的时区设置方法,记录在此,分享大家。
首先分析一下原理。经过一番研究,发现Windows平台上设置时区和以下因素有关系:
1. 设置时区时,使用API函数SetTimeZoneInformation来设置时区信息。这个API函数使用了一个结构“TIME_ZONE_INFORMATION”,其定义在winbase.h,具体如下:
typedef struct _TIME_ZONE_INFORMATION {
LONG Bias;
WCHAR StandardName[ 32 ];
SYSTEMTIME StandardDate;
LONG StandardBias;
WCHAR DaylightName[ 32 ];
SYSTEMTIME DaylightDate;
LONG DaylightBias;
} TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
Bias: 和0时区相差的分钟数
StandardName: 标准时间的名称
StandardDate:如果有夏令时的时区,这个结构确定了什么时间开始实行夏令时
StandardBias:标准时间下,和Bias的差别。通常为0
DaylightName:夏令时的名称
DaylightDate:结束夏令时的时间
DaylightBias:夏令时的时候,时间的偏差
另外,要注意一个公式:
UTC = local time + bias: 就是说本地时间加上Bais才是UTC时间。
2. 在以下注册表中存放了所有时区信息:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Time Zones
以北京时间为例,其主要注册表项如下:
Display: 就是在控制面板里,调整时区时显示的名称。Vista里面还有一条MUI_Display项,是多语言环境
的显示。
Std:标准时间名称。和设置时区信息的函数有关。
Dlt: 如果有夏令时之类的时区的名称。
Tzi: 一个数据结构,包含本地时区和0时区相差的分钟数等信息。下面我们用一个结构定义。
typedef struct _REG_TZI_FORMAT
{
LONG Bias;
LONG StandardBias;
LONG DaylightBias;
SYSTEMTIME StandardDate;
SYSTEMTIME DaylightDate;
} REG_TZI_FORMAT;
介绍完上述两点,大家就知道了,要设置时区打大概步骤:
1. 从注册表中获得相应的时区信息
2. 根据注册表中的信息,设置TIME_ZONE_INFORMATION结构
3. 调用SetTimeZoneInformation设置时区信息
当然,在Windows XP以上,还需要获得一个权限,称为“SE_TIME_ZONE_NAME” privilege。
下面是代码,以设置为北京时间为例子:
BOOL SetTimeZoneToChina(void)
{
// Enable the required privilege
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken);
LookupPrivilegeValue(
NULL, TEXT("SeTimeZonePrivilege"), &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(
hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
//Query the registry key to get the TZI info of China time zone
HKEY hKey;
TIME_ZONE_INFORMATION tziNew;
REG_TZI_FORMAT regTZI;
// TCHAR szProductType[BUFSIZE];
DWORD dwBufLen=sizeof(regTZI);
LONG lRet;
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\China Standard Time"),
0, KEY_QUERY_VALUE, &hKey );
if( lRet != ERROR_SUCCESS )
return FALSE;
lRet = RegQueryValueEx( hKey, TEXT("TZI"), NULL, NULL,
(LPBYTE) ®TZI, &dwBufLen);
RegCloseKey(hKey);
if( (lRet != ERROR_SUCCESS) || (dwBufLen > sizeof(regTZI)) )
return FALSE;
// Adjust the time zone information
ZeroMemory(&tziNew, sizeof(tziNew));
tziNew.Bias = regTZI.Bias;
tziNew.StandardDate = regTZI.StandardDate;
wcscpy(tziNew.StandardName, L"China Standard Time");
wcscpy(tziNew.DaylightName, L"China Standard Time");
tziNew.DaylightDate = regTZI.DaylightDate;
tziNew.DaylightBias = regTZI.DaylightBias;
if( !SetTimeZoneInformation( &tziNew ) )
{
printf("Failure1: %d\n", GetLastError());
return FALSE;
}
// Disable the privilege
tkp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(
hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
return TRUE;
}
以上仅供参考。具体可参考MSDN上SetTimeZoneInformation相关说明和示例代码。
文章出处:飞诺网(www.diybl.com):http://www.diybl.com/course/3_program/c++/cppjs/20090302/156436.html