Transformations: Convert field type should handle Unix timestamps in seconds (#94442)
* Parse seconds unix formatted timestamps as expected * clarify comment --------- Co-authored-by: Ihor Yeromin <yeryomin.igor@gmail.com>
This commit is contained in:
@@ -486,4 +486,52 @@ describe('fieldToTimeField', () => {
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly parse Unix timestamps - in seconds', () => {
|
||||
const numberTimeField: Field = {
|
||||
config: {},
|
||||
name: 'Unix second timestamps',
|
||||
type: FieldType.number,
|
||||
values: [1728397800, 1728397815, 1728397830],
|
||||
};
|
||||
|
||||
expect(fieldToTimeField(numberTimeField, 'X')).toEqual({
|
||||
config: {},
|
||||
name: 'Unix second timestamps',
|
||||
type: FieldType.time,
|
||||
values: [1728397800000, 1728397815000, 1728397830000],
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly parse Unix timestamps - in millseconds (with format)', () => {
|
||||
const numberTimeField: Field = {
|
||||
config: {},
|
||||
name: 'Unix MS timestamps',
|
||||
type: FieldType.number,
|
||||
values: [1728397800000, 1728397815000, 1728397830000],
|
||||
};
|
||||
|
||||
expect(fieldToTimeField(numberTimeField, 'x')).toEqual({
|
||||
config: {},
|
||||
name: 'Unix MS timestamps',
|
||||
type: FieldType.time,
|
||||
values: [1728397800000, 1728397815000, 1728397830000],
|
||||
});
|
||||
});
|
||||
|
||||
it('should properly parse Unix timestamps - in millseconds (without format)', () => {
|
||||
const numberTimeField: Field = {
|
||||
config: {},
|
||||
name: 'Unix MS timestamps',
|
||||
type: FieldType.number,
|
||||
values: [1728397800000, 1728397815000, 1728397830000],
|
||||
};
|
||||
|
||||
expect(fieldToTimeField(numberTimeField)).toEqual({
|
||||
config: {},
|
||||
name: 'Unix MS timestamps',
|
||||
type: FieldType.time,
|
||||
values: [1728397800000, 1728397815000, 1728397830000],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -131,13 +131,17 @@ export function fieldToTimeField(field: Field, dateFormat?: string): Field {
|
||||
const timeValues = field.values.slice();
|
||||
|
||||
let firstDefined = timeValues.find((v) => v != null);
|
||||
|
||||
let isISO8601 = typeof firstDefined === 'string' && iso8601Regex.test(firstDefined);
|
||||
const convertToMS = typeof firstDefined === 'number' && dateFormat === 'X';
|
||||
const isISO8601 = typeof firstDefined === 'string' && iso8601Regex.test(firstDefined);
|
||||
|
||||
for (let t = 0; t < timeValues.length; t++) {
|
||||
if (timeValues[t]) {
|
||||
let parsed = isISO8601 ? Date.parse(timeValues[t]) : dateTimeParse(timeValues[t], opts).valueOf();
|
||||
timeValues[t] = Number.isFinite(parsed) ? parsed : null;
|
||||
if (Number.isFinite(parsed)) {
|
||||
timeValues[t] = convertToMS ? parsed * 1000 : parsed;
|
||||
} else {
|
||||
timeValues[t] = null;
|
||||
}
|
||||
} else {
|
||||
timeValues[t] = null;
|
||||
}
|
||||
@@ -254,10 +258,13 @@ function fieldToComplexField(field: Field): Field {
|
||||
*/
|
||||
export function ensureTimeField(field: Field, dateFormat?: string): Field {
|
||||
const firstValueTypeIsNumber = typeof field.values[0] === 'number';
|
||||
// if the format is unix seconds, we don't want to skip formatting
|
||||
const isUnixSecondsFormat = dateFormat === 'X';
|
||||
|
||||
if (field.type === FieldType.time && firstValueTypeIsNumber) {
|
||||
return field; //already time
|
||||
}
|
||||
if (firstValueTypeIsNumber) {
|
||||
if (firstValueTypeIsNumber && !isUnixSecondsFormat) {
|
||||
return {
|
||||
...field,
|
||||
type: FieldType.time, //assumes it should be time
|
||||
|
||||
Reference in New Issue
Block a user