long timestamp to SYSTEMTIME



  • Um hier nochmal eine Lanze zu brechen: Das alles hat rein garnichts damit zu tun, dass Du C++ nie verstehen werden könntest, das hat noch nichtmal was mit C++ an sich zu tun. Wäre ULARGE_INTEGER eine schöne C++-Klasse, hätte sie (hoffentlich :D) Zuweisungs- und Rechenoperatoren, die sich benutzen liessen wie Du es hier versuchst. Nur leider ist ULARGE_INTEGER ein WinAPI-Bestandteil und damit übelstes C...



  • Vielen Dank!

    Jetzt bekomme ich die Methode allerdings nicht aufgerufen, hab schon 10-20 verschiedene Varianten versucht.
    Versuch des Aufrufs:

    SYSTEMTIME *datumZeitEnde = new SYSTEMTIME;
    GetLocalTime(datumZeitEnde);
    SYSTEMTIME d = systemtimeReduzieren(datumZeitEnde, getTaktAnzahlSekunden());
    

    Er meckert dann immer mit:

    error C2664: 'systemtimeReduzieren' : Konvertierung des Parameters 1 von 'struct _SYSTEMTIME *' in 'struct _SYSTEMTIME' nicht moeglich
    Quelltyp konnte von keinem Konstruktor angenommen werden, oder die Ueberladungsaufloesung des Konstruktors ist mehrdeutig
    error C2511: 'struct _SYSTEMTIME __thiscall CMainDlg::systemtimeReduzieren(struct _SYSTEMTIME &,int)' : Überladene Member-Funktion nicht in '<unbekannt>' gefunden

    Methode:

    SYSTEMTIME CMainDlg :: systemtimeReduzieren(SYSTEMTIME &datetime, int reduzierungAnzahlVonSekunden) {
    	// Deine Daten
    	SYSTEMTIME sys_time;
    	ULARGE_INTEGER time_to_subtract;
    	time_to_subtract.QuadPart = reduzierungAnzahlVonSekunden;
    
    	union
    	{
    		FILETIME ft;
    		ULARGE_INTEGER ts;
    	} t;
    
    	SystemTimeToFileTime(datetime, &t.ft );
    	t.ts.QuadPart -= (time_to_subtract * 10000000);
    	FileTimeToSystemTime( &t.ft, &sys_time );
    
    	return sys_time;
    }
    

    Wahrscheinlich nutze ich wieder & und * falsch. Aber das werde ich nie begreifen...



  • Du übergibst einen pointer wärend deine Funktion eine Referenz erwartet. Du brauchst hier auch gar keinen Pointer. Mach es doch so

    SYSTEMTIME datumZeitEnde;
    GetLocalTime(&datumZeitEnde);
    SYSTEMTIME d = systemtimeReduzieren(datumZeitEnde, getTaktAnzahlSekunden());
    


  • Danke. Hab das jetzt angepasst und es kompiliert. Allerdings hab ich dann in d genau das gleiche stehen wie datumZeitEnde, was ja eigentlich nicht sein soll.

    Aufruf:

    SYSTEMTIME d = systemtimeReduzieren(datumZeitEnde, 3600 );
    

    Methode:

    SYSTEMTIME CMainDlg :: systemtimeReduzieren(SYSTEMTIME &datetime, int reduzierungAnzahlVonSekunden) {
    	// Deine Daten
    	SYSTEMTIME sys_time;
    	ULARGE_INTEGER time_to_subtract;
    	time_to_subtract.QuadPart = reduzierungAnzahlVonSekunden;
    
    	union
    	{
    		FILETIME ft;
    		ULARGE_INTEGER ts;
    	} t;
    
    	SystemTimeToFileTime(&datetime, &t.ft );
    	time_to_subtract.QuadPart = time_to_subtract.QuadPart * 10000000;
    	t.ts.QuadPart -= time_to_subtract.QuadPart;
    	FileTimeToSystemTime( &t.ft, &sys_time );
    
    	return sys_time;
    }
    


  • Wahrscheinlich kommt er damit nicht klar, dass ich nur das Quad reduziere und bezieht das in der union nicht auf das filetime? Warum wendet man denn union eigentlich an? Das macht doch den Quellcode nicht gerade übersichtlicher?!



  • Hast du eventuell mal im Debugger verfolgt, was da eigentlich passiert?

    (btw, wenn du mit der MFC arbeitest, solltest du dir mal die Klasse CTime (und CTimeSpan) ansehen)



  • Jetzt gehts doch hab ne Kleinigkeit geändert aber statt einer Stunde zieht er nur 3 Minuten 45 Sekunden ab. Aber ich werd mal debuggen, mal schauen...



  • plizer schrieb:

    Warum wendet man denn union eigentlich an? Das macht doch den Quellcode nicht gerade übersichtlicher?!

    Die Struktur FILETIME besteht aus zwei 32-Bit-Werten, die den nieder- und höherwertigen Teil eines 64-Bit-Wertes repräsentieren. Damit lässt sich aber schlecht rechnen, mit der Union überschneiden sich der 64-Bit-Wert von ULARGE_INTEGER und die zwei 32-Bit-Werte, die beinhalten also die selben Werte, nur dass der Speicherbereich einmal als zwei 32-Bit-Werte angesehen wird (hier die FILETIME aus Sicht des Compilers) und gleichzeitig als ein 64-Bit-Wert (ULARGE_INTEGER). Das dient einfach dazu, dass man vernünftig Rechenoperationen durchführen kann 🙂

    Was hast du eigentlich verändert, dein geposteter Code sieht doch soweit korrekt aus?



  • Verstehe! Ich hab so einiges jetzt versucht. Wenn ich vom Quadpart z.B. (86400 * 10000000) abziehe, sollte das eigentlich 1 Tag sein! Es wird aber irgendwas um eine Minute abgezogen, multipliere ich den Wert mit 10, so kommt auch ähnliches raus, bei der Multiplikation mit 100 springt er aber direkt 3 Jahre (!) weiter! Irgendwie ist das alles für mich unlogisch. Das passt hinten und vorne nicht!



  • Ich hab den Fehler gefunden!

    Es ist ein Unterschied ob man 100.000.000 * 1.000 rechnet oder mit 100.000.000.000. Ich denke mal dass er bei der ersten Variante intern einen Typ wählt bei dem bei der Multiplikation ein Overflow zustande kommt, was bei Variante 2 nicht der Fall ist! Könnte ich damit richtig liegen?



  • Vermutlich ja - Zahlenliterale werden als int dargestellt, solange sie in einen int reinpassen. Und wenn das Produkt zweier int-Werte größer ist als INT_MAX, kommt's zum Überlauf.


Anmelden zum Antworten