需求
-
项目需要用到口袋电脑,但口袋电脑的电池容量小,经常会没电导致系统时间不准;
-
实现要求,安卓PAD和PC通过局域网(WiFi)连接动态设置电脑端的时间。
-
介绍:本文用到的 Socket 通信用于接收PAD端相对准确的时间;对Socket通信感兴趣的或者通信代码看不懂的同学请移步:
-
如果仅仅是自定义修改时间,可以用 bat 文件,代码如下,可在任意位置双击运行,BUG在哪呢,双击运行可以,但是 VC 调用却不能运行!;这样的话,如果可以操作PC,那我直接在设置里设置它不香吗,干得儿要用 bat ?显得我的屌比较大吗?
@echo off >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" if '%errorlevel%' NEQ '0' ( goto UACPrompt ) else ( goto gotAdmin ) :UACPrompt echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\getadmin.vbs" "%temp%\getadmin.vbs" exit /B :gotAdmin if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" ) date 2018-08-08 time 20:18:08
Android端发送时间
try {
Date sendDate = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd$HH:mm:ss");
String timeStr = (df.format(sendDate)).toString() + "$3";
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(AokOPS, "GBK");
outputStreamWriter.write(timeStr);
outputStreamWriter.flush();
} catch (IOException e) {
Log.i(TAG, "run: 发送事件报错!" + e.getMessage());
}
PC 端接受处理
char szRecvMsg[1024] = { 0 };
m_Socket1.Receive(szRecvMsg, 1024);
CString strReceive = "";
strReceive = (CString)szRecvMsg;
CString receivedDate = "";
CString receivedTime = "";
CString measurePoints = "";
int pos1 = strReceive.Find('$');
int pos2 = strReceive.ReverseFind('$');
if (pos1 == -1 || pos2 == -1 || pos2 == pos1) {
m_Socket1.Close();
continue;
}
receivedDate = strReceive.Left(pos1);
measurePoints = strReceive.Mid(pos2 + 1);
sscanf(strReceive, "%*[^$]$%[^$]", receivedTime);
while (true) {
if (!receivedDate.IsEmpty())break;
}
PC端设置时间
参考自:https://blog.csdn.net/waveyang/article/details/6114608
-
方法一:具体指定 int 、long 型数据,
SYSTEMTIME curr_st;//可行 GetLocalTime(&curr_st); curr_st.wYear = 2006; curr_st.wMonth = 12; curr_st.wDay = 1; curr_st.wHour = 3; curr_st.wMinute = 33; curr_st.wSecond = 59; curr_st.wMilliseconds = 999; SetLocalTime(&curr_st);
-
方法二
COleDateTime tm; //可行
COleDateTimeSpan ts; //可行
tm.ParseDateTime("2007-11-24 8:00:00"); //可行
//ts.SetDateTimeSpan(3, 8, 0, -14); //用于动态调正时间,几时几分几秒
tm += ts; //可行
SYSTEMTIME st; //可行
tm.GetAsSystemTime(st); //可行
SetLocalTime(&st); //可行
最终实现
-
通过指定 String 是可以实现的!包括通过 +“ ”+ 也通过!(以下代码是 静态代码,把困难问题简单化、具体化)
COleDateTime tm; CString date = "2007-11-24"; CString time = "8:00:00"; CString newDateTime = date + " " + time; ofstream ofile; //定义输出文件 ofile.open("C:\\Users\\Administrator\\Desktop\\receivedNewTime.txt"); ofile << newDateTime << endl; ofile.close(); tm.ParseDateTime(newDateTime); SYSTEMTIME st; tm.GetAsSystemTime(st); SetLocalTime(&st);
-
通过解析字符串也成功了!坑,在于要给date、time初始化!不能仅仅是给 “”(接收解析数据,并利用数据进行时间校准)
COleDateTime tm; CString receivedStr = "2016-09-13$17:25:17$3"; CString date = "2020-01-01"; CString time = "08:08:08"; CString measurePoints = ""; int pos1 = receivedStr.Find('$'); int pos2 = receivedStr.ReverseFind('$'); date = receivedStr.Left(pos1); //measurePoints = strReceive.Mid(pos2 + 1); measurePoints = receivedStr.Right(receivedStr.GetLength() - 1 - pos2); sscanf(receivedStr, "%*[^$]$%[^$]", time); date += " "; CString newDateTime = date + time; ofstream ofile; //定义输出文件 ofile.open("C:\\Users\\Administrator\\Desktop\\2016NewTime.txt"); ofile << date << endl; ofile << time << endl; ofile.close(); tm.ParseDateTime(newDateTime); ts.SetDateTimeSpan(0,0,0,2); tm += ts; SYSTEMTIME st; tm.GetAsSystemTime(st); SetLocalTime(&st);
注意
- PC端软件要以管理员身份运行;
- PC端打开VS编译也同样需要管理员运行;
- 遇到最大的坑!C++里面的时间问题!ParseDateTime(); 参数是 字符串,但不是完全的 string,对于参数中有 空格的,其实他可以解析,但是这个用于拼接的源数据,必须!事先给其赋值!绝不能仅仅给个 “”;另外,其字符串通过:Str3 = Str1 + " " + Str2; 是没有错的!即使C++看见空格就返回;
- 日期、字符串转换:https://www.cnblogs.com/renjiashuo/p/6913668.html
- .exe 要在属性-兼容性中写上以管理员身份运行。