EPOCH konvertering
Postat: 20 maj 2014, 09:27:53
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!
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!