Files
qt6-migration-pipeline/Z/src/ngltools/ngltools_dtg.cpp
T
2026-07-14 12:07:36 +02:00

373 lines
7.8 KiB
C++
Executable File

#include "ngltools_dtg.h"
#include <QString>
#include <QDateTime>
namespace DTG
{
static char s_timezone = 'Z';
static char s_userDefinedTimezone = s_timezone;
static char s_exerciseDefaultTimezone = s_timezone;
int timezone2Hours(char tz, bool *bOk)
{
if (!isTimezoneValid(tz))
{
if (bOk)
*bOk = false;
return 0;
}
if (bOk)
*bOk = true;
if (tz < 'J')
return tz - 'A' + 1;
if (tz < 'N')
return tz - 'A';
if (tz < 'Z')
return 'Z' - tz - 13;
return 0;
}
int timezone2Secs(char tz, bool *bOk)
{
return 3600 * timezone2Hours(tz, bOk) ;
}
bool setTimezone(char tz, bool bUserDefinedZone)
{
if (!isTimezoneValid(tz))
{
if (!(tz == 0 && bUserDefinedZone))
return false;
}
if (bUserDefinedZone)
s_userDefinedTimezone = tz;
else
s_exerciseDefaultTimezone = tz;
s_timezone = s_userDefinedTimezone != 0 ? s_userDefinedTimezone : s_exerciseDefaultTimezone;
return true;
}
char timezone()
{
return s_timezone;
}
char timezoneUserDefined()
{
return s_userDefinedTimezone;
}
char timezoneExerciseDefault()
{
return s_exerciseDefaultTimezone;
}
bool isTimezoneValid(char tz)
{
tz = toupper(tz);
return !(tz < 'A' || tz == 'J' || tz > 'Z');
}
static DateTimeType s_dateTimeType = DDMMYYYY_Z_HHMMSS;
static DisplayFormat s_defaultDisplayFormat = Long;
void setDateTimeType(DateTimeType dtType)
{
s_dateTimeType = dtType;
}
DateTimeType dateTimeType()
{
return s_dateTimeType;
}
void setDefaultDisplayFormat(DisplayFormat dtFormat)
{
s_defaultDisplayFormat = dtFormat;
}
DisplayFormat defaultDisplayFormat()
{
return s_defaultDisplayFormat;
}
QString toString(const QDateTime &dt, DisplayFormat format, DateTimeType type)
{
if (format == Default)
format = s_defaultDisplayFormat;
static const QDateTime dtNull = QDateTime::fromSecsSinceEpoch(0);
if (!dt.isValid() || dt == dtNull)
return QString();
const QDateTime dateTime = dt.toUTC().addSecs(timezone2Hours(s_timezone) * 3600);
QString ret;
switch (type)
{
case DTG:
{
QString str1;
if (format == Long)
str1 = dateTime.toString(QLatin1String("dd hhmmss"));
else if (format == TurboLong)
str1 = dateTime.toString(QLatin1String("dd hhmmss.z"));
else
{
ret = dateTime.toString(QLatin1String("ddhhmm")) + QLatin1Char(s_timezone);
break;
}
const int month = dateTime.date().month() - 1;
const int year = dateTime.date().year() - 2000;
ret = QStringLiteral("%1 %2 %3 %4")
.arg(str1)
.arg(QLatin1Char(s_timezone))
.arg(months().at(month))
.arg(year, 2, 10, QLatin1Char('0'));
}
break;
case DDMMYYYY_HHMMSS_Z:
{
if (format == Long)
ret = dateTime.toString(QLatin1String("dd.MM.yyyy HH:mm:ss")) + QLatin1Char(s_timezone);
else
ret = dateTime.toString(QLatin1String("dd.MM HH:mm")) + QLatin1Char(s_timezone);
}
break;
case DDMMYYYY_Z_HHMMSS:
if (format == Long)
ret = dateTime.toString(QLatin1String("dd.MM.yyyy "))
+ QLatin1Char(s_timezone)
+ dateTime.toString(QLatin1String(" HH:mm:ss"));
else
ret = dateTime.toString(QLatin1String("dd.MM "))
+ QLatin1Char(s_timezone)
+ dateTime.toString(QLatin1String(" HH:mm"));
break;
}
return ret;
}
QString toStringMSec(qint64 msecSinceEpoch, DisplayFormat format)
{
if (msecSinceEpoch <= 0)
return QString();
return toString(QDateTime::fromMSecsSinceEpoch(msecSinceEpoch), format);
}
static bool check24(const QChar *input, int *output)
{
const int i1 = input[0].unicode() - '0';
const int i2 = input[1].unicode() - '0';
if (i1 > 2)
return false;
if (i1 == 2 && i2 > 5)
return false;
if (output)
*output = i1 * 10 + i2;
return true;
}
static bool check31(const QChar *input, int *output = nullptr)
{
const int i1 = input[0].unicode() - '0';
const int i2 = input[1].unicode() - '0';
if (i1 > 3)
return false;
if (i1 == 3 && i2 > 1)
return false;
if (output)
*output = i1 * 10 + i2;
return true;
}
static bool check60(const QChar *input, int *output)
{
const int i1 = input[0].unicode() - '0';
const int i2 = input[1].unicode() - '0';
if (i1 > 5)
return false;
if (output)
*output = i1 * 10 + i2;
return true;
}
static DTGValidation validate18(const QString &input, QDateTime &dt)
{
int hh, mm, ss;
for (int i = 0; i < 2; ++i)
{
if (!input[i].isDigit())
return Invalid;
}
if (!check31(&input.data() [0]))
return Invalid;
if (input[2] != QLatin1Char(' '))
return Invalid;
if (input.length() == 7)
{
for (int i = 3; i < 7; ++i)
{
if (!input[i].isDigit())
return Invalid;
}
return Intermediate;
}
for (int i = 3; i < 9; ++i)
{
if (!input[i].isDigit())
return Invalid;
}
if (!check24(&input.data() [3], &hh))
return Invalid;
if (!check60(&input.data() [5], &mm))
return Invalid;
if (!check60(&input.data() [7], &ss))
return Invalid;
if (input[9] != QLatin1Char(' '))
return Invalid;
const QChar c = input[10];
if (c < QLatin1Char('A') || c > QLatin1Char('Z'))
return Invalid;
if (c == QLatin1Char('J'))
{
return Invalid;
}
const QString mon = input.mid(12, 3);
int month = months().indexOf(mon);
if (month < 0)
{
return Invalid;
}
for (int i = 16; i < 18; ++i)
{
if (!input[i].isDigit())
return Invalid;
}
const int day = input.leftRef(2).toInt();
const int year = input.midRef(16, 2).toInt() + 2000;
dt = QDateTime(QDate(year, month + 1, day), QTime(hh, mm, ss), Qt::UTC);
if (!dt.isValid())
{
return Invalid;
}
dt = dt.addSecs(-timezone2Hours(c.toLatin1()) * 3600);
return Acceptable;
}
static DTGValidation validate7(const QString &input, QDateTime &dt)
{
int hh, mm;
for (int i = 0; i < 6; ++i)
{
if (!input[i].isDigit())
return Invalid;
}
if (!check31(&input.data() [0]))
return Invalid;
if (!check24(&input.data() [2], &hh))
return Invalid;
if (!check60(&input.data() [4], &mm))
return Invalid;
const QChar c = input[6];
if (c < QLatin1Char('A') || c > QLatin1Char('Z'))
return Invalid;
if (c == QLatin1Char('J'))
{
return Invalid;
}
const int day = input.leftRef(2).toInt();
const QDate curDate = QDate::currentDate();
dt = QDateTime(QDate(curDate.year(), curDate.month(), day), QTime(hh, mm), Qt::UTC);
if (!dt.isValid())
{
return Invalid;
}
dt = dt.addSecs(-timezone2Hours(c.toLatin1()) * 3600);
return Acceptable;
}
QDateTime fromDTGString(const QString &str, bool *bOk)
{
if (bOk)
*bOk = false;
QDateTime dt;
if (str.length() == 7)
{
DTGValidation state = validate7(str, dt);
if (state == Acceptable && bOk)
*bOk = true;
}
else if (str.length() == 18)
{
DTGValidation state = validate18(str, dt);
if (state == Acceptable && bOk)
*bOk = true;
}
return dt;
}
DTGValidation validateString(const QString &str, QDateTime &dt)
{
const int len = str.length();
if (len == 7 || len == 18)
{
if (len == 18 || (str[2] == QLatin1Char(' ')))
return validate18(str, dt);
return validate7(str, dt);
}
return Invalid;
}
QStringList months()
{
return {
QLatin1String("jan"), QLatin1String("feb"), QLatin1String("mar"),
QLatin1String("apr"), QLatin1String("may"), QLatin1String("jun"),
QLatin1String("jul"), QLatin1String("aug"), QLatin1String("sep"),
QLatin1String("oct"), QLatin1String("nov"), QLatin1String("dec")
};
}
}