added new base type "DTM": date+time in minutes since 2009 (fixes #381)
This commit is contained in:
@@ -1,3 +1,13 @@
|
||||
# 21.3 (tbd)
|
||||
|
||||
## Bug Fixes
|
||||
* fix for escaping double quote in CSV format
|
||||
* adjusted helper shell scripts and Munin plugin to newer netcat
|
||||
|
||||
## Features
|
||||
* added DTM data type
|
||||
|
||||
|
||||
# 21.2 (2021-02-08)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
@@ -214,6 +214,7 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo
|
||||
size_t start = 0, count = length;
|
||||
int incr = 1;
|
||||
symbol_t symbol, last = 0, hour = 0;
|
||||
unsigned long minutes = 0;
|
||||
if (count == REMAIN_LEN && input.getDataSize() > offset) {
|
||||
count = input.getDataSize() - offset;
|
||||
} else if (offset + count > input.getDataSize()) {
|
||||
@@ -229,7 +230,7 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo
|
||||
}
|
||||
int type = (m_hasDate?2:0) | (m_hasTime?1:0);
|
||||
for (size_t index = start, i = 0; i < count; index += incr, i++) {
|
||||
if (length == 4 && i == 2 && m_hasDate) {
|
||||
if (length == 4 && i == 2 && m_hasDate && !m_hasTime) {
|
||||
continue; // skip weekday in between
|
||||
}
|
||||
symbol = input.dataAt(offset + index);
|
||||
@@ -331,6 +332,33 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo
|
||||
}
|
||||
*output << setw(2) << dec << setfill('0') << static_cast<unsigned>(symbol);
|
||||
break;
|
||||
|
||||
case 3: // date+time
|
||||
if (length != 4) {
|
||||
return RESULT_ERR_INVALID_POS;
|
||||
}
|
||||
// number of minutes since 01.01.2009
|
||||
minutes |= symbol*(1<<(8*i));
|
||||
if (i<3) {
|
||||
break;
|
||||
}
|
||||
int mjd = static_cast<int>(minutes/(24*60)) + 54832; // 01.01.2009
|
||||
int y = static_cast<int>((mjd-15078.2)/365.25);
|
||||
int m = static_cast<int>((mjd-14956.1-static_cast<int>(y*365.25))/30.6001);
|
||||
int d = mjd-14956-static_cast<int>(y*365.25)-static_cast<int>(m*30.6001);
|
||||
m--;
|
||||
if (m >= 13) {
|
||||
y++;
|
||||
m -= 12;
|
||||
}
|
||||
*output << dec << setfill('0') << setw(2) << static_cast<unsigned>(d) << "."
|
||||
<< setw(2) << static_cast<unsigned>(m) << "." << static_cast<unsigned>(y + 1900);
|
||||
m = minutes%(24*60);
|
||||
d = m/60;
|
||||
*output << " " << setw(2) << dec << setfill('0') << static_cast<unsigned>(d);
|
||||
m -= d*60;
|
||||
*output << ":" << setw(2) << dec << setfill('0') << static_cast<unsigned>(m);
|
||||
break;
|
||||
}
|
||||
last = symbol;
|
||||
}
|
||||
@@ -366,16 +394,16 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
||||
}
|
||||
result_t result;
|
||||
size_t i = 0, index;
|
||||
int type = (m_hasDate?2:0) | (m_hasTime?1:0);
|
||||
int type = m_hasDate ? 2 : (m_hasTime ? 1 : 0);
|
||||
bool skip = false;
|
||||
for (index = start; i < count; index += skip ? 0 : incr, i++) {
|
||||
skip = false;
|
||||
switch (type) {
|
||||
case 2: // date only
|
||||
if (length == 4 && i == 2) {
|
||||
if (length == 4 && i == 2 && !m_hasTime) {
|
||||
continue; // skip weekday in between
|
||||
}
|
||||
if (input->eof() || !getline(*input, token, '.')) {
|
||||
if (input->eof() || !getline(*input, token, m_hasTime && i==2 ? ' ' : '.')) {
|
||||
return RESULT_ERR_EOF; // incomplete
|
||||
}
|
||||
if (!hasFlag(REQ) && token == NULL_VALUE) {
|
||||
@@ -402,18 +430,29 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i + 1 == count) {
|
||||
if (i + 1 == (m_hasTime ? count-1 : count)) {
|
||||
if (length == 4) {
|
||||
// calculate local week day
|
||||
int y = (value < 100 ? value + 2000 : value) - 1900;
|
||||
int l = last <= 2 ? 1 : 0;
|
||||
int mjd = 14956 + lastLast + static_cast<int>((y-l)*365.25) + static_cast<int>((last+1+l*12)*30.6001);
|
||||
int daysSinceSunday = (mjd+3) % 7; // Sun=0
|
||||
if (m_hasTime) {
|
||||
if (mjd < 54832) { // 01.01.2009
|
||||
return RESULT_ERR_OUT_OF_RANGE; // invalid date
|
||||
}
|
||||
last = mjd - 54832;
|
||||
index = start + incr;
|
||||
i = 1;
|
||||
type = 1;
|
||||
skip = true; // switch to second pass for parsing the time
|
||||
} else {
|
||||
// calculate local week day
|
||||
int daysSinceSunday = (mjd + 3) % 7; // Sun=0
|
||||
if (hasFlag(BCD)) {
|
||||
output->dataAt(offset + index - incr) = (symbol_t)((6+daysSinceSunday) % 7); // Sun=0x06
|
||||
output->dataAt(offset + index - incr) = (symbol_t) ((6 + daysSinceSunday) % 7); // Sun=0x06
|
||||
} else {
|
||||
// Sun=0x07
|
||||
output->dataAt(offset + index - incr) = (symbol_t)(daysSinceSunday == 0 ? 7 : daysSinceSunday);
|
||||
output->dataAt(offset + index - incr) = (symbol_t) (daysSinceSunday == 0 ? 7 : daysSinceSunday);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (value >= 2000) {
|
||||
@@ -471,7 +510,24 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
||||
if (value > 24 * 6) {
|
||||
return RESULT_ERR_OUT_OF_RANGE; // invalid time
|
||||
}
|
||||
} else if (m_hasDate) {
|
||||
if (i + 1 == count) {
|
||||
last = (lastLast * 24 + last) * 60 + value;
|
||||
value = last & 0xff;
|
||||
last >>= 8;
|
||||
index = start;
|
||||
i = 0;
|
||||
type = 3;
|
||||
} else {
|
||||
last = lastLast;
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // date and time in store phase
|
||||
value = lastLast & 0xff;
|
||||
last = lastLast >> 8;
|
||||
break;
|
||||
}
|
||||
lastLast = last;
|
||||
@@ -940,6 +996,8 @@ DataTypeList::DataTypeList() {
|
||||
add(new DateTimeDataType("HDA", 24, 0, 0xff, true, false, 0));
|
||||
// date, days since 01.01.1900, 01.01.1900 - 06.06.2079 (0x00,0x00 - 0xff,0xff)
|
||||
add(new DateTimeDataType("DAY", 16, 0, 0xff, true, false, 0));
|
||||
// date+time in minutes since 01.01.2009, 01.01.2009 - 31.12.2099
|
||||
add(new DateTimeDataType("DTM", 32, REQ, 0x100, true, true, 0));
|
||||
// time in BCD, 00:00:00 - 23:59:59 (0x00,0x00,0x00 - 0x59,0x59,0x23)
|
||||
add(new DateTimeDataType("BTI", 24, BCD|REV, 0xff, false, true, 0));
|
||||
// time, 00:00:00 - 23:59:59 (0x00,0x00,0x00 - 0x17,0x3b,0x3b)
|
||||
|
||||
@@ -156,6 +156,9 @@ int main() {
|
||||
{"x,,day", "31.12.2078", "10fe07000262ff", "00", ""},
|
||||
{"x,,day", "-.-.-", "10fe070002ffff", "00", ""},
|
||||
{"x,,day", "", "10fe0700020000", "00", "Rw"},
|
||||
{"x,,dtm", "01.01.2009 00:00", "10fe07000400000000", "00", ""},
|
||||
{"x,,dtm", "31.12.2099 23:59", "10fe0700041f4eda02", "00", ""},
|
||||
{"x,,dtm", "16.12.2020 16:51", "10fe07000453f85f00", "00", ""},
|
||||
{"x,,bti", "21:04:58", "10fe070003580421", "00", ""},
|
||||
{"x,,bti", "00:00:00", "10fe070003000000", "00", ""},
|
||||
{"x,,bti", "23:59:59", "10fe070003595923", "00", ""},
|
||||
|
||||
Reference in New Issue
Block a user