diff --git a/redisinsight/ui/src/utils/formatters/utils.ts b/redisinsight/ui/src/utils/formatters/utils.ts index f81824b5dd..5df09e3b4f 100644 --- a/redisinsight/ui/src/utils/formatters/utils.ts +++ b/redisinsight/ui/src/utils/formatters/utils.ts @@ -11,3 +11,17 @@ export const bufferFormatRangeItems = ( return newItems } + +export const convertTimestampToMilliseconds = (value: string): number => { + // seconds, microseconds, nanoseconds to milliseconds + switch (parseInt(value, 10).toString().length) { + case 10: + return +value * 1000 + case 16: + return +value / 1000 + case 19: + return +value / 1000000 + default: + return +value + } +} diff --git a/redisinsight/ui/src/utils/formatters/valueFormatters.tsx b/redisinsight/ui/src/utils/formatters/valueFormatters.tsx index 190a4d0f1e..da3c0ab752 100644 --- a/redisinsight/ui/src/utils/formatters/valueFormatters.tsx +++ b/redisinsight/ui/src/utils/formatters/valueFormatters.tsx @@ -25,6 +25,7 @@ import { bufferToFloat64Array, bufferToFloat32Array, checkTimestamp, + convertTimestampToMilliseconds, } from 'uiSrc/utils' import { reSerializeJSON } from 'uiSrc/utils/formatters/json' @@ -152,11 +153,13 @@ const formattingBuffer = ( } } case KeyValueFormat.DateTime: { - const value = bufferToUnicode(reply) + const value = bufferToUnicode(reply)?.trim() try { if (checkTimestamp(value)) { - // formatting to DateTime only from timestamp(the number of milliseconds since January 1, 1970, UTC) - return { value: formatDateFns(new Date(+value), DATETIME_FORMATTER_DEFAULT), isValid: true } + // formatting to DateTime only from timestamp(the number of milliseconds since January 1, 1970, UTC). + // if seconds - add milliseconds (since JS Date works only with milliseconds) + const timestamp = convertTimestampToMilliseconds(value) + return { value: formatDateFns(timestamp, DATETIME_FORMATTER_DEFAULT), isValid: true } } } catch (e) { // if error return default diff --git a/redisinsight/ui/src/utils/tests/validations.spec.ts b/redisinsight/ui/src/utils/tests/validations.spec.ts index 2053a0e04c..1b3181ec4e 100644 --- a/redisinsight/ui/src/utils/tests/validations.spec.ts +++ b/redisinsight/ui/src/utils/tests/validations.spec.ts @@ -41,7 +41,7 @@ const checkTimestampTests = [ { input: '1234567891234567891', expected: true }, { input: '1234567891.2', expected: true }, // it should be valid timestamp (for date < 1970) - { input: '-1234567891', expected: true }, + { input: '-123456789', expected: true }, { input: '', expected: false }, { input: '-', expected: false }, { input: '0', expected: false }, diff --git a/redisinsight/ui/src/utils/validations.ts b/redisinsight/ui/src/utils/validations.ts index 44d3619ff8..16b9fe412b 100644 --- a/redisinsight/ui/src/utils/validations.ts +++ b/redisinsight/ui/src/utils/validations.ts @@ -129,22 +129,24 @@ export const getApproximatePercentage = (total?: number, part: number = 0): stri } export const IS_NUMBER_REGEX = /^-?\d*(\.\d+)?$/ -export const IS_TIMESTAMP = /^-?(\d{10}|\d{13}|\d{16}|\d{19})$/ +export const IS_TIMESTAMP = /^(\d{10}|\d{13}|\d{16}|\d{19})$/ +export const IS_NEGATIVE_TIMESTAMP = /^-(\d{9}|\d{12}|\d{15}|\d{18})$/ export const IS_INTEGER_NUMBER_REGEX = /^\d+$/ const detailedTimestampCheck = (value: string) => { try { // test integer to be of 10, 13, 16 or 19 digits const integerPart = parseInt(value, 10).toString() - if (!IS_TIMESTAMP.test(integerPart)) { - return false - } - if (integerPart.length === value.length) { - return true + + if (IS_TIMESTAMP.test(integerPart) || IS_NEGATIVE_TIMESTAMP.test(integerPart)) { + if (integerPart.length === value.length) { + return true + } + // check part after dot separator (checking floating numbers) + const subPart = value.replace(integerPart, '') + return IS_INTEGER_NUMBER_REGEX.test(subPart.substring(1, subPart.length)) } - // check part after dot separator (checking floating numbers) - const subPart = value.replace(integerPart, '') - return IS_INTEGER_NUMBER_REGEX.test(subPart.substring(1, subPart.length)) + return false } catch (err) { // ignore errors return false