#include "stdafx.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/*
BOOL IsLeapYear(int nYear)
{
    // nYear is in Solar system, 1982...
    if (nYear % 4 == 0) {
        if (nYear % 100 == 0) {
            if (nYear % 400 == 0) {
                //...
                return FALSE;
            }
        }
        return TRUE;
    }

    return FALSE;
}

int GetDayEnd(int nYear, int nMonth)
{
    int nDayEnd;

    if (nMonth == 2) {
        nDayEnd = 28;
        if (IsLeapYear(nYear)) {
            nDayEnd++;
        } else {
            // 28
        }
    } else {
        nDayEnd = 30;
        if ((nMonth == 1) || (nMonth == 3) || (nMonth == 5) || (nMonth == 7) || (nMonth == 8) || (nMonth == 10) || (nMonth == 12))
            nDayEnd++; // 31
    }

    return nDayEnd;
}

long GetTotalSeconds(int nYear, int nMonth, int nDay)
{
    // Seconds elapsed since 00:00:00 on the date nYear/nMonth/nDay...
    ASSERT(nYear >= 1970);
    ASSERT((1 <= nMonth) && (nMonth <= 12));
    ASSERT(1 <= nDay);
    ASSERT(nDay <= GetDayEnd(nYear, nMonth));

    long lTotal = 0;
    int nStart;
    for(nStart = 1970; nStart < nYear; nStart++) {
        int nDays = 365;
        if (IsLeapYear(nStart)) {
            nDays++;
        }
        lTotal += nDays * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
    }
    for(nStart = 1; nStart < nMonth; nStart++) {
        int nDayEnd = GetDayEnd(nYear, nStart);
        lTotal += nDayEnd * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
    }
    lTotal += (nDay - 1) * 24 * 60 * 60; // 24 hours * 60 min * 60 sec

    return lTotal;
}
*/
BOOL CTimeDate::IsLeapYear(int nYear)
{
    // nYear is in Solar system, 1982...
    if (nYear % 4 == 0) {
        if (nYear % 100 == 0) {
            if (nYear % 400 == 0) {
                //...
                return FALSE;
            }
        }
        return TRUE;
    }

    return FALSE;
}

long CTimeDate::GetCurrent()
{
    CTimeDate t;

    t.CurrentDate();

    return t.m_lDate;
}

void CTimeDate::CurrentDate()
{
    ASSERT(this);
    time_t t;
    struct tm* p;
    
    time(&t);
    p = localtime(&t);

    m_lDate = 0;
    m_LN.m_xDay = p->tm_mday - 1;
    m_LN.m_xMonth = p->tm_mon;
    m_LN.m_xYear = (p->tm_year + 1900) - TIMEDATE_YEAR_BASE;
    //m_LN.m_xReserved = 0;
    //m_LN.m_xLunar = 0;
    //m_LN.m_xLeap = 0;
}

BOOL CTimeDate::GetDate(long lDate, BOOL bLunar/* = FALSE*/, BOOL bLeap/* = FALSE*/)
{
    ASSERT(!bLunar && !bLeap); // not yet implemented...

    int nDay = lDate % 100;
    lDate /= 100;
    int nMonth = lDate % 100;
    lDate /= 100;
    int nYear = lDate;
    BOOL bLeapYear = IsLeapYear(nYear);
    nYear -= TIMEDATE_YEAR_BASE;
    if ((nYear < 0) || (nYear >= (1 << TIMEDATE_YEAR_BITS)))
        return FALSE;
    if (!((1 <= nMonth) && (nMonth <= 12))) {
        return FALSE;
    }
    int nDayMax = 30;
    switch(nMonth) {
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
        nDayMax++; // 31
        break;
    case 2:
        nDayMax--; // 29
        if (!bLeapYear) {
            nDayMax--; // 28
        }
        break;
    default:
        break;
    }
    if (!((1 <= nDay) && (nDay <= nDayMax))) {
        return FALSE;
    }
    nMonth--;
    nDay--;

    m_lDate = 0;
    m_LN.m_xYear = nYear;
    m_LN.m_xMonth = nMonth;
    m_LN.m_xDay = nDay;
    //m_LN.m_xReserved = 0;
    //m_LN.m_xLunar = 0;
    //m_LN.m_xLeap = 0;

    return TRUE;
}

long CTimeLong::GetCurrent()
{
    CTimeLong t;

    t.CurrentTime();

    return t.m_lTime;
}

void CTimeLong::CurrentTime()
{
    ASSERT(this);
    time_t t;

    time(&t);

    m_lTime = t;
}

void CTimeLong::GetTime(tm& t) const
{
    ASSERT(this);
    t = *localtime(&m_lTime);
}

