Datum in KW umrechnen


  • Mod

    Din1355 ist aber nur ein Fall:

    Da hat jedes Land seine Spezialitäten siehe:

    GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_IFIRSTDAYOFWEEK,m_iFirstDayOfWeek­); 
    GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_IFIRSTWEEKOFYEAR,m_iFirstWeekOfYe­ar);
    

    Ich verwende COleDateTime basierend daruf gibt es hier den entsprechenden Code:
    http://groups.google.de/group/microsoft.public.de.vc/browse_frm/thread/6c8ac313341fc8ec/fae52b5758f4231a

    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; 
    }
    


  • Die Kalenderwoche auszurechnen ist nicht so einfach möglich, da es für jedes Land eine eigene Definition der "Kalenderwoche" gibt...

    Aus diesem Grunde gibt es GetLocaleInfo mit LOCALE_IFIRSTWEEKOFYEAR und LOCALE_IFIRSTDAYOFWEEK:
    http://blogs.msdn.com/michkap/archive/2005/11/14/492249.aspx
    http://msdn.microsoft.com/library/en-us/intl/nls_34rz.asp
    http://msdn.microsoft.com/library/en-us/intl/nls_8rse.asp

    Siehe auch:
    http://en.wikipedia.org/wiki/ISO_week_date

    ADD: Martin war wieder schneller 😉

    @AndyDD: Was hat Dein Posting mit dem Problem zu tun?



  • @Martin Richter: Stimmt, das ist länderspezifisch. Bin mal von Deutschland ausgegangen, da nichts anderes angegeben wurde.

    Ansonsten gilt (für Deutschland) die Regel: "Der erste Donnerstag im neuen Jahr liegt immer in der KW 1." Weiß nicht, ob Microsoft das anders sieht. Was ich damit sagen will: ich weiß nicht welche Berechnungsmodelle bei CString::Format() bzw. strftime() dahinterstecken.



  • Jochen Kalmbach schrieb:

    @AndyDD: Was hat Dein Posting mit dem Problem zu tun?

    Ich berechne die KW in meinen Programmen damit und hatte da noch nie Fehler. Damit könnte man das zweite Problem (also die Berechnung) lösen. Die Berechnung der KW steht in der Mitte. Da darin der Bezug auf weitere Funktionen gemacht wird hab ich halt alles gepostet. Die Formatierung des Datums muss natürlich noch gemacht werden (erstes Problem).


  • Mod

    Die CRT nimmt den entsprechenden Sonntag als Wochenbegin. Din Normen sind den Amerikanern seit jeher unbekannt. COleDateTime::Format verwendet srtftime!

    Du hast den CRT Code. Kein Problem da hinein zu sehen!



  • Martin Richter schrieb:

    Die CRT nimmt den entsprechenden Sonntag als Wochenbegin. Din Normen sind den Amerikanern seit jeher unbekannt. COleDateTime::Format verwendet srtftime!

    Du hast den CRT Code. Kein Problem da hinein zu sehen!

    Also doch selber berechnen. Ich hatte das ja schon vermutet. Außerdem muss die Woche mit Montag anfangen, da sonst der Donnerstag nicht in der Mitte der Woche liegt. Neben der DIN 1355 kann man auch mal in die ISO/R 2015-1971 reinschauen.


  • Mod

    Mein Algorithmus berücksichtigt alle Fälle des Gregorianischen Kalenders inkl. aller Nationalen Spezialitäten und Kombinationen.



  • Ich habe eine Frage zu Martin Richter's Code!
    Wie übergebe ich dort das Datum?
    Es kommen diverse Fehlermeldungen wenn ich den Code welcher du gepostet hast in mein Projekt einbinde! Brauche ich sonst noch etwas?


  • Mod

    1. Diese Funktion basiert auf COleDateTime.
    2. Diese Funktion ist aus meinem Produktivcode kopiert. Dort werden die Locale Daten in einem Singleton gehalten.
    m_iFirstWeekOfYear wird durch
    GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_IFIRSTWEEKOFYEAR,m_iFirstWeekOfYe­ar);
    m_iFirstDayOfWeek wird durch
    GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_IFIRSTDAYOFWEEK,m_iFirstDayOfWeek­);
    Ermittelt.

    Es ist kein echter CPP-Code (Copy-Paste-Programmer-Code) :xmas1:



  • Ach so... 😉
    Kein Wunder funktioniert dieser nicht 😛 (Gibt es Fehler) 😉
    Werde mal versuchen, das Ding zum Laufen zu bringen!
    Aber wie übergebe ich aber den "DATE date"? Anders gefragt, wie schreibe ich das Datum in einen DATE-Datentyp?

    Vielen Dank für die vielen Antworten!
    Frohe Festtage!


  • Mod

    Lesen.... COleDateTime ist ein guter Wrapper für DATE Datentypen!



  • Hi ich bin bereits ziemlich weit gekommen! Nur noch 27 Fehler im Code 😉
    Habe aber ein kleines Problem mit dieser Zeile:

    CLocale &rMyLocale
    

    Ich habe die Datei: "<locale.h>" eingefügt im Header, leider kennt er CLocale immer noch nicht! Ich benutze Visual Studio 2003, kann mir jemand sagen was ich noch includen muss, damit er die Definition kennt?


Anmelden zum Antworten