VC++ SetLocalTime与SetSystemTime区别

来源:互联网 发布:迅雷会员 淘宝 编辑:程序博客网 时间:2024/06/05 18:19
                                                                                             VC++ SetLocalTime与SetSystemTime区别

SetLocalTime设置北京时间;SetSystemTime设置格林威治时间,比北京时间晚8小时,需要调整wHour
初始化SYSTEMTIME是不能忽略其成员变量wDayOfWeek,wMilliseconds(可lpSystemTime->wDayOfWeek = -1;lpSystemTime->wMilliseconds = 0;),否则将返回0,不能成功设定本机时间。

这里把自己所用到的一些功能和体会给出来,至少要把SetSystemTIme()和SetLocalTime()这两个函数的区别搞清楚。
对于这两个函数,其输入参数必须是一个下面这样的结构体,其成员变量类型必须是ushort,成员变量不能改变顺序。

[StructLayout(LayoutKind.Sequential)]
public struct SystemTime
…{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMiliseconds;
}

调用Win32的API,根据需要选用:

public class Win32
…{
[DllImport("Kernel32.dll")]
public static extern bool SetSystemTime(ref SystemTime sysTime );
[DllImport("Kernel32.dll")]
public static extern bool SetLocalTime(ref SystemTime sysTime);
[DllImport("Kernel32.dll")]
public static extern void GetSystemTime(ref SystemTime sysTime);
[DllImport("Kernel32.dll")]
public static extern void GetLocalTime(ref SystemTime sysTime);
}

下面是SetLocalTime的调用,SetLocalTime的功能就是设置本地系统时间。因为我的工作中要用到的是根据XML文件中的节点内容字符串通过解析后来设置系统时间,所以我做了一个通过输入字符串参数设置本地系统时间的函数,其中调用了SetLocalTime()函数。

public static bool SetLocalTimeByStr(string timestr)
{
bool flag=false;
SystemTime sysTime =new SystemTime();

string SysTime=timestr.Trim(); //此步骤多余,为方便程序而用直接用timestr即可
sysTime.wYear = Convert.ToUInt16(SysTime.Substring(0,4));
sysTime.wMonth = Convert.ToUInt16(SysTime.Substring(4,2));
sysTime.wDay=Convert.ToUInt16(SysTime.Substring(6,2));
sysTime.wHour=Convert.ToUInt16(SysTime.Substring(8,2));
sysTime.wMinute = Convert.ToUInt16(SysTime.Substring(10,2));
sysTime.wSecond = Convert.ToUInt16(SysTime.Substring(12,2));
//注意:
//结构体的wDayOfWeek属性一般不用赋值,函数会自动计算,写了如果不对应反而会出错
//wMiliseconds属性默认值为一,可以赋值
try
{
flag=Win32.SetLocalTime(ref sysTime);
}
//由于不是C#本身的函数,很多异常无法捕获
//函数执行成功则返回true,函数执行失败返回false
//经常不返回异常,不提示错误,但是函数返回false,给查找错误带来了一定的困难
catch(Exception ex1)
{
Console.WriteLine(“SetLocalTime函数执行异常”+ex1.Message);
}

return flag;
}
如果不是以字符串来赋值,而以int甚至ushort类型数来赋值将会更加简单,不多说了。

程序执行之后本地系统时间将会如期改变。

那么SetLocalTime()和SetSystemTime()又有什么区别呢?大家可以把上述函数的“flag=Win32.SetLocalTime(ref sysTime);”部分换成“flag=Win32.SetSystemTime(ref sysTime);”试试,你将会发现这样一个结果:

执行后系统时间也会改变,但总是比预期的有些偏差,中国的朋友估计都会多出8个小时来。

这是时区的设置造成的,SetSystemTime()默认设置的为UTC时间,当系统设置时间的时候还会按照时区加上一个偏差。而我们的用的北京时间也就是东八区时间,刚好比UTC多了8个小时。这回了解二者的区别了吧。
                       UTC=                                     LocalTime+                       bias
                       GetSystemTime                   GetLocalTime

这个偏差是不是可以补回来呢?比如对于北京时间,设置完之后减去8个小时就可以了吗?是这么回事,但是具体做起来要有些麻烦,因为要考虑到天,月甚至年都有可能会造成改变,还要考虑到不同的月份。虽然有了SetLocalTime,再来考虑这个有些多此一举,或者也可以直接从时区的方法上入手,但是我偏偏不服,做了一个这样的方法,只是小试一下,没有自己审核,可能会有bug,给大家参考:

//从字符串设置系统时间
public bool SetSysTimeByStr(string timestr)
…{
int temp=0;
SystemTime sysTime =new SystemTime();
//给sysTIme初始赋值
Win32.GetSystemTime(ref sysTime);
string SysTime=timestr;
sysTime.wYear = Convert.ToUInt16(SysTime.Substring(0,4));
sysTime.wMonth = Convert.ToUInt16(SysTime.Substring(4,2));
sysTime.wDay=Convert.ToUInt16(SysTime.Substring(6,2));
sysTime.wHour=Convert.ToUInt16(SysTime.Substring(8,2));

//为抵消北京时间+8而进行的操作
temp=Convert.ToInt16(SysTime.Substring(8,2))-8;
if(temp<0)
…{
sysTime.wHour =Convert.ToUInt16(temp+24);//Convert.ToUInt16(SysTime.Substring(8,2))-Convert.ToInt16(8);
sysTime.wDay=Convert.ToUInt16(sysTime.wDay-1);
if(sysTime.wDay==0)
…{
if(sysTime.wMonth==5|sysTime.wMonth==7|sysTime.wMonth==8|sysTime.wMonth==10|sysTime.wMonth==12)
…{
sysTime.wMonth=Convert.ToUInt16(sysTime.wMonth-1);
sysTime.wDay=Convert.ToUInt16(30);
}
else if(sysTime.wMonth==1)
…{
sysTime.wMonth=Convert.ToUInt16(12);
sysTime.wDay=Convert.ToUInt16(31);
sysTime.wYear=Convert.ToUInt16(sysTime.wYear-1);
}
else if(sysTime.wMonth==3)
…{
sysTime.wMonth=Convert.ToUInt16(2);
if(sysTime.wYear%4==0&&sysTime.wYear%100!=0)
sysTime.wDay=Convert.ToUInt16(29);
else
sysTime.wDay=Convert.ToUInt16(28);
}
else
…{
sysTime.wMonth=Convert.ToUInt16(sysTime.wMonth-1);
sysTime.wDay=Convert.ToUInt16(31);
}

}
}
else
…{
sysTime.wHour=Convert.ToUInt16(temp);
}

sysTime.wMinute = Convert.ToUInt16(SysTime.Substring(10,2));
sysTime.wSecond = Convert.ToUInt16(SysTime.Substring(12,2));
bool flag=Win32.SetSystemTime(ref sysTime);

return flag;
}

而对于那两个Get的方法GetSystemTimer(),和GetLocalTime()的使用,相信不成什么问题,就不多说了。

http://hi.baidu.com/ggyyso/blog/item/7ce17524aed5ff238644f92d.html

原创粉丝点击