블로그는 나의 힘!
[ Programing ]/Algorithm2014. 1. 10. 13:09

설정한 기간 관련 주간을 계산 하기 위한 코드.

예 : 2014.01.01 ~ 2014.01.10 에서 현재 날짜가 2014.01.05  이고 주간 체크 부분을 수요일로 해 놓을 경우.

      -> 1주 계산. ( 주간 체크 카운터로는 0 )

 

 

 

 

enum eWEEK_TYPE
{
        eWEEK_TYPE_NONE = -1,
        eWEEK_TYPE_SUNDAY = 0,
        eWEEK_TYPE_MONDAY,
        eWEEK_TYPE_TUESDAY,
        eWEEK_TYPE_WEDNESDAY,
        eWEEK_TYPE_THURSDAY,
        eWEEK_TYPE_FRIDAY,
        eWEEK_TYPE_SATURDAY,

        eWEEK_TYPE_MAX,
 
        // option
        eWEEK_TYPE_BEGIN = eWEEK_TYPE_SUNDAY,
        eWEEK_TYPE_END = eWEEK_TYPE_SATURDAY,
};

 

#define CHECK_WEEK_TYPE(x) ( eWEEK_TYPE_BEGIN <= (x) && eWEEK_TYPE_END >= (x) )
#define DATE_1DAYTOTIME (60 * 60 * 24)    // 86400 [Second * Minute * Hour]

 

/*
typedef struct _SYSTEMTIME {
        WORD wYear;
        WORD wMonth;
        WORD wDayOfWeek;
        WORD wDay;
        WORD wHour;
        WORD wMinute;
        WORD wSecond;
        WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;

 

struct tm {
        int tm_sec;     // seconds after the minute [0, 59]
        int tm_min;     // minutes after the hour [0, 59]
        int tm_hour;    // hour since midnight [0, 23]
        int tm_mday;    // day of thr month [1, 31]
        int tm_mon;     // months since January [0, 11]
        int tm_year;    // years since 1900
        int tm_wday;    // day since Sunday [0, 6]
        int tm_yday;    // days since January 1 [0, 365]
        int tm_isdst;   // daylight saving time flag
};


// 날짜 관련 구조체. operator 포함
struct SDate
{
        int iYear;
        int iMonth;
        int iDay;
        int iHour;
        int iMin;
        int iSec;

 

        SDate()
        {
                Initialize();
        }

 

        void Initialize()
        {
                memset( this, 0x00, sizeof(SDate) );
        }

 

        SDate& operator=( const SDate& rhsDate )
        {
                this->iYear = rhsDate.iYear;

                this->iMonth = rhsDate.iMonth;

                this->iDay = rhsDate.iDay;

                this->iHour = rhsDate.iHour;

                this->iMin = rhsDate.iMin;

                this->iSec = rhsDate.iSec;

 

                return (*this);
        }

 

        bool operator<( const SDate& rhsDate ) const
        {
                if( this->iYear > rhsDate.iYear ) return false;
                if( this->iYear < rhsDate.iYear ) return true;

 

                if( this->iMonth > rhsDate.iMonth ) return false;
                if( this->iMonth < rhsDate.iMonth ) return true;

 

                if( this->iDay > rhsDate.iDay ) return false;
                if( this->iDay < rhsDate.iDay ) return true;

 

                if( this->iHour > rhsDate.iHour ) return false;
                if( this->iHour < rhsDate.iHour ) return true;

 

                if( this->iMin > rhsDate.iMin ) return false;
                if( this->iMin < rhsDate.iMin ) return true;

 

                if( this->iSec >= rhsDate.iSec ) return false;

 

                return true;
        }

 

        bool operator>( const SDate& rhsDate ) const
        {
                if( this->iYear < rhsDate.iYear ) return false;
                if( this->iYear > rhsDate.iYear ) return true;

 

                if( this->iMonth < rhsDate.iMonth ) return false;
                if( this->iMonth > rhsDate.iMonth ) return true;

 

                if( this->iDay < rhsDate.iDay ) return false;
                if( this->iDay > rhsDate.iDay ) return true;


                if( this->iHour < rhsDate.iHour ) return false
                if( this->iHour > rhsDate.iHour ) return true;

 

                if( this->iMin < rhsDate.iMin ) return false;
                if( this->iMin > rhsDate.iMin ) return true;

 

                if( this->iSec <= rhsDate.iSec ) return false;

 

                return true;
        }

 

        bool operator==( const SDate& rhsDate ) const
        {
                if( this->iYear != rhsDate.iYear ) return false;
                if( this->iMonth != rhsDate.iMonth ) return false;
                if( this->iDay != rhsDate.iDay ) return false;
                if( this->iHour != rhsDate.iHour ) return false;
                if( this->iMin != rhsDate.iMin ) return false;
                if( this->iSec != rhsDate.iSec ) return false;

 

                return true;
        }

 

        bool operator!=( const SDate& rhsDate ) const
        {
                if( this->iYear != rhsDate.iYear ) return true;
                if( this->iMonth != rhsDate.iMonth ) return true;
                if( this->iDay != rhsDate.iDay ) return true;
                if( this->iHour != rhsDate.iHour ) return true;
                if( this->iMin != rhsDate.iMin ) return true;
                if( this->iSec != rhsDate.iSec ) return true;

 

                return false;
        }

 

        bool operator<=( const SDate& rhsDate ) const
        {
                if( this->iYear > rhsDate.iYear ) return false;
                if( this->iYear < rhsDate.iYear ) return true;

 

                if( this->iMonth > rhsDate.iMonth ) return false;
                if( this->iMonth < rhsDate.iMonth ) return true;

 

                if( this->iDay > rhsDate.iDay ) return false;
                if( this->iDay < rhsDate.iDay ) return true;

 

                if( this->iHour > rhsDate.iHour ) return false;
                if( this->iHour < rhsDate.iHour ) return true;

 

                if( this->iMin > rhsDate.iMin ) return false;
                if( this->iMin < rhsDate.iMin ) return true;

 

                if( this->iSec > rhsDate.iSec ) return false;

 

                return true;
        }

 

        bool operator>=( const SDate& rhsDate ) const
        {
                if( this->iYear < rhsDate.iYear ) return false;
                if( this->iYear > rhsDate.iYear ) return true;

 

                if( this->iMonth < rhsDate.iMonth ) return false;
                if( this->iMonth > rhsDate.iMonth ) return true;

 

                if( this->iDay < rhsDate.iDay ) return false;
                if( this->iDay > rhsDate.iDay ) return true;

 

                if( this->iHour < rhsDate.iHour ) return false;
                if( this->iHour > rhsDate.iHour ) return true;

 

                if( this->iMin < rhsDate.iMin ) return false;
                if( this->iMin > rhsDate.iMin ) return true;

 

                if( this->iSec < rhsDate.iSec ) return false;

 

                return true;
        }
} // !SDate
*/

 

// 입력학 Date 값을 SYSTEMTIME  구조체에 담는다.
void GetDateToSysTimeInfo( SYSTEMTIME& sysTime, const SDate& sDateInfo )
{
        sysTime.wYear = sDateInfo.iYear;
        sysTime.wMonth = sDateInfo.iMonth;
        sysTime.wDay = sDateInfo.iDay;
        sysTime.wHour = sDateInfo.iHour;
        sysTime.wMinute = sDateInfo.iMin;
        sysTime.wSecond = sDateInfo.iSec;
        sysTime.wMilliseconds = 0;
        sysTime.wDayOfWeek = 0;
}

 

double CompareSystemTime( PSYSTEMTIME pTargetTime, PSYSTEMTIME pCompareTime )
{
        tm tmTime1, tmTime2;
        time_t timeTime1, timeTime2;

 

        tmTime1.tm_sec = pTargetTime->wSecond;
        tmTime1.tm_min = pTargetTime->wMinute;
        tmTime1.tm_hour = pTargetTime->wHour;
        tmTime1.tm_mday = pTargetTime->wDay;
        tmTime1.tm_mon = pTargetTime->wMonth - 1;
        tmTime1.tm_year = pTargetTime->wYear - 1900;
        tmTime1.tm_isdst = 0;
        timeTime1 = ::mktime( &tmTime1 );

 

        tmTime2.tm_sec = pCompareTime->wSecond;
        tmTime2.tm_min = pCompareTime->wMinute;
        tmTime2.tm_hour = pCompareTime->wHour;
        tmTime2.tm_mday = pCompareTime->wDay;
        tmTime2.tm_mon = pCompareTime->wMonth - 1;
        tmTime2.tm_year = pCompareTime->wYear - 1900;
        tmTime2.tm_isdst = 0;
        timeTime2 = ::mktime( &tmTime2 );


        // time2와 time1의 second 차이를 double 형으로 리턴
        return ::difftime( timeTime1, timeTime2 );
}

 

int GetTermDay( const SDate sStartDate, const SDate sEndDate )
{
        SYSTEMTIME sStartSystemTime;
        sStartSystemTime.wYear = sStartDate.iYear;
        sStartSystemTime.wMonth = sStartDate.iMonth;
        sStartSystemTime.wDay = sStartDate.iDay;
        sStartSystemTime.wHour = sStartDate.iHour;
        sStartSystemTime.wMinute = sStartDate.iMin;
        sStartSystemTime.wSecond = sStartDate.iSec;
        sStartSystemTime.wMilliseconds = 0;
        sStartSystemTime.wDayOfWeek = 0;

 

        SYSTEMTIME sEndSystemTime;
        sEndSystemTime.wYear = sEndDate.iYear;
        sEndSystemTime.wMonth = sEndDate.iMonth;
        sEndSystemTime.wDay = sEndDate.iDay;
        sEndSystemTime.wHour = sEndDate.iHour;
        sEndSystemTime.wMinute = sEndDate.iMin;
        sEndSystemTime.wSecond = sEndDate.iSec;
        sEndSystemTime.wMilliseconds = 0;
        sEndSystemTime.wDayOfWeek = 0;

 

        int iTerm = (int)( ::CompareSystemTime(&sEndSystemTime, &sStartSystemTime) );
        if( 0 >= iTerm ) return 0;

 

        return (iTerm / DATE_1DAYTOTIME) + 1;
}


// 설정된 주간 기간 카운터 계산하기
// 해당 설정된 기간에 관련하여 시작 날짜~종료 날짜(현재 날짜) 계산하여 주간을 계산한다.
bool SettingRefreshCount( int& iRefreshCount, eWEEK_TYPE eRefreshWeekType,

                                     const SDate sStartDate, const SDate sEndDate )
{
        SDate sCurrentDate, sTempDate;
        SYSTEMTIME sCurrentSysTime;

 

        // 현재 시간 SYSTEMTIME 구조체 담기
        ::GetLocalTime( &CurrentSysTime );
        GetDateToSysTimeInfo( sCurrentDate, sCurrentSysTime );

 

        if( FALSE == CHECK_WEEK_TYPE(sCurrentSysTime.wDayOfWeek) ) return false;
 

        eWEEK_TYPE eCurrentWeekType = static_cast<eWEEK_TYPE>( sCurrentSysTime.wDayOfWeek );

        sTempDate = (sStartDate <= sCurrentDate)? sCurrentDate : sEndDate;


        int iTermDay = GetTermDay( sStartDate, sTempDate );
        if( 0 >= iTermDay ) return false;

 

        int iPlusWeek = (eCurrentWeekType <= eRefreshWeekType)? (eRefreshWeekType - eCurrentWeekType) : 

                               (eWEEK_TYPE_MAX - (eCurrentWeekType + 1) + (eRefreshWeekType + 1));
        int iNextTermDay = iTermDay - PlusWeek;
        if( 0 >= iNextTermDay ) return false;

 

        iRefreshCount += ( iNextTermDay / eWEEK_TYPE_MAX );

 

        if( eRefreshWeekType <= (iNextTermDay % eWEEK_TYPE_MAX) )
                iRefreshCount++;

 

       return true;

}

 

void main()
{
        eWEEK_TYPE eRefreshWeekType = eWEEK_TYPE_WEDNESDAY;
        int iRefreshCount[eWEEK_TYPE_MAX] = { 0, };

 

        SDate sStartDate;
        sStartDate.iYear = 2014;
        sStartDate.iMonth = 1;
        sStartDate.iDay= 1;

 

        SDate sEndDate;
        sStartDate.iYear = 2014;
        sStartDate.iMonth = 1;
        sStartDate.iDay= 10;
 

        if( false == SettingRefreshCount(iRefreshCount[eRefreshWeekType], eRefreshWeekType, sStartDate, sEndDate) )
                printf( "[main] SettingRefreshCount(%d) \n", 0 );

 

        for( int i = 0; i < eWEEK_TYPE_MAX; ++i )
                printf( "RefreshWeek[(%d)] : (%d) \n", i, iRefreshCount[i] + 1 );
}

 

Posted by Mister_Q