Funktion DateDiff() in WinApi?



  • In VB gibt es eine Funktion Namens DateDiff(...); die die Differenz zweier Datums oder Zeitangaben berechnet. Gibt es sowas auch für C++ in WinApi?
    Also um genau zu seien bräuchte ich sowas 😉

    Public Function DateID(DatTage As Date) As Long
    DateID = Abs(DateDiff("d", DatTage, "31.12.1899"))    'Ausgabe der Differenz der Tage
    End Function
    

    MfG schirrmie



  • So eine einfache Funktion gibt es da nicht. Du musst AFAIK:
    - die beiden Datumswerte voin SYSTEMTIME nach FILETIME umwandeln (SystemTimeToFileTime)
    - dann die beiden FILETIME-Werte in jeweils einen ULARGE_INTEGER kopieren (siehe Hilfe zu FILETIME)
    - dann diese beiden ULARGE_INTEGER voneinander abziehen
    - dann dieses wieder zurück in eine SYSTEMTIME umwandeln (FileTimeToSystemTime) oder von Hand die Anzahl der Tage aus dem FILETIME ausrechnen



  • Hmm das klingt ja schon mal vielversprechend.
    Aber wie bekomme ich das hin mit dem 31.12.1899? Mit SetSystemTime? Ich will ja aber nicht das Datum meines Rechners ändern?

    MfG schirrmie



  • schirrmie schrieb:

    Aber wie bekomme ich das hin mit dem 31.12.1899? Mit SetSystemTime? Ich will ja aber nicht das Datum meines Rechners ändern?

    Äh....

    SYSTEMTIME st;
      ZeroMemory(&st, sizeof(SYSTEMTIME));
      st.wYear = 1899;
      st.wMonth = 12;
      st.wDay = 31;
    

    ?



  • Hmm da hab ich wohl wieder zu weit gedacht 😃
    Danke 👍


  • Mod

    Wenn es sich um ein DATE Feld handelt kann man die Doubles einfach voneinander abziehen. Der Ganzzahlige Anteil sind Tage. Alles <1 ist der Brauchteil des Tages.
    COleDateTime kapselt die ganze Sosse. IMHO ist das Rechnen damit extremst einfacher als SYSTEMTIME etc.



  • Also ich bin jetzt schon ziemlich weiter (denk ich ;)) und es sieht so aus.

    int cSEdit::DateID(SYSTEMTIME st1)
    {
    	FILETIME ft1, ft2;
    	LARGE_INTEGER li;
    	SYSTEMTIME st2;
    	ZeroMemory(&st2, sizeof(SYSTEMTIME));
    	st2.wYear	= 1899;
    	st2.wMonth	= 12;
    	st2.wDay	= 31;
    	SystemTimeToFileTime(&st1, &ft1);
    	SystemTimeToFileTime(&st2, &ft2);
    
    	li.LowPart  = ft2.dwLowDateTime;
    	li.HighPart = ft2.dwHighDateTime;
    
    	((LARGE_INTEGER*)&ft1)->QuadPart -= li.QuadPart;
    	FileTimeToSystemTime(&ft1, &st1);
    	return 0;
    }
    

    Ich komm nur nicht mit der letzten Berechnung klar.
    Also wenn ich den heutigen Tag eingeben steht in st1 dann der 01.09.1707 drinn. Bloß wie bekomm ich die Differenz? Sie müsste 38958 sein?

    MfG schirrmie


  • Mod

    Das geht nicht. Du kannst die Differenz doch nicht einfach wieder zurückverwandeln in ein Datum!

    Zitat:
    The FILETIME data structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601

    Du musst den erhaltenen Wert entsprechend dividieren um die Anzahl derTage zu erhalten.
    Ich kann mich nur wiederholen. Die Arithmetik mit DATE/COleDateTime ist weitaus einfacher!



  • Hast recht, so wie das in der MSDN aussieht ist das genau das was ich brauche. Also danke nochmal.



  • Die reine WinAPI-Variante sieht so aus:

    #include <windows.h>
    #include <tchar.h>
    
    DWORD DiffInDays(SYSTEMTIME st1, SYSTEMTIME st2)
    {
      FILETIME ft1, ft2;
      SystemTimeToFileTime(&st1, &ft1);
      SystemTimeToFileTime(&st2, &ft2);
    
      LARGE_INTEGER li1;
      li1.LowPart  = ft1.dwLowDateTime;
      li1.HighPart = ft1.dwHighDateTime;
      LARGE_INTEGER li2;
      li2.LowPart  = ft2.dwLowDateTime;
      li2.HighPart = ft2.dwHighDateTime;
    
      LARGE_INTEGER li3;
      li3.QuadPart = li1.QuadPart - li2.QuadPart;
    
      li3.QuadPart /= 10; // => now us
      li3.QuadPart /= 1000; // now ms
      li3.QuadPart /= 1000; // now sec
      li3.QuadPart /= 60; // now min
      li3.QuadPart /= 60; // now h
      li3.QuadPart /= 24; // now days
    
      return li3.LowPart; 
    }
    
    int _tmain()
    {
      SYSTEMTIME st1;
      ZeroMemory(&st1, sizeof(SYSTEMTIME));
      st1.wYear = 1990;
      st1.wMonth = 1;
      st1.wDay = 10;
    
      SYSTEMTIME st2;
      ZeroMemory(&st2, sizeof(SYSTEMTIME));
      st2.wYear = 1990;
      st2.wMonth = 1;
      st2.wDay = 1;
    
      _tprintf(_T("%d"), DiffInDays(st1, st2)); 
      return 0;
    }
    

    Die MFC/COM Variante sieht so aus:

    COleDateTime dt1(1990, 1, 1, 0, 0, 0);
      COleDateTime dt2(1990, 1, 10, 0, 0, 0);
    
      COleDateTimeSpan diff;
      diff = dt2 - dt1;
      _tprintf(szTest, _T("%d"), (DWORD) diff.GetTotalDays());
    

    Die MFC/ATL Variante sieht so aus:

    CTime dt1(1990, 1, 1, 0, 0, 0);
      CTime dt2(1990, 1, 10, 0, 0, 0);
    
      CTimeSpan diff;
      diff = dt2 - dt1;
      TCHAR szTest[100];
      _stprintf(szTest, _T("%d"), (DWORD) diff.GetDays());
    

    Und die WinAPI/COM Variante sieht so aus:

    DWORD DiffInDays(SYSTEMTIME st1, SYSTEMTIME st2)
    {
      DOUBLE dbl1;
      SystemTimeToVariantTime(&st1, &dbl1);
      DOUBLE dbl2;
      SystemTimeToVariantTime(&st2, &dbl2);
    
      DOUBLE diff = dbl1 - dbl2;
      return (DWORD) diff;
    }
    
    int _tmain()
    {
      SYSTEMTIME st1;
      ZeroMemory(&st1, sizeof(SYSTEMTIME));
      st1.wYear = 1990;
      st1.wMonth = 1;
      st1.wDay = 10;
    
      SYSTEMTIME st2;
      ZeroMemory(&st2, sizeof(SYSTEMTIME));
      st2.wYear = 1990;
      st2.wMonth = 1;
      st2.wDay = 1;
    
      _tprintf(_T("%d"), DiffInDays(st1, st2)); 
      return 0;
    }
    


  • Ein herzlichen Dank an alle die mir geholfen haben. Nu kann ich mir ja eine Lösung aussuchen 😉

    MfG schirrmie


Anmelden zum Antworten