C ++ UnixTimestamp и читаемый формат времени

Я получаю метку времени в виде 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 рассчитывается обратно в читаемый формат.

Что мне здесь не хватает?! …

1

Решение

Ты получил не Unix TimeStamp, но TDateTime. Следующее из документации строителя:

Неотъемлемой частью значения TDateTime является количество дней, которые имеют
прошло с 30.12.1899. Дробная часть значения TDateTime
время суток.

В другом случае Unix TimeStump — это количество секунд с 01.01.1970

0

Другие решения

Вы могли бы попробовать Бесплатная библиотека Говарда Хиннанта с открытым исходным кодом, только заголовки, дата / время который расширяет 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
0

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);
0