logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[c][avr] porównanie dwóch dat

Maly216 09 Lip 2010 12:28 2688 5
REKLAMA
  • #1 8276638
    Maly216
    Poziom 11  
    Witam,

    Mój problem dotyczy ATmegi 128 (język C) i przedstawia się następująco: mam dwie daty (w każdej z nich zapisany jest rok, miesiąc, dzień, godzina, minuta, sekunda, milisekunda - w sumie 7 bajtów, rok to tylko końcówka do roku 2000) i chcę zrobić porównanie, która z tych dat jest większa. Można przeliczyć wszytko na milisekundy, dodać i porównać:
    long long data1_sum;
    
    data1_sum = 0;
    data1_sum += (long long)data1[milisekunda];
    data1_sum += (long long)data1[sekunda]*99;
    data1_sum += (long long)data1[minuta]*99*60;
    data1_sum += (long long)data1[godzina]*99*60*60;
    data1_sum += (long long)data1[dzien]*99*60*60*24;
    data1_sum += (long long)data1[miesiac]*99*60*60*24*30;
    data1_sum += (long long)data1[rok]*99*60*60*24*30*365;


    Jednak zajmuje to sporo czasu.

    Czy zna ktoś może bardziej optymalny sposób na porównanie tych dwóch dat?

    Pozdrawiam,
    maly216
  • REKLAMA
  • Pomocny post
    #2 8276680
    piotr_go
    Konstruktor DIY elektronika
    Jak masz w tablicy to porównuj w pętli zaczynając od roku.
    Większe, mniejsze, a jak równe to leć dalej z pętlą.
  • REKLAMA
  • #3 8278647
    michalko12
    Specjalista - Mikrokontrolery
    Błędem jest twój format daty, który nijak nie nadaje się do operacji matematycznych. Ja stosuję sekundowy format, 0 to 2000.01.01 00:00:00. Do tego procedury do konwersji i wszystkie operacje na dacie staja się łatwiejsze.
  • REKLAMA
  • #4 8279235
    tmf
    VIP Zasłużony dla elektroda
    A najprościej zapisać datę jako strukturę, całość mieści się w 32 bitach. Jest szybko, wygodnie i wydajnie:
    union CompactDateTime
    {
    	struct CDT
    	{
    		uint8_t	Second : 6;
    		uint8_t Minute : 6;
    		uint8_t Hour   : 5;
    		uint8_t Day	   : 5;
    		uint8_t Month  : 4;
    		uint8_t Year   : 6;
    	} cdt;
    
    	uint32_t bin;							
    };
  • REKLAMA
  • #5 8279265
    Konto nie istnieje
    Poziom 1  
  • #6 8282626
    Maly216
    Poziom 11  
    Dziękuje wszystkim za pomoc i podpowiedzi. Problem został rozwiązany dzięki piotr_go w ten oto sposób:

    data1_greater_then_data2 = false;
    
    for(unsigned char i = 0; i < 7; i++)
    {
    	if(data1[i] == data2[i]);
    	else
    	{
    		if(data1[i] > data2[i])
    		{
    			data1_greater_then_data2 = true;	
    		}
    		break;	
    	}
    }


    Zanim zastosowałem metodę wymnażania i przeliczania wszystkiego na milisekundy też próbowałem tego typu porównań tylko z małym błędem, który prowadził do złego rozwiązania - zagnieżdżałem porównania jedno w drugim:

    data1_greater_then_data2 = false;
    
    if(data1[rok] >= data2[rok])
    	if(data1[miesiac] >= data2[miesiac])
    		if(data1[dzien] >= data2[dzien])
    			if(data1[godzina] >= data2[godzina])
    				if(data1[minuta] >= data2[minuta])
    					if(data1[sekunda] >= data2[sekunda])
    						if(data1[milisekunda] >= data2[milisekunda])
    						data1_greater_then_data2 = true;


    i w przypadku np. takiego porównania godziny (ten sam dzień, miesiąc, rok) 11:07 (data1) z 10:49 (data2), wynikiem było, że godzina 10:49 jest godziną późniejszą, co jest nieprawdą.

    michalko12 co do formatu daty to mam go narzucony i nie mam możliwości zmiany.

    Co do proponowanej struktury przez tmf jak najbardziej masz rację, ale w moim przypadku stosowanie jej nie ma sensu, bo obie daty mam w buforach UART0 i UART1 w związku z czym bezsensem byłoby przepisywanie daty do tej struktury, porównania dokonuję bezpośrednio na danych w tych buforach.

    Pozdrawiam,
    maly216
REKLAMA