Я получаю метку времени в виде AnsiString из моей базы данных в моем приложении C ++.
Похоже, это «2017-09-12 09:35:10».
Теперь я хочу разобрать его обратно в метку времени Unix.
AnsiString myDate = Query->Fields->FieldByName("MyDates")->AsString;
TDateTime = StrToDateTime(myDate);
В моем конкретном случае я получаю следующую дату: 2017-08-10 08:43:35
Но Unixtimestamp, который я получаю: +42957,363599537
Который 01-01-1970 12:55:57 рассчитывается обратно в читаемый формат.
Что мне здесь не хватает?! …
Ты получил не Unix TimeStamp, но TDateTime
. Следующее из документации строителя:
Неотъемлемой частью значения TDateTime является количество дней, которые имеют
прошло с 30.12.1899. Дробная часть значения TDateTime
время суток.
В другом случае Unix TimeStump — это количество секунд с 01.01.1970
Вы могли бы попробовать Бесплатная библиотека Говарда Хиннанта с открытым исходным кодом, только заголовки, дата / время который расширяет C ++ 11 <chrono>
заголовок для обработки календарных вычислений.
#include "date.h"#include <iostream>
#include <sstream>
int
main()
{
std::istringstream in{"2017-08-10 08:43:35"};
date::sys_seconds Unixtimestamp;
in >> date::parse("%F %T", Unixtimestamp);
std::cout << Unixtimestamp.time_since_epoch().count() << '\n';
std::cout << date::format("%F %T\n", Unixtimestamp);
}
Выход:
1502354615
2017-08-10 08:43:35
C ++ Builder 6 и более поздние версии имеют DateTimeToUnix()
функция в DateUtils
единица измерения:
#include <SysUtils.hpp>
#include <DateUtils.hpp>
AnsiString myDateStr = Query->Fields->FieldByName("MyDates")->AsString;
TDateTime myDate = StrToDateTime(myDateStr);
__int64 myTimestamp = DateTimeToUnix(myDate);
Если вы используете C ++ Builder 5 или более раннюю версию, вы можете реализовать свой собственный DateTimeToUnix()
функционировать так:
#include <SysUtils.hpp>
// Days between TDateTime basis (12/31/1899) and Unix time_t basis (1/1/1970)
const __int64 UnixDateDelta = 25569;
__int64 DateTimeToMilliseconds(const TDateTime &ADateTime)
{
TTimeStamp LTimeStamp = DateTimeToTimeStamp(ADateTime);
return (__int64(LTimeStamp.Date) * MSecsPerDay) + LTimeStamp.Time;
}
__int64 DateTimeToUnix(const TDateTime &AValue)
{
__int64 Result = abs(DateTimeToMilliseconds(UnixDateDelta) - DateTimeToMilliseconds(AValue)) / MSecsPerSec;
if (AValue < UnixDateDelta)
Result = -Result;
return Result;
}
Также обратите внимание, что версия StrToDateTime()
вы используете в зависимости от текущих настроек языка пользователя для даты / времени. Поскольку вы имеете дело с очень конкретным форматом даты / времени, я предлагаю вам разобрать его вручную и не полагаться на какой-либо конкретный язык, например:
#include <SysUtils.hpp>
#include <stdio.h>
AnsiString myDateStr = Query->Fields->FieldByName("MyDates")->AsString;
Word wYear, wMonth, wDay, wHour, wMin, wSec;
sscanf(myDateStr.c_str(), "%hu-%hu-%hu %hu:%hu:%hu", &wYear, &wMonth, &wDay, &wHour, &wMin, &wSec);
TDateTime myDate = EncodeDate(wYear, wMonth, wDay) + EncodeTime(wHour, wMin, wSec, 0);
__int64 myTimestamp = DateTimeToUnix(myDate);
Если вы используете C ++ Builder 2006 или более позднюю версию, вы можете использовать перегруженную версию StrToDateTime()
который принимает TFormatSettings
структура как вход:
#include <SysUtils.hpp>
#include <DateUtils.hpp>
String myDateStr = Query->Fields->FieldByName("MyDates")->AsString;
TFormatSettings myFmt = TFormatSettings::Create();
myFmt.ShortDateFormat = _D("yyyy-mm-dd hh:nn:ss");
myFmt.DateSeparator = _D('-');
myFmt.TimeSeparator = _D(':');
TDateTime myDate = StrToDateTime(myDateStr, myFmt);
__int64 myTimestamp = DateTimeToUnix(myDate);