Converting a CString date key into a long key

时间:2017-06-12 16:56:28

标签: mfc

I have this problem.

This is how I create a key from a date:

CString strKey = psEvent->datEvent.Format(_T("%Y-%m-%d"));

More recently, I created a new type of key:

WORD wKey = static_cast<WORD>(CInPlaceDT::GetLongDate(psEvent->datEvent));

The GetLongDate method is:

long CInPlaceDT::GetLongDate(COleDateTime timDate)
{
    long    lDate;

    lDate = (timDate.GetYear() * 10000) +
            (timDate.GetMonth() * 100 ) +
             timDate.GetDay();

    return lDate;
}

There is nothing wrong with the above code. But I am now in a situation where I need to take a CString that contains a formatted key (date) and build the same long date. At the moment I am doing this:

if (mapSSEventLocations.GetSize() > 0 && m_mapWOSpecialEvents.GetSize() > 0 )
{
    // The new SRR format does not use the mapSSEventLocations object anymore.
    // So we must migrate what we can across.
    POSITION sPos = mapSSEventLocations.GetStartPosition();
    while (sPos != nullptr)
    {
        CString strDate, strLocation;
        mapSSEventLocations.GetNextAssoc(sPos, strDate, strLocation);
        // We must now find the match
        // The key is like this: psEvent->datEvent.Format(_T("%Y-%m-%d"));
        POSITION sPos2 = m_mapWOSpecialEvents.GetStartPosition();
        while (sPos2 != nullptr)
        {
            WORD wDate;
            CSpecialEvent *pEvent = nullptr;
            m_mapWOSpecialEvents.GetNextAssoc(sPos2, wDate, (CObject *&)pEvent);
            if (pEvent != nullptr)
            {
                COleDateTime datEvent;

                CInPlaceDT::GetOleDateTime(wDate, datEvent);
                CString strThisKey = datEvent.Format(_T("%Y-%m-%d"));

                if (strThisKey == strDate)
                {
                    // We got the match
                    pEvent->SetLocation(strLocation);
                    break;
                }
            }
        }
    }
}

It works fine. But I would like to take strDate and convert it to a wDate style key so I can just lookup the event.

1 个答案:

答案 0 :(得分:1)

我有一些旧代码使用scanf将文本转换为日期,并使用regex添加了第二个版本。我似乎记得一个MFC正则表达式类,但无法找到它。

CString FormatDate(COleDateTime const& dateTime)
{
    // YYYY-MM-DD
    return dateTime.Format(_T("%Y-%m-%d"));
}

long ToLongDate(COleDateTime const& dateTime)
{
    return ((dateTime.GetYear() * 10000) +
        (dateTime.GetMonth() * 100) +
        dateTime.GetDay());
}

// the scanf way
long ToLongDate(CString const& dateText)
{
    int year = 0;
    int month = 0;
    int day = 0;

    if (_stscanf_s(dateText, _T("%d-%d-%d"), &year, &month, &day) != 3)
    {
        // invalid date - throw something?
    }

    COleDateTime dateTime{ year, month, day, 0, 0, 0 };
    //if (dateTime.GetStatus() == COleDateTime::DateTimeStatus::invalid)
    // invalid date - throw something?
    return ToLongDate(dateTime);
}

// The std::regex way - #include <regex>
long ToLongDate2(CString const& dateText)
{
    int year = 0;
    int month = 0;
    int day = 0;

    try
    {
        std::basic_regex<TCHAR> regularExpression(
            _T("^([0-9]{4})-([0-9]{2})-([0-9]{2})$"));
        std::match_results<LPCTSTR> match;

        if (std::regex_search(dateText.GetString(), match,
            regularExpression) && (match.size() == 4))
        {
            // [0] - is the entire string
            year = stoi(match[1].str());
            month = stoi(match[2].str());
            day = stoi(match[3].str());
        }
    }
    catch (std::exception& e)
    {
        // Do something with exception
    }

    COleDateTime dateTime{ year, month, day, 0, 0, 0 };
    //if (dateTime.GetStatus() == COleDateTime::DateTimeStatus::invalid)
    return ToLongDate(dateTime);
}