mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-11 16:38:39 +01:00
Tests for date + time parsing & formatting, and fixing the bugs they revealed
This commit is contained in:
parent
672ed0aa0e
commit
ca429d0fae
@ -16,7 +16,8 @@ import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To parse a date into the right format
|
* Parse a date string into a Date object
|
||||||
|
* Time will be 00:00:00 UTC
|
||||||
*
|
*
|
||||||
* @param {string} dateString
|
* @param {string} dateString
|
||||||
* @returns {Date | undefined}
|
* @returns {Date | undefined}
|
||||||
@ -65,15 +66,15 @@ export function parseDate(dateString)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [year, month, day] = parsedString.split('/').map(Number);
|
const [year, month, day] = parsedString.split('/').map(Number);
|
||||||
const parsedDate = new Date(year, month - 1, day);
|
const parsedDate = new Date(`${year}-${month < 10 ? "0" + month : month}-${day < 10 ? "0" + day : day}T00:00:00Z`);
|
||||||
|
|
||||||
// Check if parsedDate is not `Invalid Date` or that the date has changed (e.g. the not existing 31.02.2020)
|
// Check if parsedDate is not `Invalid Date` or that the date has changed (e.g. the not existing 31.02.2020)
|
||||||
if (
|
if(
|
||||||
year > 0 &&
|
year > 0 &&
|
||||||
month > 0 &&
|
month > 0 &&
|
||||||
day > 0 &&
|
day > 0 &&
|
||||||
parsedDate.getDate() === day &&
|
parsedDate.getUTCDate() === day &&
|
||||||
parsedDate.getMonth() === month - 1
|
parsedDate.getUTCMonth() === month - 1
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return parsedDate;
|
return parsedDate;
|
||||||
@ -82,8 +83,8 @@ export function parseDate(dateString)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To parse a time into the right format
|
* To parse a time into a Date object
|
||||||
* Date will be 1970-01-01
|
* Date will be 1970-01-01, time is in UTC to avoid browser issues
|
||||||
*
|
*
|
||||||
* @param {string} timeString
|
* @param {string} timeString
|
||||||
* @returns {Date | undefined}
|
* @returns {Date | undefined}
|
||||||
@ -108,8 +109,16 @@ export function parseTime(timeString)
|
|||||||
}
|
}
|
||||||
|
|
||||||
let am_pm = timeString.endsWith("pm") || timeString.endsWith("PM") ? 12 : 0;
|
let am_pm = timeString.endsWith("pm") || timeString.endsWith("PM") ? 12 : 0;
|
||||||
timeString = timeString.replaceAll(/[^0-9:]/gi, '');
|
|
||||||
const [hour, minute] = timeString.split(':').map(Number);
|
let strippedString = timeString.replaceAll(/[^0-9:]/gi, '');
|
||||||
|
|
||||||
|
if(timeString.startsWith("12") && strippedString != timeString)
|
||||||
|
{
|
||||||
|
// 12:xx am -> 0:xx, 12:xx pm -> 12:xx
|
||||||
|
am_pm -= 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [hour, minute] = strippedString.split(':').map(Number);
|
||||||
|
|
||||||
const parsedDate = new Date("1970-01-01T00:00:00Z");
|
const parsedDate = new Date("1970-01-01T00:00:00Z");
|
||||||
parsedDate.setUTCHours(hour + am_pm);
|
parsedDate.setUTCHours(hour + am_pm);
|
||||||
@ -128,6 +137,7 @@ export function parseTime(timeString)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* To parse a date+time into an object
|
* To parse a date+time into an object
|
||||||
|
* Time is in UTC to avoid browser issues
|
||||||
*
|
*
|
||||||
* @param {string} dateTimeString
|
* @param {string} dateTimeString
|
||||||
* @returns {Date | undefined}
|
* @returns {Date | undefined}
|
||||||
@ -180,7 +190,7 @@ export function parseDateTime(dateTimeString)
|
|||||||
* set 'dateFormat': "Y-m-d" to specify a particular format
|
* set 'dateFormat': "Y-m-d" to specify a particular format
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function formatDate(date : Date, options) : string
|
export function formatDate(date : Date, options = {dateFormat: ""}) : string
|
||||||
{
|
{
|
||||||
if(!date || !(date instanceof Date))
|
if(!date || !(date instanceof Date))
|
||||||
{
|
{
|
||||||
@ -213,7 +223,7 @@ export function formatDate(date : Date, options) : string
|
|||||||
* set 'timeFormat': "12" to specify a particular format
|
* set 'timeFormat': "12" to specify a particular format
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function formatTime(date : Date, options) : string
|
export function formatTime(date : Date, options = {timeFormat: ""}) : string
|
||||||
{
|
{
|
||||||
if(!date || !(date instanceof Date))
|
if(!date || !(date instanceof Date))
|
||||||
{
|
{
|
||||||
@ -221,7 +231,7 @@ export function formatTime(date : Date, options) : string
|
|||||||
}
|
}
|
||||||
let _value = '';
|
let _value = '';
|
||||||
|
|
||||||
let timeformat = options.timeFormat || <string>window.egw.preference("timeformat") || '24';
|
let timeformat = options.timeFormat || <string>window.egw.preference("timeformat") || "24";
|
||||||
let hours = (timeformat == "12" && date.getUTCHours() > 12) ? (date.getUTCHours() - 12) : date.getUTCHours();
|
let hours = (timeformat == "12" && date.getUTCHours() > 12) ? (date.getUTCHours() - 12) : date.getUTCHours();
|
||||||
if(timeformat == "12" && hours == 0)
|
if(timeformat == "12" && hours == 0)
|
||||||
{
|
{
|
||||||
@ -244,7 +254,7 @@ export function formatTime(date : Date, options) : string
|
|||||||
* set 'dateFormat': "Y-m-d", 'timeFormat': "12" to specify a particular format
|
* set 'dateFormat': "Y-m-d", 'timeFormat': "12" to specify a particular format
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function formatDateTime(date : Date, options) : string
|
export function formatDateTime(date : Date, options = {dateFormat: "", timeFormat: ""}) : string
|
||||||
{
|
{
|
||||||
if(!date || !(date instanceof Date))
|
if(!date || !(date instanceof Date))
|
||||||
{
|
{
|
||||||
|
97
api/js/etemplate/Et2Date/test/Formatter.test.ts
Normal file
97
api/js/etemplate/Et2Date/test/Formatter.test.ts
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
* Test file for Etemplate date formatting
|
||||||
|
*/
|
||||||
|
import {assert} from '@open-wc/testing';
|
||||||
|
import {formatDate, formatTime} from "../Et2Date";
|
||||||
|
|
||||||
|
describe("Date formatting", () =>
|
||||||
|
{
|
||||||
|
// Function under test
|
||||||
|
let formatter = formatDate;
|
||||||
|
|
||||||
|
// Setup run before each test
|
||||||
|
beforeEach(async() =>
|
||||||
|
{
|
||||||
|
// Stub global egw for preference
|
||||||
|
// @ts-ignore
|
||||||
|
window.egw = {
|
||||||
|
preference: () => 'Y-m-d'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Handles Y-m-d", () =>
|
||||||
|
{
|
||||||
|
let test_string = '2021-09-22';
|
||||||
|
let test_date = new Date(2021, 8, 22, 0, 0, 0);
|
||||||
|
|
||||||
|
let formatted = formatter(test_date);
|
||||||
|
|
||||||
|
assert.equal(formatted, test_string);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Handles Y.d.m", () =>
|
||||||
|
{
|
||||||
|
let test_string = '2021.22.09';
|
||||||
|
let test_date = new Date(2021, 8, 22, 0, 0, 0);
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
window.egw = {
|
||||||
|
preference: () => 'Y.d.m'
|
||||||
|
};
|
||||||
|
let formatted = formatter(test_date);
|
||||||
|
|
||||||
|
assert.equal(formatted, test_string);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Time formatting", () =>
|
||||||
|
{
|
||||||
|
// Function under test
|
||||||
|
let formatter = formatTime;
|
||||||
|
|
||||||
|
// Setup run before each test
|
||||||
|
beforeEach(async() =>
|
||||||
|
{
|
||||||
|
// Stub global egw for preference
|
||||||
|
// @ts-ignore
|
||||||
|
window.egw = {
|
||||||
|
preference: () => 'Y-m-d'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Handles 12h", () =>
|
||||||
|
{
|
||||||
|
const test_data = {
|
||||||
|
"9:15 am": new Date('2021-09-22T09:15:00Z'),
|
||||||
|
"12:00 am": new Date('2021-09-22T00:00:00Z'),
|
||||||
|
"12:00 pm": new Date('2021-09-22T12:00:00Z'),
|
||||||
|
"5:00 pm": new Date('2021-09-22T17:00:00Z'),
|
||||||
|
};
|
||||||
|
for(let test_string of Object.keys(test_data))
|
||||||
|
{
|
||||||
|
let test_date = test_data[test_string];
|
||||||
|
let formatted = formatter(test_date, {timeFormat: "12"});
|
||||||
|
|
||||||
|
assert.equal(formatted, test_string);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Handles 24h", () =>
|
||||||
|
{
|
||||||
|
const test_data = {
|
||||||
|
"09:15": new Date('2021-09-22T09:15:00Z'),
|
||||||
|
"00:00": new Date('2021-09-22T00:00:00Z'),
|
||||||
|
"12:00": new Date('2021-09-22T12:00:00Z'),
|
||||||
|
"17:00": new Date('2021-09-22T17:00:00Z'),
|
||||||
|
};
|
||||||
|
for(let test_string of Object.keys(test_data))
|
||||||
|
{
|
||||||
|
let test_date = test_data[test_string];
|
||||||
|
let formatted = formatter(test_date, {timeFormat: "24"});
|
||||||
|
|
||||||
|
assert.equal(formatted, test_string);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -1,10 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* Test file for Etemplate date parsing
|
* Test file for Etemplate date parsing
|
||||||
*/
|
*/
|
||||||
import {assert, fixture} from '@open-wc/testing';
|
import {assert} from '@open-wc/testing';
|
||||||
import {Et2Date, parseDate} from "../Et2Date";
|
import {parseDate, parseTime} from "../Et2Date";
|
||||||
import {html} from "lit-element";
|
|
||||||
import * as sinon from 'sinon';
|
|
||||||
|
|
||||||
describe("Date parsing", () =>
|
describe("Date parsing", () =>
|
||||||
{
|
{
|
||||||
@ -36,7 +34,7 @@ describe("Date parsing", () =>
|
|||||||
it("Handles Y-m-d", () =>
|
it("Handles Y-m-d", () =>
|
||||||
{
|
{
|
||||||
let test_string = '2021-09-22';
|
let test_string = '2021-09-22';
|
||||||
let test_date = new Date(2021, 8, 22, 0, 0, 0);
|
let test_date = new Date("2021-09-22T00:00:00Z");
|
||||||
|
|
||||||
let parsed = parser(test_string);
|
let parsed = parser(test_string);
|
||||||
|
|
||||||
@ -46,7 +44,7 @@ describe("Date parsing", () =>
|
|||||||
it("Handles Y.d.m", () =>
|
it("Handles Y.d.m", () =>
|
||||||
{
|
{
|
||||||
let test_string = '2021.22.09';
|
let test_string = '2021.22.09';
|
||||||
let test_date = new Date(2021, 8, 22, 0, 0, 0);
|
let test_date = new Date("2021-09-22T00:00:00Z");
|
||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
window.egw = {
|
window.egw = {
|
||||||
@ -56,4 +54,78 @@ describe("Date parsing", () =>
|
|||||||
|
|
||||||
assert.equal(parsed.toJSON(), test_date.toJSON());
|
assert.equal(parsed.toJSON(), test_date.toJSON());
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe("Time parsing", () =>
|
||||||
|
{
|
||||||
|
// Setup run before each test
|
||||||
|
beforeEach(async() =>
|
||||||
|
{
|
||||||
|
// Stub global egw for preference
|
||||||
|
// @ts-ignore
|
||||||
|
window.egw = {
|
||||||
|
preference: () => 'Y-m-d'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("Handles 12h", () =>
|
||||||
|
{
|
||||||
|
const test_data = {
|
||||||
|
// As expected
|
||||||
|
"9:15 am": new Date('1970-01-01T09:15:00Z'),
|
||||||
|
"12:00 am": new Date('1970-01-01T00:00:00Z'),
|
||||||
|
"12:00 pm": new Date('1970-01-01T12:00:00Z'),
|
||||||
|
"5:00 pm": new Date('1970-01-01T17:00:00Z'),
|
||||||
|
"11:59 pm": new Date('1970-01-01T23:59:00Z'),
|
||||||
|
|
||||||
|
// Not valid, should be undefined
|
||||||
|
"invalid": undefined,
|
||||||
|
"23:45 pm": undefined
|
||||||
|
};
|
||||||
|
for(let test_string of Object.keys(test_data))
|
||||||
|
{
|
||||||
|
let test_date = test_data[test_string];
|
||||||
|
let parsed = parseTime(test_string);
|
||||||
|
|
||||||
|
if(typeof test_date == "undefined")
|
||||||
|
{
|
||||||
|
assert.isUndefined(parsed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert.equal(parsed.toJSON(), test_date.toJSON());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Handles 24h", () =>
|
||||||
|
{
|
||||||
|
const test_data = {
|
||||||
|
"09:15": new Date('1970-01-01T09:15:00Z'),
|
||||||
|
"00:00": new Date('1970-01-01T00:00:00Z'),
|
||||||
|
"12:00": new Date('1970-01-01T12:00:00Z'),
|
||||||
|
"17:00": new Date('1970-01-01T17:00:00Z'),
|
||||||
|
"23:59": new Date('1970-01-01T23:59:00Z'),
|
||||||
|
|
||||||
|
// Not valid, should be undefined
|
||||||
|
"invalid": undefined,
|
||||||
|
"23:45 pm": undefined
|
||||||
|
};
|
||||||
|
for(let test_string of Object.keys(test_data))
|
||||||
|
{
|
||||||
|
let test_date = test_data[test_string];
|
||||||
|
let parsed = parseTime(test_string);
|
||||||
|
|
||||||
|
if(typeof test_date == "undefined")
|
||||||
|
{
|
||||||
|
assert.isUndefined(parsed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert.equal(parsed.toJSON(), test_date.toJSON());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user