Matematické Fórum

Nevíte-li si rady s jakýmkoliv matematickým problémem, toto místo je pro vás jako dělané.

Nástěnka
22. 8. 2021 (L) Přecházíme zpět na doménu forum.matweb.cz!
04.11.2016 (Jel.) Čtete, prosím, před vložení dotazu, děkuji!
23.10.2013 (Jel.) Zkuste před zadáním dotazu použít některý z online-nástrojů, konzultovat použití můžete v sekci CAS.

Nejste přihlášen(a). Přihlásit

#1 12. 01. 2012 10:42

Victronix
Zelenáč
Místo: Boskovice
Příspěvky: 14
Reputace:   
 

DT [s] od 1970 výpočet (Pascal)

Ahoj,
Programuji PLC automaty v Pascalu. Stačil by mi, ale i výpočet.
Jde o to, že potřebuji číslo, které vyjadřuje počet sekund od 1.1.1970.
Nechci žádné výpisy funkcí. Čistě výpočet, podle kterého bych mohl napsat program.
Díky.

Offline

  • (téma jako nevyřešené označil(a) Victronix)

#2 12. 01. 2012 11:46 — Editoval frank_horrigan (12. 01. 2012 11:46)

frank_horrigan
Příspěvky: 938
Reputace:   31 
 

Re: DT [s] od 1970 výpočet (Pascal)

Zdravím,

nejsem si zcela jistý (v pascalu), ale unixový čas by (myslím že zcela určitě) měla vracet nějaká rutina. Pokud takovou nenajdeš, nebo to chceš (spíš asi musíš) počítat sám, tak výpočet je jednoduchý:

Zjisti (na kalkulačce) a zaveď konstanty vyjadřující počet sekund za běžný a přestupný rok, počet sekund za dlouhý, krátký měsíc a únor, počet sekund za den, za hodinu a minutu.

Potom parsuj datum odzadu, tedy si zjistíš, kolik bylo v daném období  běžných a přestupných  celých let (vynásobíš konstantami), kolik bylo celých měsíců (dlouhých, krátkých, únorů, je tento rok přestupný?) v aktuálním roce, a kolik celých dní v "aktuálním měsíci", hodin v "aktuálním dni" a nakonec minut v "aktuální hodině". Pak tyto proměnné sečteš, a máš unixový čas...

Takhle popsané se to zdá složité, ale nic komplikovaného v tom nehledej :)


The only thing worse than being wrong is staying wrong
Sun Tzu - The Art of War

Offline

 

#3 12. 01. 2012 15:27

Victronix
Zelenáč
Místo: Boskovice
Příspěvky: 14
Reputace:   
 

Re: DT [s] od 1970 výpočet (Pascal)

Takže program je zřejmě hotov. Díky za nápady -> frank_horrigan

PROGRAM prg_RT_to_DT
(*477 přestupných let do 1970
1970 / 4 = 492,5 -
1970 / 100 = 19,7 +
1970 / 400 = 4,925 =
477*)
(*
86400s - den
Leden - 31
Unor - 28, 29 - prestupny
Brezen - 31
Duben - 30
Kveten - 31
Cerven - 30
Cervenec - 31
Srpen - 31
Zari - 30
Rijen - 31
Listopad - 30
Prosinec - 31
*)
VAR
(*Vstupy*)
    w_Y    :    WORD    :=    2012    ;    (*Zadaný rok*)
    w_Mo    :    WORD    :=    1    ;    (*Zadaný měsíc*)
    w_D    :    WORD    :=    12    ;    (*Zadaný den*)
    w_H    :    WORD    :=    15    ;    (*Zadaná hodina*)
    w_Mi    :    WORD    :=    20    ;    (*Zadaná minuta*)
    w_S    :    WORD    :=    45    ;    (*Zadaná sekunda*)

(*Výsledek*)
    dw_DT_S    :    DWORD    ;    (*Počet sekund od 1970*)

(*temp*)
    x_tmp_Y_Leap    :    BOOL    ;    (*Přestupný rok*)
    w_tmp_Leap_Ys    :    WORD    ;    (*Počet přestupných roků od 1970*)
    w_tmp_No_Leap_Ys    :    WORD    ;    (*Počet nepřestupných roků od 1970*)
    w_tmp_Y_minus_1    :    WORD    ;    (*Aktuální rok minus 1*)

END_VAR
VAR CONSTANT
    w_const_Leap_Ys_to_1970    :    WORD    :=    477    ;    (*Počet přestupných roků do 1970*)
    arr_const_Days_Left    :    ARRAY [1..12]    OF    WORD    :=    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334    ;    (*Pole uplynulých dní po měsících; nepřestupný rok*)

END_VAR



(*Je aktuální rok přestupný?*)


IF    (    (    w_Y    MOD    4    =    0    )    AND    (    w_Y    MOD    100    <>    0    )    )    OR
    (    w_Y    MOD    400    =    0    )    THEN
    x_tmp_Y_Leap    :=    TRUE    ;
ELSE
    x_tmp_Y_Leap    :=    FALSE    ;
END_IF

(*Počet přestupných roků před zadaným rokem "w_Y"*)
w_tmp_Y_minus_1    :=    w_Y    -    1    ;
w_tmp_Leap_Ys    :=    (    (    w_tmp_Y_minus_1    /    4    )    -    (    w_tmp_Y_minus_1    /    100    )    +    (    w_tmp_Y_minus_1    /    400    )    )    -    w_const_Leap_Ys_to_1970    ;

(*Počet nepřestupných roků před zadaným rokem "w_Y"*)
w_tmp_No_Leap_Ys    :=    (    w_Y    -    1970    )    -    w_tmp_Leap_Ys    ;

(*Počet sekund před zadaným rokem od 1970*)
dw_DT_S    :=    (    (    w_tmp_Leap_Ys    *    366    )    +    (    w_tmp_No_Leap_Ys    *    365    )    )    *    86400    ;

(*Pokud je zadaný měsíc více jak únor a je přestupný rok = přičíst jeden den*)
IF    (    w_Mo    >    2    )    AND    x_tmp_Y_Leap    THEN
    dw_DT_S    :=    dw_DT_S    +    86400    ;
END_IF

(*Přičíst měsíce a dny bez posledního dne*)
dw_DT_S    :=    dw_DT_S    +    (    (    arr_const_Days_Left    [w_Mo]    +    (    w_D    -    1    )    )    *    86400    )    ;

(*Přičíst hodiny, minuty, sekundy*)
dw_DT_S    :=    dw_DT_S    +    (    w_H    *    3600    )    +    (    w_Mi    *    60    )    +    w_S    ;

Offline

 

#4 12. 01. 2012 16:32

Victronix
Zelenáč
Místo: Boskovice
Příspěvky: 14
Reputace:   
 

Re: DT [s] od 1970 výpočet (Pascal)

Abych někomu neublížil, použil jsem část nápadu ze zdrojového kódu: http://www.mbari.org/staff/rich/utccalc.htm
Tak ještě úprava programu a přetvoření do funkce:

FUNCTION fun_RT_to_DT : DWORD
VAR_INPUT
    w_Y    :    WORD    :=    2012    ;    (*Zadaný rok*)
    w_Mo    :    WORD    :=    1    ;    (*Zadaný měsíc*)
    w_D    :    WORD    :=    12    ;    (*Zadaný den*)
    w_H    :    WORD    :=    15    ;    (*Zadaná hodina*)
    w_Mi    :    WORD    :=    20    ;    (*Zadaná minuta*)
    w_S    :    WORD    :=    45    ;    (*Zadaná sekunda*)
END_VAR
VAR
(*temp*)
    x_tmp_Y_Leap    :    BOOL    ;    (*Přestupný rok*)
    w_tmp_Leap_Ys    :    WORD    ;    (*Počet přestupných roků od 1970*)
    w_tmp_No_Leap_Ys    :    WORD    ;    (*Počet nepřestupných roků od 1970*)
    w_tmp_Y_minus_1    :    WORD    ;    (*Aktuální rok minus 1*)
END_VAR
VAR CONSTANT
(*477 přestupných let do 1970
1970 / 4 = 492,5 -
1970 / 100 = 19,7 +
1970 / 400 = 4,925 =
477*)
    w_const_Leap_Ys_to_1970    :    WORD    :=    477    ;    (*Počet přestupných roků do 1970*)
(*Leden - 31; Unor - 28, 29 - prestupny; Brezen - 31; Duben - 30; Kveten - 31; Cerven - 30; Cervenec - 31; Srpen - 31; Zari - 30; Rijen - 31; Listopad - 30; Prosinec - 31*)
    arr_const_Days_Left    :    ARRAY [1..12]    OF    WORD    :=    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334    ;    (*Pole uplynulých dní po měsících; nepřestupný rok*)
    dw_const_Seconds_a_Day    :    DWORD    :=    86400    ;    (*Počet sekund za den*)
END_VAR

(*Je aktuální rok přestupný?*)
x_tmp_Y_Leap    :=    (    (    w_Y    MOD    4    =    0    )    AND    (    w_Y    MOD    100    <>    0    )    )    OR    (    w_Y    MOD    400    =    0    )    ;

(*Počet přestupných roků před zadaným rokem "w_Y"*)
w_tmp_Y_minus_1    :=    w_Y    -    1    ;
w_tmp_Leap_Ys    :=    (    (    w_tmp_Y_minus_1    /    4    )    -    (    w_tmp_Y_minus_1    /    100    )    +    (    w_tmp_Y_minus_1    /    400    )    )    -    w_const_Leap_Ys_to_1970    ;

(*Počet nepřestupných roků před zadaným rokem "w_Y"*)
w_tmp_No_Leap_Ys    :=    (    w_Y    -    1970    )    -    w_tmp_Leap_Ys    ;

(*Počet sekund před zadaným rokem od 1970*)
fun_RT_to_DT    :=    (    (    w_tmp_Leap_Ys    *    366    )    +    (    w_tmp_No_Leap_Ys    *    365    )    )    *    dw_const_Seconds_a_Day    ;

(*Pokud je zadaný měsíc více jak únor a je přestupný rok = přičíst jeden den*)
IF    (    w_Mo    >    2    )    AND    x_tmp_Y_Leap    THEN
    fun_RT_to_DT    :=    fun_RT_to_DT    +    dw_const_Seconds_a_Day    ;
END_IF

(*Přičíst měsíce a dny bez posledního dne*)
fun_RT_to_DT    :=    fun_RT_to_DT    +    (    (    arr_const_Days_Left    [w_Mo]    +    (    w_D    -    1    )    )    *    dw_const_Seconds_a_Day    )    ;

(*Přičíst hodiny, minuty, sekundy*)
fun_RT_to_DT    :=    fun_RT_to_DT    +    (    w_H    *    3600    )    +    (    w_Mi    *    60    )    +    w_S    ;

Offline

 

#5 13. 01. 2012 03:46

RePRO
Místo: Jihlava
Příspěvky: 363
Škola: AI VŠPJ (09-12, Bc.)
Pozice: programátor
Reputace:   11 
Web
 

Re: DT [s] od 1970 výpočet (Pascal)

Zdravím,
výborný. Kdybys dal kód ještě do sekce code, bylo by to ještě lepší. ;)


Srdcem trochu-programátor, duší rádoby-matematik a povoláním analytik-vývojář.

Offline

 

#6 20. 11. 2014 09:07

Victronix
Zelenáč
Místo: Boskovice
Příspěvky: 14
Reputace:   
 

Re: DT [s] od 1970 výpočet (Pascal)

Náhodou nemáte někdo zpětnou konverzi?

Offline

 

#7 20. 11. 2014 21:50

mák
Místo: Vesmír, Galaxie MD
Příspěvky: 868
Reputace:   62 
 

Re: DT [s] od 1970 výpočet (Pascal)

Zdravím,
výpočet ti budou komplikovat přestupné sekundy.


LibreOffice Verze: 7.6.6.3, Maxima 5.47.0 (SBCL)

Offline

 

#8 20. 11. 2014 22:41

Victronix
Zelenáč
Místo: Boskovice
Příspěvky: 14
Reputace:   
 

Re: DT [s] od 1970 výpočet (Pascal)

↑ mák:
Je to složitá otázka.
PLC wago 881 má funkci RTCGetTimeDate. Výstupem funkce je hodnota ve formátu DT (DATE_AND_TIME).
Převodem (funkce DT_TO_DWORD) na Double word dostaneme počet sekund od 1970.
RTCSetTimeDate zase uloží DT do reálných hodin. Pokud toto nastavení bude v rámci PLC, tak je mi jedno nějaká sekunda.
Problémem je, že PLC má možnost automatické synchronizace s volitelným time serverem.
A pak nastane rozdíl...

Offline

 

Zápatí

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson