1. 程式人生 > >自己手寫一個 VB 的 DateAdd 函式(VB/C 雙語言版本)

自己手寫一個 VB 的 DateAdd 函式(VB/C 雙語言版本)

         可能有些朋友覺得這是多餘的事情,既然 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 <
[email protected]
> ' 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 <[email protected]>
// 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;
    }
}
程式碼看上去是不是就像直譯的偷笑,其實本來也是差不多直譯過來用的。好了有需要的就拿去用呲牙