Convert TDateTime to Unix TimeStamp

tech • 252 słowa • 2 minuty czytania

O tym, że “gardzę” językami pascalowatymi i nie lubię Borlanda niektórzy pewnie wiedzą. Żyjemy sobie w błogiej świadomości, że nie będziemy mieć żadnej styczności z Delphi, czy wymysłami Borlanda, a tu nagle krach. Otrzymywane dane z jakiegoś źródła, bądź gdzieś wysyłane musza być zapisane w nad wyraz pięknym formacie TDateTime.

Zabić to mało…

Na szczęście można w łatwy sposób przekonwertować dziwny format TDateTime (8 bajtów) na coś bardziej ludzkiego - unixowy timestamp (4 bajty).

TDateTime - borlandowski typ służący do przechowywania daty i czasu, jaki upłynął od 30 grudnia 1899 roku. Jest to nic innego jak typ double, gdzie część całkowita określa datę (liczbę dni od 30 grudnia 1899 roku), a część ułamkowa czas.

type TDateTime = type Double;

Unix TimeStamp - uniksowy znacznik czasu, 32-bitowa zmienna typu całkowitego ze znakiem zawierająca liczbę sekund, które upłynęły od rozpoczęcia epoki uniksowej, czyli od 1 stycznia 1970, godz. 0:00.

Konwersja nie jest taka trudna jakby się mogło na początku wydawać. Wystarczy od wartości TDateTime odjąć offset między 30 grudnia 1899 a 1 stycznia 1970 i wynik pomnożyć przez ilość sekund w dobie. W ten sposób otrzymamy liczbę sekund od 1970. W sieci można znaleźć kilka podobnych rozwiązań.

Poniżej trochę mojego kodu. Funkcje najlepiej deklarować jako inline, aby zostały rozwinięte w miejscu wywołania.

#include <math.h>

inline int TDateTime2UnixTimeStamp(double datetime) {
	return (int)round((datetime - 25569.0) * 86400);
}

inline double UnixTimeStamp2TDateTime(int timestamp) {
	return (timestamp / 86400) + 25569.0;
}

W przypadku problemów z round, wynikających z starszych implementacji sprzed standardu C99, można użyć funkcji ceil.

Komentarze (5)

zwierzak avatar
zwierzak
20070730-030122-zwierzak

Osobiście kiedyś pisałem w BCB, jednak od kilku dobrych lat bierze mnie wielka niechęć do ichniejszych rozwiązań.

Sam sposób zapisywania daty to porażka, chociaż ostatnio POSIX przeszedł na 8 bitowy zapis daty, z powodu kończenia się limitu zmiennej. Porada na pewno się przyda

MalCom avatar
MalCom
20070730-031836-malcom

Rozumiem, że miałeś na myśli 8 bajtów (64-bity) :P

zwierzak avatar
zwierzak
20070730-171639-zwierzak

Dokładnie, trochę źle mi się to napisało. Ale wiadomo o co chodzi. na szczęście kolejnego powiększenia wielkości tej zmiennej już nie doczekamy.

MalCom avatar
MalCom
20070730-213601-malcom

Podoba mi się ten cytat z wikipedii:

Zapobiec mu może przejście na 64-bitową reprezentację czasu (typ time_t), dla której analogiczny problem pojawi się dopiero w roku 292 277 026 596 (czyli za około 292 miliardy lat) - nie będzie to jednak sprawa nagląca.

Sprawa nagląca :)

Dodaj komentarz

/dozwolony markdown/

/nie zostanie opublikowany/