Sida 1 av 1

EPOCH konvertering

Postat: 20 maj 2014, 09:27:53
av Icecap
Ja, det finns ju UNIX-tid (EPOCH) som är sekunder sedan 1970-01-01 00:00:00. UNIX använder en 32-bit signed variabel för detta varför det blir problem 2038 där den variabel går till minus pga. overflow.

För att räkna med detta finns det <time.h> som man kan inkludera.

Men jag vill gärna ha sättet med sekundräknaren men jag vill ha det som unsigned DWORD vilket ger mig 138 års räkning. Samtidig vill jag kunde ställa starttidpunkten till ett - för mig - valfritt tidpunkt. Jag är mycket medveten om att detta inte gör systemet universellt användbart (om jag inte ställer startidpunkten till 1970-01-01 00:00:00) men jag anser att det ska vara så.

Självklart kan jag välja att ha en signed 64-bit variabel för tidräkningen, det ger ju runt 4.521.984 års räkning så att det blir problem runt år 4523954 - vilket känns rimligt avlägset - men detta betyder att om jag sparar insamlade data med tidstämpel i t.ex. EEPROM kommer varje punkt att ta 4 byte extra i onödan.

Alltså kör jag på med min tanke om en unsigned 32-bit sekundräknare som räknar sedan ett valfritt tidpunkt (just nu 2010-01-01 00:00:00).

Och nu kommer det egentliga problem: Det känns mer lättläst att se värden som 2014-05-20 09:12:10 och detta har jag redan en rutin för.
Den fungerar vid att börja med startåret och kolla antal dagar i det. Jag har rutin för att räkna ut skottår (och jag testade även att göra en macro som skapar en tabell över antal dagar/år) så det sker vid en succesiv uträkning:
1: Hur många hela år har det gått sedan startår?
2: Subtrahera det antal år i hela dagar * 24 * 60 * 60 (alltså antal sekunder).
3: Hur många hela månader har det gått?
4: Subtrahera det antal månader i hela dagar * 24 * 60 * 60 (alltså antal sekunder).
5: Antal dygn = (restvärdet / 24 * 60 *60).
6: Subtrahera antal dygn * 24 * 60 * 60.
7: Datum antalet dygn + 1.
8: Timme = restvärde / 60 * 60.
9: Subtrahera Timme * 60 * 60.
10: Minuter = restvärde / 60.
11: Subtrahera Minuter * 60.
12: Sekunder = restvärde.

Detta går ju ganska snabbt som sådan (32-bit µC på 50MHz) - men finns det en snabbare metod som jag har översett? (detta är alltså frågan)

Visst, en uppslagstabell med årsvärden kan vara en lösning, man kan t.o.m. stega upp detta till en uppslagstabell som går 138 år in i framtiden och som även innehåller månaderna (inkl. skottår), den kommer dock att använda 1656 DWORD och det känns lite mycket och jag undrar om jag kommer att vinna speciellt mycket tid på detta.

Och nej, lösningen är inte att bara inkludera <time.h> (som ju ger problem 2038, alltså om 24 år) - men jag funderar på att skapa liknande funktioner och kanske kopiera de funktioner som finns rakt av.

Jag har inget behov av att gå baklänges i tiden så en signed uträkning behövs inte. Hade det varit ett administrativt system hade det varit ganska annorlunda dock - men det är det inte!

Re: EPOCH konvertering

Postat: 20 maj 2014, 12:21:39
av blueint
Vet inte om metoden är snabbare. Men jag har använt tricket att dela antalet sekunder sedan 1970 med 1461 dagar. Heltalsdelen ger antalet år med en period på 4 år. Och divisionsresten (modulo) är då vilket av de 4 åren som är nu. Sedan får man se upp med skottsekunder som en del tillämpar och undantaget för skottdag år 2000.

Andra fallgropar är att sommartid gör att tiden inte matchar 1:1 korrekt.

Om du ändå är ute efter att spara utrymme så kanske du inte behöver full precision med 1 sekund? MS-DOS har bara en precision på 2 sekunder vill jag minnas.

Bara några ledtrådar iaf ;)

Re: EPOCH konvertering

Postat: 20 maj 2014, 12:28:31
av Icecap
blueint: intressant! Helt klart värd att ta med i det hela, det sparar ju ett antal uträkningar när tiderna börjar stiga.
Tack.

Och FYI: skottsekunder räknas inte med i EPOCH, de "bara händer".

EDIT: hoppla! Sitter och kollar lite i OpenOffice och det räknar jo internt med EPOCH-tid. Men 1900-01-01 00:00:00 har värdet av 2 dygn! Det har ju ingen betydelse i verkligheten men ändå var det lite kul att nollpunkten inte är noll.

Mer EDIT: Den uträkning (dela med 1461) fungerar inte utan kompensation! År 2100 kommer den att ge fel. Visst, man kan kompensera för detta men då ska man ändå köra igenom extra steg och då faller fördelen bort. Men fram till innan år 2100 fungerar det utmärkt.

Re: EPOCH konvertering

Postat: 20 maj 2014, 16:55:17
av Swech
Efter 2100 har nog iallafall supporten övergått till någon annan...
Swech