可能有些朋友觉得这是多余的事情,既然 VB 有了 DateAdd 函数来进行日期运算,干嘛还要自己手写一个? 其实这一点也不多余,因为有些时候我们的开发环境不一定就在 VB 里,而那些个开发环境不一定就有那么多现成的函数可以使用,那么这个时候要做个日期运算那就不是那么简单的事情了。就比如我写这函数的理由,就是在单片机里需要做日期运算写的。因为在单片机里,就连想取得个时间都要外挂一个外围的时钟芯片,要读个时间也要进行专门的通讯才能读到内容,更别说什么现成的日期时间类型或对其进行运算了,这些全要自己弄,所以做这些个蛋疼的事情并不是没必要的,而是你是否接触到这种蛋疼的需求而已。好了,闲话不多说,先看看这个函数如果用 VB 可以怎么写吧。
'====================================================================================================
' Definition structure ( 结构体定义 )
'====================================================================================================
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
'====================================================================================================
' API function declaration ( API 函数声明 )
'====================================================================================================
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, _
Source As Any, _
ByVal Length As Long)
'====================================================================================================
' Custom function ( 自定义函数 )
'====================================================================================================
'----------------------------------------------------------------------------------------------------
' Function Name: DateAdd2
' Description : A function for computing time.
' Input Parameter: interval - (String)Necessary,Type of operation time.
' : number - (Long)Necessary,The numeric value that needs to be performed.
' : dateInfo - (SYSTEMTIME)Necessary,The time required for computation is also
' : the result of computation..
' Return Value: (void) - No return
' Version : 1.0.0
' Author : Zhou Wen Xing <mail@rljy.com>
' CSDN Accounts: SupermanKing
' Date : June, 26nd 2018
'----------------------------------------------------------------------------------------------------
Private Sub DateAdd2(ByVal interval As String, _
ByVal number As Long, _
ByRef dateInfo As SYSTEMTIME)
Dim m_Year As Long
Dim IsLeapYear As Long
Dim m_Month As Long
Dim m_AllMonth As Long
Dim m_Day As Long
Dim m_AllDay As Long
Dim m_DayCount As Long
Dim m_AllHour As Long
Dim m_Hour As Long
Dim m_AllMinute As Long
Dim m_Minute As Long
Dim m_AllSecond As Long
Dim m_Second As Long
Dim m_SYSTEMTIME As SYSTEMTIME
Select Case interval
Case "yyyy":
dateInfo.wYear = dateInfo.wYear + number
Case "m"
m_Year = dateInfo.wYear
m_AllMonth = dateInfo.wMonth + number
If m_AllMonth > 12 Then
m_Year = m_Year + Int(m_AllMonth / 12)
m_Month = m_AllMonth Mod 12
If m_Month = 0 Then
dateInfo.wMonth = 1
Else
dateInfo.wMonth = m_Month
End If
dateInfo.wYear = m_Year
Else
dateInfo.wMonth = m_AllMonth
End If
Case "d"
m_Year = dateInfo.wYear
If (m_Year - 1980) Mod 4 = 0 Then
IsLeapYear = 1
Else
IsLeapYear = 0
End If
m_Month = dateInfo.wMonth
Select Case m_Month
Case 1, 3, 5, 7, 8, 10, 12
m_DayCount = 31
Case 2
If IsLeapYear Then
m_DayCount = 29
Else
m_DayCount = 28
End If
Case 4, 6, 9, 11
m_DayCount = 30
End Select
m_AllDay = dateInfo.wDay + number
If m_AllDay > m_DayCount Then
Do
m_AllDay = m_AllDay - m_DayCount
m_Month = m_Month + 1
If m_AllDay > m_DayCount Then
If m_Month > 12 Then
m_Month = 1
m_Year = m_Year + 1
If (m_Year - 1980) Mod 4 = 0 Then
IsLeapYear = 1
Else
IsLeapYear = 0
End If
End If
End If
Select Case m_Month
Case 1, 3, 5, 7, 8, 10, 12
m_DayCount = 31
Case 2
If IsLeapYear Then
m_DayCount = 29
Else
m_DayCount = 28
End If
Case 4, 6, 9, 11
m_DayCount = 30
End Select
Loop While m_AllDay > m_DayCount
If m_AllDay = 0 Then
m_AllDay = 1
End If
dateInfo.wDay = m_AllDay
dateInfo.wMonth = m_Month
dateInfo.wYear = m_Year
Else
dateInfo.wDay = m_AllDay
End If
Case "h"
m_AllHour = dateInfo.wHour + number
If m_AllHour < 24 Then
dateInfo.wHour = m_AllHour
Else
m_Hour = m_AllHour Mod 24
m_AllDay = Int(m_AllHour / 24)
CopyMemory m_SYSTEMTIME, dateInfo, LenB(m_SYSTEMTIME)
DateAdd2 "d", CInt(m_AllDay), m_SYSTEMTIME
dateInfo.wHour = m_Hour
dateInfo.wDay = m_SYSTEMTIME.wDay
dateInfo.wMonth = m_SYSTEMTIME.wMonth
dateInfo.wYear = m_SYSTEMTIME.wYear
End If
Case "n"
m_AllMinute = dateInfo.wMinute + number
If m_AllMinute < 60 Then
dateInfo.wMinute = m_AllMinute
Else
m_Minute = m_AllMinute Mod 60
m_AllHour = Int(m_AllMinute / 60)
CopyMemory m_SYSTEMTIME, dateInfo, LenB(m_SYSTEMTIME)
DateAdd2 "h", CInt(m_AllHour), m_SYSTEMTIME
dateInfo.wMinute = m_Minute
dateInfo.wHour = m_SYSTEMTIME.wHour
dateInfo.wDay = m_SYSTEMTIME.wDay
dateInfo.wMonth = m_SYSTEMTIME.wMonth
dateInfo.wYear = m_SYSTEMTIME.wYear
End If
Case "s"
m_AllSecond = dateInfo.wSecond + number
If m_AllSecond < 60 Then
dateInfo.wSecond = m_AllSecond
Else
m_Second = m_AllSecond Mod 60
m_AllMinute = Int(m_AllSecond / 60)
CopyMemory m_SYSTEMTIME, dateInfo, LenB(m_SYSTEMTIME)
DateAdd2 "n", CInt(m_AllMinute), m_SYSTEMTIME
dateInfo.wSecond = m_Second
dateInfo.wMinute = m_SYSTEMTIME.wMinute
dateInfo.wHour = m_SYSTEMTIME.wHour
dateInfo.wDay = m_SYSTEMTIME.wDay
dateInfo.wMonth = m_SYSTEMTIME.wMonth
dateInfo.wYear = m_SYSTEMTIME.wYear
End If
End Select
End Sub
上面是 VB 的实现过程,我写来主要是用来调试逻辑的 ,因为如果要在单片机里调试逻辑怎么都没直接在 Windows 下方便 ,其实写好了程序直接翻译一下就可以成为 C 语言的函数了,比如以下代码:
//====================================================================================================
// Adduction head file ( 引用头文件 )
//====================================================================================================
#include <STRING.H>
//====================================================================================================
// Type definition ( 类型定义 )
//====================================================================================================
#define BYTE unsigned char
#define WORD unsigned int
//====================================================================================================
// Definition structure ( 结构体定义 )
//====================================================================================================
typedef struct tagSYSTEMTIME{
BYTE Century; // 世纪
BYTE FullYear; // 年份
BYTE Month; // 月份
BYTE Day; // 日期
BYTE Hours; // 小时
BYTE Minutes; // 分钟
BYTE Seconds; // 秒钟
BYTE Week; // 周几
}SYSTEMTIME,*PSYSTEMTIME;
//====================================================================================================
// Custom function ( 自定义函数 )
//====================================================================================================
//----------------------------------------------------------------------------------------------------
// Function Name: DateAdd
// Description : A function for computing time.
// Input Parameter: interval - (char *)Necessary,Type of operation time.
// : number - (WORD)Necessary,The numeric value that needs to be performed.
// : dateInfo - (SYSTEMTIME *)Necessary,The time required for computation is also
// : the result of computation..
// Return Value: (void) - No return
// Version : 1.0.0
// Author : Zhou Wen Xing <mail@rljy.com>
// CSDN Accounts: SupermanKing
// Date : June, 26nd 2018
//----------------------------------------------------------------------------------------------------
void DateAdd(char *interval,WORD number,SYSTEMTIME *dateInfo)
{
WORD m_Year;
WORD m_Month;
WORD m_Hour;
WORD m_Minute;
WORD m_Second;
WORD m_AllMonth;
WORD m_AllDay;
WORD m_AllHour;
WORD m_AllMinute;
WORD m_AllSecond;
WORD m_DayCount;
BYTE IsLeapYear;
BYTE m_SType;
SYSTEMTIME m_SYSTEMTIME;
if(strcmp(interval,"y")){
m_SType = 0;
}else if(strcmp(interval,"M")){
m_SType = 1;
}else if(strcmp(interval,"d")){
m_SType = 2;
}else if(strcmp(interval,"h")){
m_SType = 3;
}else if(strcmp(interval,"i")){
m_SType = 4;
}else if(strcmp(interval,"s")){
m_SType = 5;
}
switch(m_SType){
case 0: // 年份计算
m_Year = (dateInfo->Century*100)+dateInfo->FullYear;
m_Year += number;
dateInfo->Century = ((m_Year-(m_Year%100))/100)&0xFF;
dateInfo->FullYear = (m_Year%100)&0xFF;
break;
case 1: // 月份计算
m_Year = (dateInfo->Century*100)+dateInfo->FullYear;
m_AllMonth = dateInfo->Month+number;
if(m_AllMonth>12){
m_Year = m_Year+(m_AllMonth / 12);
m_Month = m_AllMonth % 12;
if(m_Month==0){
dateInfo->Month = 1;
}else{
dateInfo->Month = m_Month;
}
dateInfo->Century = ((m_Year-(m_Year%100))/100)&0xFF;
dateInfo->FullYear = (m_Year%100)&0xFF;
}else{
dateInfo->Month = m_AllMonth;
}
break;
case 2: // 日期计算
m_Year = (dateInfo->Century*100)+dateInfo->FullYear;
if((m_Year-1980)%4==0){
IsLeapYear = 1;
}else{
IsLeapYear = 0;
}
m_Month = dateInfo->Month;
switch(m_Month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
m_DayCount = 31;
break;
case 2:
if(IsLeapYear){
m_DayCount = 29;
}else{
m_DayCount = 28;
}
break;
case 4:
case 6:
case 9:
case 11:
m_DayCount = 30;
break;
}
m_AllDay = dateInfo->Day+number;
if(m_AllDay>m_DayCount){
while(m_AllDay>m_DayCount){
m_AllDay = m_AllDay - m_DayCount;
m_Month++;
if(m_AllDay>m_DayCount){
if(m_Month>12){
m_Month = 1;
m_Year++;
if((m_Year-1980)%4==0){
IsLeapYear = 1;
}else{
IsLeapYear = 0;
}
}
}
switch(m_Month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
m_DayCount = 31;
break;
case 2:
if(IsLeapYear){
m_DayCount = 29;
}else{
m_DayCount = 28;
}
break;
case 4:
case 6:
case 9:
case 11:
m_DayCount = 30;
break;
}
}
if(m_AllDay == 0){
m_AllDay = 1;
}
dateInfo->Day = m_AllDay&0xFF;
dateInfo->Month = m_Month&0xFF;
dateInfo->Century = ((m_Year-(m_Year%100))/100)&0xFF;
dateInfo->FullYear = (m_Year%100)&0xFF;
}else{
dateInfo->Day = m_AllDay&0xFF;
}
break;
case 3: // 小时计算
m_AllHour = dateInfo->Hours + number;
if(m_AllHour<24){
dateInfo->Hours = m_AllHour&0xFF;
}else{
m_Hour = m_AllHour%24;
m_AllDay = m_AllHour/24;
memcpy((void *)&m_SYSTEMTIME,(void *)dateInfo,sizeof(SYSTEMTIME));
DateAdd("d",m_AllDay,(SYSTEMTIME *)&m_SYSTEMTIME);
dateInfo->Hours = m_Hour&0xFF;
dateInfo->Day = m_SYSTEMTIME.Day;
dateInfo->Month = m_SYSTEMTIME.Month;
dateInfo->FullYear = m_SYSTEMTIME.FullYear;
dateInfo->Century = m_SYSTEMTIME.Century;
}
break;
case 4: // 分钟计算
m_AllMinute = dateInfo->Minutes + number;
if(m_AllMinute<60){
dateInfo->Minutes = m_AllMinute&0xFF;
}else{
m_Minute = m_AllMinute%60;
m_AllHour = m_Minute/60;
memcpy((void *)&m_SYSTEMTIME,(void *)dateInfo,sizeof(SYSTEMTIME));
DateAdd("h",m_AllHour,(SYSTEMTIME *)&m_SYSTEMTIME);
dateInfo->Minutes = m_Minute&0xFF;
dateInfo->Hours = m_SYSTEMTIME.Hours;
dateInfo->Day = m_SYSTEMTIME.Day;
dateInfo->Month = m_SYSTEMTIME.Month;
dateInfo->FullYear = m_SYSTEMTIME.FullYear;
dateInfo->Century = m_SYSTEMTIME.Century;
}
break;
case 5: // 秒钟计算
m_AllSecond = dateInfo->Seconds + number;
if(m_AllSecond<60){
dateInfo->Seconds = m_AllSecond&0xFF;
}else{
m_Second = m_AllSecond%60;
m_AllMinute = m_AllSecond/60;
memcpy((void *)&m_SYSTEMTIME,(void *)dateInfo,sizeof(SYSTEMTIME));
DateAdd("n",m_AllMinute,(SYSTEMTIME *)&m_SYSTEMTIME);
dateInfo->Seconds = m_Second&0xFF;
dateInfo->Minutes = m_SYSTEMTIME.Minutes;
dateInfo->Hours = m_SYSTEMTIME.Hours;
dateInfo->Day = m_SYSTEMTIME.Day;
dateInfo->Month = m_SYSTEMTIME.Month;
dateInfo->FullYear = m_SYSTEMTIME.FullYear;
dateInfo->Century = m_SYSTEMTIME.Century;
}
break;
}
}
代码看上去是不是就像直译的,其实本来也是差不多
直译过来用的。好了有需要的就拿去用