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)
|
# 21.2 (2021-02-08)
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ result_t DateTimeDataType::readSymbols(size_t offset, size_t length, const Symbo
|
|||||||
size_t start = 0, count = length;
|
size_t start = 0, count = length;
|
||||||
int incr = 1;
|
int incr = 1;
|
||||||
symbol_t symbol, last = 0, hour = 0;
|
symbol_t symbol, last = 0, hour = 0;
|
||||||
|
unsigned long minutes = 0;
|
||||||
if (count == REMAIN_LEN && input.getDataSize() > offset) {
|
if (count == REMAIN_LEN && input.getDataSize() > offset) {
|
||||||
count = input.getDataSize() - offset;
|
count = input.getDataSize() - offset;
|
||||||
} else if (offset + count > input.getDataSize()) {
|
} 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);
|
int type = (m_hasDate?2:0) | (m_hasTime?1:0);
|
||||||
for (size_t index = start, i = 0; i < count; index += incr, i++) {
|
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
|
continue; // skip weekday in between
|
||||||
}
|
}
|
||||||
symbol = input.dataAt(offset + index);
|
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);
|
*output << setw(2) << dec << setfill('0') << static_cast<unsigned>(symbol);
|
||||||
break;
|
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;
|
last = symbol;
|
||||||
}
|
}
|
||||||
@@ -366,16 +394,16 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
|||||||
}
|
}
|
||||||
result_t result;
|
result_t result;
|
||||||
size_t i = 0, index;
|
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;
|
bool skip = false;
|
||||||
for (index = start; i < count; index += skip ? 0 : incr, i++) {
|
for (index = start; i < count; index += skip ? 0 : incr, i++) {
|
||||||
skip = false;
|
skip = false;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 2: // date only
|
case 2: // date only
|
||||||
if (length == 4 && i == 2) {
|
if (length == 4 && i == 2 && !m_hasTime) {
|
||||||
continue; // skip weekday in between
|
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
|
return RESULT_ERR_EOF; // incomplete
|
||||||
}
|
}
|
||||||
if (!hasFlag(REQ) && token == NULL_VALUE) {
|
if (!hasFlag(REQ) && token == NULL_VALUE) {
|
||||||
@@ -402,12 +430,22 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i + 1 == count) {
|
if (i + 1 == (m_hasTime ? count-1 : count)) {
|
||||||
if (length == 4) {
|
if (length == 4) {
|
||||||
// calculate local week day
|
|
||||||
int y = (value < 100 ? value + 2000 : value) - 1900;
|
int y = (value < 100 ? value + 2000 : value) - 1900;
|
||||||
int l = last <= 2 ? 1 : 0;
|
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 mjd = 14956 + lastLast + static_cast<int>((y-l)*365.25) + static_cast<int>((last+1+l*12)*30.6001);
|
||||||
|
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
|
int daysSinceSunday = (mjd + 3) % 7; // Sun=0
|
||||||
if (hasFlag(BCD)) {
|
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
|
||||||
@@ -416,6 +454,7 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
|||||||
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) {
|
if (value >= 2000) {
|
||||||
value -= 2000;
|
value -= 2000;
|
||||||
}
|
}
|
||||||
@@ -471,7 +510,24 @@ result_t DateTimeDataType::writeSymbols(size_t offset, size_t length, istringstr
|
|||||||
if (value > 24 * 6) {
|
if (value > 24 * 6) {
|
||||||
return RESULT_ERR_OUT_OF_RANGE; // invalid time
|
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;
|
break;
|
||||||
}
|
}
|
||||||
lastLast = last;
|
lastLast = last;
|
||||||
@@ -940,6 +996,8 @@ DataTypeList::DataTypeList() {
|
|||||||
add(new DateTimeDataType("HDA", 24, 0, 0xff, true, false, 0));
|
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)
|
// 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));
|
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)
|
// 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));
|
add(new DateTimeDataType("BTI", 24, BCD|REV, 0xff, false, true, 0));
|
||||||
// time, 00:00:00 - 23:59:59 (0x00,0x00,0x00 - 0x17,0x3b,0x3b)
|
// 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", "31.12.2078", "10fe07000262ff", "00", ""},
|
||||||
{"x,,day", "-.-.-", "10fe070002ffff", "00", ""},
|
{"x,,day", "-.-.-", "10fe070002ffff", "00", ""},
|
||||||
{"x,,day", "", "10fe0700020000", "00", "Rw"},
|
{"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", "21:04:58", "10fe070003580421", "00", ""},
|
||||||
{"x,,bti", "00:00:00", "10fe070003000000", "00", ""},
|
{"x,,bti", "00:00:00", "10fe070003000000", "00", ""},
|
||||||
{"x,,bti", "23:59:59", "10fe070003595923", "00", ""},
|
{"x,,bti", "23:59:59", "10fe070003595923", "00", ""},
|
||||||
|
|||||||
Reference in New Issue
Block a user