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

konwersja czasu UNIX na ludzką postać

rpal 27 Paź 2010 15:10 2758 13
REKLAMA
  • #1 8669982
    rpal
    Poziom 27  
    Nie mam pomysłu na zmianę czasu UNIX na dzień, miesiąc, rok. Z czasem poradziłem sobie błyskawicznie ale na datę nie mam żadnego pomysłu a zwłaszcza na lata przestępne i ten nieszczęsny luty. Jak rozróżnić że dany miesiąc ma 30 dni a nie 31 ? Należy porobić jakieś tablice czy jak ?
  • REKLAMA
  • #2 8670006
    mirekk36
    Poziom 42  
    void decode_time(unsigned long ntp_time, ntp_struct *dt)
    {
        unsigned long dayclock;
        unsigned int  dayno;
        unsigned char summertime;
    
        dt->year = EPOCH_YR; //=1970
        dayclock = (ntp_time - GETTIMEOFDAY_TO_NTP_OFFSET) % SECS_DAY;
        dayno    = (ntp_time - GETTIMEOFDAY_TO_NTP_OFFSET) / SECS_DAY;
    
        dt->second = dayclock % 60UL;
        dt->minute = (dayclock % 3600UL) / 60;
        dt->hour   = dayclock / 3600UL;
        dt->wday   = (dayno + 4) % 7;      // day 0 was a thursday
    
        while (dayno >= YEARSIZE(dt->year))
        {
            dayno -= YEARSIZE(dt->year);
            dt->year++;
        }
    
        dt->month = 0;
        while (dayno >= monthlen(LEAPYEAR(dt->year), dt->month))
        {
            dayno -= monthlen(LEAPYEAR(dt->year), dt->month);
            dt->month++;
        }
        dt->month ++;
        dt->day  = dayno+1;
    
        // Summertime
        summertime = 1;
        if (dt->month < 3 || dt->month > 10)     // month 1, 2, 11, 12
        {
            summertime = 0;                          // -> Winter
        }
    
        if ((dt->day - dt->wday >= 25) && (dt->wday || dt->hour >= 2))
        {                              // after last Sunday 2:00
            if (dt->month == 10)        // October -> Winter
            {
                summertime = 0;
            }
        }
        else
        {                              // before last Sunday 2:00
            if (dt->month == 3)        // March -> Winter
            {
                summertime = 0;
            }
        }
    
        if (summertime)
        {
            dt->hour++;              // add one hour
            if (dt->hour == 24)
            {                        // next day
                dt->hour = 0;
                dt->wday++;            // next weekday
                if (dt->wday == 7 )
                {
                    dt->wday = 0;
                }
                if (dt->day == monthlen(LEAPYEAR(dt->year), dt->month))
                {                // next month
                    dt->day = 0;
                    dt->month++;
                }
                dt->day++;
            }
        }
    
        strcpy_P(dt->datestr, &wday_str[dt->wday*3]);
        sprintf_P(dt->datestr+2, PSTR(" %u.%02u.%04u"), dt->day, dt->month, dt->year);
        sprintf_P(dt->timestr, PSTR("%2u:%02u:%02u"), dt->hour, dt->minute, dt->second);
    }
    


    do tego strukturka ;)

        typedef struct
        {
            unsigned char	second;
            unsigned char	minute;
            unsigned char	hour;
            unsigned char	day;
            unsigned char	wday;
            unsigned char	month;
            unsigned int	year;
            char	datestr[14];
            char	timestr[9];
        } ntp_struct;
  • #3 8670056
    rpal
    Poziom 27  
    no wszystko fajnie tylko co się kryje za nazwami pisanymi dużymi literami? to stałe? a może jakieś makra ?
  • REKLAMA
  • #4 8670064
    mirekk36
    Poziom 42  
    sorki:

    
        #define	EPOCH_YR	1970
        //(24L * 60L * 60L)
        #define	SECS_DAY	86400UL  
        #define	LEAPYEAR(year)	(!((year) % 4) && (((year) % 100) || !((year) % 400)))
        #define	YEARSIZE(year)	(LEAPYEAR(year) ? 366 : 365)
    
        // Number of seconds between 1-Jan-1900 and 1-Jan-1970, unix time starts 1970
        // and ntp time starts 1900.
        #define GETTIMEOFDAY_TO_NTP_OFFSET 2208988800UL
  • #5 8670086
    rpal
    Poziom 27  
    póki co dziękuję, zaraz sparwdzę co się za tym kryje. Te kopiowanie stałych z Flasha to do czegoś potrzebne ? Co tam jest ciekawego ukryte ?
    ja rozumiem że
    monthlen(LEAPYEAR(dt->year), dt->month);
    to funkcja zwracająca ilość dni w danym miesiącu ?
  • #6 8670105
    mirekk36
    Poziom 42  
    jakie kopiowanie stałych z Flasha? Sposób na pewno jest ok bo sam z niego korzystałem, to nie moja funkcja a zaporzyczona z pierwszego lepszego kawałka stosu TCP gdzie była obsługa NTP ;)
  • REKLAMA
  • #7 8670129
    rpal
    Poziom 27  
    strcpy_P(dt->datestr, &wday_str[dt->wday*3]); 
    
    to wół ? sorry porównanie ciągów ale przeprowadzanej na stałej z pamięci Flash. Jeszcze ten monthlen by się przydał kolego. Bo jak już cieszyć się czudzą pracą intelektualną to na całego :)
  • #8 8670151
    mirekk36
    Poziom 42  
    Oczywiście - to kod OpenSource więc żaden problem - jesli jeszcze czegoś zapomniałem to daj znać:

    PROGMEM char wday_str[] = "So\0Mo\0Di\0Mi\0Do\0Fr\0Sa";

    To nazwy dni z niemieckiego ;)

    Sonnabend, Montag, Dienstag, Mittwoch,Donnerstag i Samstag
    Niedziela , Pon , Wto ..... itd

    unsigned char monthlen(unsigned char isleapyear,unsigned char month)
    {
        if (month == 1)
        {
            return (28+isleapyear);
        }
    
        if (month > 6)
        {
            month--;
        }
    
        if (month %2 == 1)
        {
            return (30);
        }
    
        return (31);
    }
  • #9 8670183
    rpal
    Poziom 27  
    Dobrze że nadmieniłeś o tym niemiecki bo już miałem się pytać czy to w gwarze śląskiej było pisane, ale mnie ubiegłeś. Szybki jesteś kolego :))))

    Dodano po 13 [minuty]:

    coś jest nei tak z tym kodem bo przykładowo 2000000 zamienione przez Link daje 24 01 1970 03:33:20
    a wg tego kodu 01 03 2036 10:01:36 ciekawe czemu ?
  • #10 8670298
    mirekk36
    Poziom 42  
    teraz ci nie podpowiem co i jak bo bawiłem się pobieraniem czasu z serwera NTP jakiś czas temu, próbowałem zresztą kilku różnych stosików i wydaje mi się o ile dobrze pamiętam, że ten działał mi bardzo fajnie.

    Ale rzeczywiście wynik powinien być tak jak z tego linku co podajesz tak samo zresztą wychodzi mi z mojego programu w Delphi na PC ;) tzn tak jak z tego linku. Więc coś może mi się pomieszało - no ale z drugiej strony ja sam w ogóle nie bawiłem się wtedy w modyfikację tych funkcji i na LCD miałem dobry czas ....

    Dodano po 12 [minuty]:

    Ok, tak na szybko to jeszcze tu możesz się wspomóc w kwestii zamiany UnixTime :

    http://tuxgraphics.org/electronics/200710/avr-ntp-clock.shtml

    zassaj źródła i sprawdź jak jest robiona konwersja do wyświetlania na LCD

    ja właśnie też coś w tym stylu robiłem tyle że z innym stosem TCP
  • #11 8671201
    rpal
    Poziom 27  
    zaraz się tym pobawię zobaczę co z tego wyjdzie. Czym ja się tobie kolego zrewanżuję :) Może chcesz coś ode mnie ??? MOgę dać jakby co RDS-a o którego się bezskutecznie dopominałem a nikt jakoś nie chciał pomóc więc sam pomogłem sobie :) ?
  • Pomocny post
    #12 8671382
    mirekk36
    Poziom 42  
    rpal -> Na prawdę to nic wielkiego się nie stało ;) po to chyba jest forum i w ogóle net żeby sobie pomagać czasem prawda ? (jak bym kiedyś miał zająć się RDS'em to wiem kogo zapytać jeśli będę miał problemy, dzięki)
  • REKLAMA
  • #13 8672248
    michalko12
    Specjalista - Mikrokontrolery
    Czas na serwerach NTP jest liczbą sekund od 1900 roku
REKLAMA