ich brings einfach nicht fertig, die Kalenderwoche zu berechnen.
Und die Beispiele im Netz, die ich bisher fand, sind auch nicht
besser.
In .NET gibt es ja die Funktion GetWeekOfYear.
Diese habe ich (hoffentlich richtig) umgesetzt.
Nach dieses Methode wird z.B. der 31.12.2008 falsch berechnet.
(Ergibt 53. KW und nicht 1. KW)
Kennt jemand eine korrekte Funktion?
(arbeite immer noch mit VS6)
Tschüß, Holger.
int GetWeekOfYearFullDays(DATUMCLASS Datum, int firstDayOfWeek, int
fullDays)
{
int dayForJan1;
int offset;
int year, month, day;
year = Datum.Jahr;
dayForJan1 = (int)GetWochenTag(1, 1, Datum.Jahr);
//
// Calculate the number of days between the first day of year and the first
day of the first week.
//
offset = firstDayOfWeek - dayForJan1;
if (offset != 0)
{
if (offset < 0)
{
offset += 7;
}
//
// If the offset is greater than the value of fullDays, it means that
// the first week of the year starts on the week where Jan/1 falls on.
//
if (offset >= fullDays)
{
offset -= 7;
}
}
//
// Calculate the day of year for specified time by taking offset into
account.
//
day = GetTagImJahr(Datum.Tag, Datum.Monat, Datum.Jahr) - offset;
if (day > 0)
{
//
// If the day of year value is greater than zero, get the week of year.
//
return ((day - 1)/7 + 1);
}
//
// Otherwise, the specified time falls on the week of previous year.
// Call this method again by passing the last day of previous year.
//
Datum.Jahr--;
Datum.Monat=12;
Datum.Tag=31;
return (GetWeekOfYearFullDays(Datum, firstDayOfWeek, fullDays));
}
int GetKalenderwoche(int Tag, int Monat, int Jahr)
{
DATUMCLASS Datum;
Datum.Jahr=Jahr;
Datum.Monat=Monat;
Datum.Tag=Tag;
return GetWeekOfYearFullDays(Datum, 1, 4);
}
>ich brings einfach nicht fertig, die Kalenderwoche zu berechnen.
Jetzt geht das wieder los. :)
>Und die Beispiele im Netz, die ich bisher fand, sind auch nicht
>besser.
Wir hatten hier in der Gruppe erst vor einem halben Jahr oder so eine
laengliche Diskussion um das Thema. Mit diversen Beispielprogrammen und
allen Schikanen (im wahrsten Sinne des Wortes).
Um es kurz zu machen. Meine Lieblingsresource zur KW ist immernoch:
http://www.salesianer.de/util/kalwoch.html
Guck auch nochmal in den Thread hier:
http://groups-beta.google.com/group/microsoft.public.de.vc/browse_thread/thread/7123dcd5964b859f?num=20&as_scoring=r&as_umsgid=3a921c1a%2...@netnews.web.de
Ausserdem geb es mal einen Thread, wo wir diverse Routinen vorgestellt
haben. Das Ergebnis der basisdemokratischen Umfrage hatte ich auch mal
an Hotto gemailt, aber keine Reaktion. Ich muss zuhaus mal nachgucken,
ob ich das noch wiederfinde...
Carsten Witte [MVP]
--
mpdvc-FAQ: http://www.mpdvc.de
Newssuche: http://groups.google.com/advanced_group_search
Private : http://www.carsti.de/dmfc.html
Ich beantworte keine Fragen, die per e-mail eingehen!
>>ich brings einfach nicht fertig, die Kalenderwoche zu berechnen.
>
>
> Jetzt geht das wieder los. :)
Und bei der Gelegenheit kann ich meinen verbesserten Algorithmus hier
vorstellen, der sich an der aktuellen Locale ausrichtet. Denn jedes Land
berechnet ja seine KW anders... <veg>
int GetWeekOfYear(DATE date)
{
// Convert
COleDateTime datetime(date);
CLocale &rMyLocale = CLocale::Instance();
int iWeekOfYear = 0;
// dayOfWeek 0==Mon, 1==Tue, ... (respectively first day of week etc.)
int iYear = datetime.GetYear();
COleDateTime dDateFirstJanuary(iYear,1,1,0,0,0);
int iDayOfWeek =
(dDateFirstJanuary.GetDayOfWeek()+5+rMyLocale.m_iFirstDayOfWeek)%7;
/* Select mode
* 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 four days is the first week of
that year. */
switch (rMyLocale.m_iFirstWeekOfYear)
{
case 0:
{
// Week containing 1/1 is the first week of that year.
// check if this week reaches into the next year
dDateFirstJanuary = COleDateTime(iYear+1,1,1,0,0,0);
// Get start of week
iDayOfWeek =
(datetime.GetDayOfWeek()+5+rMyLocale.m_iFirstDayOfWeek)%7;
COleDateTime dStartOfWeek =
datetime-COleDateTimeSpan(iDayOfWeek,0,0,0);
// If this week spans over to 1/1 this is week 1
if (dStartOfWeek+COleDateTimeSpan(6,0,0,0)>=dDateFirstJanuary)
// we are in the last week of the year that spans over 1/1
iWeekOfYear = 1;
else
{
// Get week day of 1/1
dDateFirstJanuary = COleDateTime(iYear,1,1,0,0,0);
iDayOfWeek =
(dDateFirstJanuary.GetDayOfWeek()+5+rMyLocale.m_iFirstDayOfWeek)%7;
// Just count from 1/1
iWeekOfYear =
(int)(((datetime-dDateFirstJanuary).GetDays()+iDayOfWeek) / 7) + 1;
}
}
break;
case 1:
{
// First full week following 1/1 is the first week of that
year.
/* If the 1.1 is the start of the week everything is ok
* else we need the next week is the correct result */
iWeekOfYear =
(int)(((datetime-dDateFirstJanuary).GetDays()+iDayOfWeek) / 7) +
(iDayOfWeek==0 ? 1:0);
/* If we are in week 0 we are in the first not full week
* calculate from the last year */
if (iWeekOfYear==0)
{
/* Special case: we are in the week of 1.1 but 1.1. is
not on the
* start of week. Calculate based on the last year */
dDateFirstJanuary = COleDateTime(iYear-1,1,1,0,0,0);
iDayOfWeek =
(dDateFirstJanuary.GetDayOfWeek()+5+rMyLocale.m_iFirstDayOfWeek)%7;
/* and we correct this in the same we we done this
before but the result
* is now 52 or 53 and not 0 */
iWeekOfYear =
(int)(((datetime-dDateFirstJanuary).GetDays()+iDayOfWeek) / 7) +
(iDayOfWeek<=3 ? 1:0);
}
}
break;
case 2:
{
// First week containing at least four days is the first
week of that year.
/* Each year can start with any day of the week. But our
* weeks always start with monday. So we add the day of week
* before calculation of the final week of year.
* Rule: is the 1.1 a Mo,Tu,We,Th than the week starts on
the 1.1 with
* week==1, else a week later, so we add one for all those
days if
* day is less <=3 Mo,Tu,We,Th. Otherwise 1.1 is in the
last week of the
* previous year */
iWeekOfYear =
(int)(((datetime-dDateFirstJanuary).GetDays()+iDayOfWeek) / 7) +
(iDayOfWeek<=3 ? 1:0);
// Sonderfälle kontrollieren
if (iWeekOfYear==0)
{
/* special case week 0. We got a day before the 1.1,
2.1 or 3.1, were the
* 1.1. is not a Mo, Tu, We, Th. So the week 1 does not
start with the 1.1.
* So we calculate the week according to the 1.1 of the
year befor
*------------------------------------------------------------------*/
dDateFirstJanuary = COleDateTime(iYear-1,1,1,0,0,0);
iDayOfWeek =
(dDateFirstJanuary.GetDayOfWeek()+5+rMyLocale.m_iFirstDayOfWeek)%7;
/* and we correct this in the same we we done this
before but the result
* is now 52 or 53 and not 0 */
iWeekOfYear =
(int)(((datetime-dDateFirstJanuary).GetDays()+iDayOfWeek) / 7) +
(iDayOfWeek<=3 ? 1:0);
}
else if (iWeekOfYear==53)
{
/* special case week 53. Either we got the correct week
53 or we just got the
* week 1 of the next year. So ist the 1.1.(year+1)
also a Mo, Tu, We, Th than
* we alrady have the week 1, otherwise week 53 is correct
*------------------------------------------------------------------*/
dDateFirstJanuary = COleDateTime(iYear+1,1,1,0,0,0);
iDayOfWeek =
(dDateFirstJanuary.GetDayOfWeek()+5+rMyLocale.m_iFirstDayOfWeek)%7;
// 1.1. in week 1 or week 53?
iWeekOfYear = iDayOfWeek<=3 ? 1:53;
}
}
break;
default:
ASSERT(FALSE);
break;
}
// return result
return iWeekOfYear;
}
--
Martin Richter [MVP] WWJD
"In C we had to code our own bugs. In C++ we can inherit them."
FAQ : http://www.mpdvc.de
Samples: http://www.codeguru.com http://www.codeproject.com
deine Routine sieht einfach Klasse aus.
Habe zwar keine Infos zu CLocale gefunden (scheint
also deine private zu sein) und mußte raten,
was m_iFirstDayOfWeek bei uns ist. Aber mit 0
sieht alles ok aus.
Tschüß, Holger.
"Holger Gothan" <hol...@friedrich-datentechnik.de> schrieb im Newsbeitrag
news:31t6pgF...@individual.net...
Ruf GetLocaleInfo mit LCType = LOCALE_IFIRSTDAYOFWEEK auf,
für m_iFirstDayOfYear halt analog mit LCType =
LOCALE_IFIRSTDAYOFYEAR.
MfG
Andre Stille
> Ruf GetLocaleInfo mit LCType = LOCALE_IFIRSTDAYOFWEEK auf,
> für m_iFirstDayOfYear halt analog mit LCType =
> LOCALE_IFIRSTDAYOFYEAR.
Danke. Ich hatte dasselbe Problem wie Holger.
Nach Deiner Info sieht das ganze gut aus.
Na ja, dies war ja von Martin nicht anders zu erwarten :)
--
Gruß Alex
"Strebe nie nach Dingen, die auch Dümmeren gelingen" (Uli Stein)
FAQ,s : http://www.mpdvc.de
Samples: http://codeguru.developer.com http://www.codeproject.com
Anstand: news:de.newusers.infos www.learn.to/quote
Sorry! Ich war etwas schnell!
> CLocale &rMyLocale = CLocale::Instance();
Das ist eine kleine Thread-statische Klasse, die einige Infos aus der
Locale vorhält, ohne das ich die CRT oder die Win32 API bemühen muss.
Die Variablen, die hier benötigt werden sind wie folgt definiert:
int m_iFirstDayOfWeek, // 0==Monday
m_iFirstWeekOfYear; // 0==Week of 01.01,
// 1==first full week after 01.01,
// 2==week that is containing at least 4 days of the week
Sie werden folgendermaßen geladen (Pseudo-Code)
GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_IFIRSTDAYOFWEEK,m_iFirstDayOfWeek);
GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_IFIRSTWEEKOFYEAR,m_iFirstWeekOfYear);
>Sie werden folgendermaßen geladen (Pseudo-Code)
>GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_IFIRSTDAYOFWEEK,m_iFirstDayOfWeek);
>GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_IFIRSTWEEKOFYEAR,m_iFirstWeekOfYear);
Ich wuerde vorschlage, Du schenkst Deiner API noch 'nen Parameter. Um's
ins damalige Testprogramm einzupflegen, musste ich auf meiner englischen
Maschine doch was in der Art faken:
int GetWeekOfYear(..., LCID lcid= LOCALE_USER_DEFAULT);
und dann mit
LCID lcid=MAKELCID(
MAKELANGID(LANG_GERMAN,SUBLANG_GERMAN),
SORT_DEFAULT);
fuettern. Der Rechner muss ja nicht immer in dem Land stehen, in dem
fakturiert wird. Denk mal nur an die Offshores in Indien und Portugal.
Ansonsten liefert Dein Algoritmus, wie nicht anders erwartet, identische
Ergebnisse zur Vorgaengerversion. Wenn jemand interesse hat, kann ich
die aktualisierte Version wieder irgendwo uploaden, zur allgemeinen
Belustigung. ;)
Momentan liegt da noch die alte Version, ich kann erst heute abend
wieder zum FTP schreiten.