 |
|
 |
I keep getting the wrong week number. It seems consistent if the previous year had 53 weeks. Noticed the inconsistency between the CMonthCtrl and your code. Is there an easy fix?
|
|
|
|
 |
|
 |
Gee... I never noticed that. I'll have a look.
Regards,
João Paulo Figueira
Embedded MVP
|
|
|
|
 |
 | Fix  |  | tom.schultz | 21:46 7 Apr '05 |
|
 |
I've been using this fix for some time, it works...
You did not take into the consideration that you'd have a week 53
void CDateTimeFormat::FormatWeek()
{
TCHAR szFmt[16];
int nDayOfYear = m_odt.GetDayOfYear(),
nWeek,
nfday,
dow;
COleDateTime odtFirst(m_odt.GetYear(), 1, 1, 0, 0, 0);
nWeek = ((nDayOfYear) / 7) + 1;
nfday = odtFirst.GetDayOfWeek();
dow = m_odt.GetDayOfWeek();
//Change weekday ordering, monday first (day 1), sunday(day 7)
if (nfday == 1) nfday = 7;
else
nfday --;
//Change weekday ordering, monday first (day 1), sunday(day 7)
if (dow == 1) dow = 7;
else
dow --;
//If week 53 exists, and we're on a thursday or later... (this is where the error would occur.)
if ( nfday >= 4 && dow > 4)
nWeek --;
switch(m_nw)
{
case 1:
swprintf(szFmt, _T("%d"), nWeek);
break;
case 2:
swprintf(szFmt, _T("%02d"), nWeek);
break;
default:
wcscpy(szFmt, _T("???"));
}
wcscat(m_pszBuf, szFmt);
}
Hope it helps someone.... just copy and paste.
|
|
|
|
 |
|
|
 |
|
 |
I just discovered a rather embarresing error in my "fix". I have now created my own class that will return the WeekOfYear. I'll paste the important code here, as a remedy (hopefully).
CDateTime CDateTime::GetDate1stDay1stWeek()
{
TCHAR szBuf[20];
CDateTime odt1stJan(this->GetYear(), 1, 1, 0, 0, 0);
CDateTime odt1stDay1stWeek;
COleDateTimeSpan span;
int n1stWoY;
int dow1stJan, n1stDayofWeek;
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IFIRSTWEEKOFYEAR, szBuf, sizeof(szBuf)/sizeof(TCHAR));
n1stWoY = _ttoi(szBuf);
GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK, szBuf, sizeof(szBuf)/sizeof(TCHAR));
n1stDayofWeek = _ttoi(szBuf);
dow1stJan = odt1stJan.GetDayOfWeek();
//convert to (mon(0) .. sun(6)) COleDateTime uses U.S or M$ standard.
if ( dow1stJan == 1)
dow1stJan = 6;
else
dow1stJan-=2;
//convertion done.
/*
0 Week containing 1/1 is the first week of that year.
1 First full week following 1/1 is the first week of that year
2 First week containing at least 4 days is the first week of that year.
*/
switch ( n1stWoY )
{
case 0 : //Week one always start in the week where 1.jan is.
if ( n1stDayofWeek > dow1stJan )
{
span.SetDateTimeSpan( 7 - (n1stDayofWeek - dow1stJan), 0,0,0 );
}
else
{
span.SetDateTimeSpan( (dow1stJan - n1stDayofWeek), 0,0,0 );
}
odt1stDay1stWeek = odt1stJan - span;
break;
case 1 : //First week containing only days from this year.
if ( dow1stJan == n1stDayofWeek)
odt1stDay1stWeek = odt1stJan;
else // find next full week.
{ //Find No. days to first day of next week.
span.SetDateTimeSpan( 7 + (n1stDayofWeek - dow1stJan), 0,0,0 );
odt1stDay1stWeek = odt1stJan + span;
}
break;
case 2 : //First week containing at least 4 days of current year.
if ( dow1stJan == n1stDayofWeek) //the whole week in this year.
odt1stDay1stWeek = odt1stJan;
else
{
int diff;
if (n1stDayofWeek > dow1stJan)
diff = (7 + dow1stJan) - n1stDayofWeek;
else
diff = dow1stJan - n1stDayofWeek;
if ( (diff <= 3) )
span.SetDateTimeSpan( -diff, 0,0,0 ); //correct week just adjust for first dow.
else
{
span.SetDateTimeSpan( 7 - diff, 0,0,0 ); //we need to skip to first day of next week.
}
odt1stDay1stWeek = odt1stJan + span;
}
break;
};
return odt1stDay1stWeek;
}
int CDateTime::GetWeekOfYear()
{
CDateTime Jan1stNxtYear( GetYear()+1, 01, 01, 00, 00, 00 );
CDateTime odt1stDay1stWeekNextYear = Jan1stNxtYear.GetDate1stDay1stWeek();
CDateTime odt1stDay1stWeek = GetDate1stDay1stWeek();
COleDateTimeSpan span, span1Day(1,0,0,0);
int nWeek(-1);
if ( odt1stDay1stWeek > (*this) )
{
CDateTime newYearsEve( GetYear() - 1, 12, 31, 00, 00, 00 );
nWeek = newYearsEve.GetWeekOfYear();
} else if ( odt1stDay1stWeekNextYear <= (*this) ) //we're in week 1.
{
nWeek = 1;
} else
{
span = (*this) - odt1stDay1stWeek; // find the span in days between (1day of 1st week) and current day.
nWeek = ( (span.GetDays() / 7) +1);
}
return nWeek;
}
//And format..
CString CDateTime::Format( LPCTSTR pFormat )
{
CDateTimeFormat frmt;
frmt.SetDateTime( (*this) );
frmt.SetFormat( pFormat );
return frmt.GetString();
}
now i change the Date Timeformatter to use my COleDateTime derived class instead. So the code reads.
void CDateTimeFormat::FormatWeek()
{
TCHAR szFmt[16];
switch(m_nw)
{
case 1:
swprintf(szFmt, _T("%d"), m_odt.GetWeekOfYear());
break;
case 2:
swprintf(szFmt, _T("%02d"), m_odt.GetWeekOfYear());
break;
default:
wcscpy(szFmt, _T("???"));
}
wcscat(m_pszBuf, szFmt);
}
-- modified at 7:36 Monday 20th March, 2006
|
|
|
|
 |
|
 |
the class doesnt get the 'seconds' and 'miliseconds' format.. how can i do that ?
Riki Risnandar
|
|
|
|
 |
|
 |
The seconds format is either 'ss' or 's'. There is no provision for milliseconds.
Regards,
João Paulo Figueira
Embedded MVP
|
|
|
|
 |
|
 |
I have problems in using date time picker control with Win 32 API programming. Can anybody help?
|
|
|
|
 |
|
|
 |
|
 |
... and much more...
bb |~ bb
|
|
|
|
 |
|
 |
Yeah, but I is not supported in the embedded version of the API for PocketPC (or so the documentation says). Maybe this should go to the embedded section...
|
|
|
|
 |
|
 |
I believe COleDateTime is supprted by WinCE. This class can do the same, if you don't mind using MFC that is.
|
|
|
|
 |
|
 |
You should be right according to the documentation. Unfortunately, MFC for CE 3.0 gives COleDateTime the same treatment as to CTime: no configurable formatting methods. If you look at the COleDateTime definition in MFC for CE 3.0 (in afxdisp.h), you will see the following code:
CString Format(DWORD dwFlags = 0, LCID lcid = LANG_USER_DEFAULT) const;
WCE_DEL CString Format(LPCTSTR lpszFormat) const;
WCE_DEL CString Format(UINT nFormatID) const;
The problem is that WCE_DEL expands to //...
|
|
|
|
 |
|
 |
Different objectves: in my program code I'll use the "strftime()" function that is more powerfull, but if I have to ask the format to the end user, I prefer this article solution because is more similar to the Excel/Access style format.
And, because I really have to create a "properties" dialog in my project with the display format preference... I'll use this article for sure!
Ps: Thank you João Paulo Figueira!
|
|
|
|
 |
|
 |
Agree. But if I have to use some "Excel" style format, I do a simple reformat of the parameter string getting the strftime control string by string replace.
This has many advantages: Very easy to localize (different languages) and still the power of strftime.
bb |~ bb
|
|
|
|
 |
|
 |
Thank you!
You just named all the reasons that lead me to write this one.
|
|
|
|
 |
|
 |
There is also CTime::Format()
|
|
|
|
 |
|
 |
This method is absent from MFC 3.0 for Windows CE 3.0. If you look at the class declaration in afx.h you will see something like:
WCE_DEL CString Format(LPCTSTR pFormat) const;
WCE_DEL CString FormatGmt(LPCTSTR pFormat) const;
WCE_DEL CString Format(UINT nFormatID) const;
WCE_DEL CString FormatGmt(UINT nFormatID) const;
The WCE_DEL expands to //... Thank you, Microsoft!
|
|
|
|
 |