Skip to content

Commit 55ec80a

Browse files
committed
fix(datetime): improve parseTemplate
1 parent 0bd736d commit 55ec80a

File tree

3 files changed

+106
-50
lines changed

3 files changed

+106
-50
lines changed

ionic/components/datetime/test/datetime.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ describe('DateTime', () => {
465465

466466
// pt-br
467467
var customLocale: datetime.LocaleData = {
468-
dayShort: [
468+
dayNames: [
469469
'domingo',
470470
'segunda-feira',
471471
'ter\u00e7a-feira',

ionic/util/datetime-util.ts

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -266,33 +266,38 @@ export function updateDate(existingData: DateTimeData, newData: any) {
266266

267267

268268
export function parseTemplate(template: string): string[] {
269-
var formats: string[] = [];
269+
let formats: string[] = [];
270+
271+
template = template.replace(/[^\w\s]/gi, ' ');
270272

271-
var foundFormats: {index: number; format: string}[] = [];
272273
FORMAT_KEYS.forEach(format => {
273-
var index = template.indexOf(format.f);
274-
if (index > -1) {
275-
template = template.replace(format.f, replacer(format.f));
276-
foundFormats.push({
277-
index: index,
278-
format: format.f,
279-
});
274+
if (format.f.length > 1 && template.indexOf(format.f) > -1 && template.indexOf(format.f + format.f.charAt(0)) < 0) {
275+
template = template.replace(format.f, ' ' + format.f + ' ');
280276
}
281277
});
282278

283-
// sort the found formats back to their original order
284-
foundFormats.sort((a, b) => (a.index > b.index) ? 1 : (a.index < b.index) ? -1 : 0);
285-
286-
return foundFormats.map(val => val.format);
287-
}
288-
279+
let words = template.split(' ').filter(w => w.length > 0);
280+
words.forEach((word, i) => {
281+
if (word.length) {
282+
FORMAT_KEYS.forEach(format => {
283+
if (word === format.f) {
284+
if (word === FORMAT_A || word === FORMAT_a) {
285+
// this format is an am/pm format, so it's an "a" or "A"
286+
if ((formats.indexOf(FORMAT_h) < 0 && formats.indexOf(FORMAT_hh) < 0) ||
287+
(words[i - 1] !== FORMAT_m && words[i - 1] !== FORMAT_mm)) {
288+
// template does not already have a 12-hour format
289+
// or this am/pm format doesn't have a minute format immediately before it
290+
// so do not treat this word "a" or "A" as an am/pm format
291+
return;
292+
}
293+
}
294+
formats.push(word);
295+
}
296+
});
297+
}
298+
});
289299

290-
function replacer(originalStr: string): string {
291-
let r = '';
292-
for (var i = 0; i < originalStr.length; i++) {
293-
r += '^';
294-
}
295-
return r;
300+
return formats;
296301
}
297302

298303

ionic/util/test/datetime-util.spec.ts

Lines changed: 79 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -249,36 +249,87 @@ describe('getValueFromFormat', () => {
249249

250250
describe('parseTemplate', () => {
251251

252-
it('should get formats from template "a A m mm h hh H HH D DD DDD DDDD M MM MMM MMMM YY YYYY"', () => {
253-
var formats = datetime.parseTemplate('a A m mm h hh H HH D DD DDD DDDD M MM MMM MMMM YY YYYY');
254-
expect(formats[0]).toEqual('a');
255-
expect(formats[1]).toEqual('A');
256-
expect(formats[2]).toEqual('m');
257-
expect(formats[3]).toEqual('mm');
258-
expect(formats[4]).toEqual('h');
259-
expect(formats[5]).toEqual('hh');
260-
expect(formats[6]).toEqual('H');
261-
expect(formats[7]).toEqual('HH');
262-
expect(formats[8]).toEqual('D');
263-
expect(formats[9]).toEqual('DD');
264-
expect(formats[10]).toEqual('DDD');
265-
expect(formats[11]).toEqual('DDDD');
266-
expect(formats[12]).toEqual('M');
267-
expect(formats[13]).toEqual('MM');
268-
expect(formats[14]).toEqual('MMM');
269-
expect(formats[15]).toEqual('MMMM');
270-
expect(formats[16]).toEqual('YY');
271-
expect(formats[17]).toEqual('YYYY');
272-
});
273-
274-
it('should get formats from template YYMMMMDDHma', () => {
275-
var formats = datetime.parseTemplate('YYMMMMDDHma');
252+
it('should not parse D thats apart of a word', () => {
253+
var formats = datetime.parseTemplate('D Days');
254+
expect(formats.length).toEqual(1);
255+
expect(formats[0]).toEqual('D');
256+
});
257+
258+
it('should not parse D thats apart of a word', () => {
259+
var formats = datetime.parseTemplate('DD Days');
260+
expect(formats.length).toEqual(1);
261+
expect(formats[0]).toEqual('DD');
262+
});
263+
264+
it('should not parse m thats apart of a word', () => {
265+
var formats = datetime.parseTemplate('m mins');
266+
expect(formats.length).toEqual(1);
267+
expect(formats[0]).toEqual('m');
268+
});
269+
270+
it('should not parse M thats apart of a word', () => {
271+
var formats = datetime.parseTemplate('mm Minutes');
272+
expect(formats.length).toEqual(1);
273+
expect(formats[0]).toEqual('mm');
274+
});
275+
276+
it('should not pickup "a" within 12-hour, but its not the am/pm', () => {
277+
var formats = datetime.parseTemplate('hh:mm is a time');
278+
expect(formats.length).toEqual(2);
279+
expect(formats[0]).toEqual('hh');
280+
expect(formats[1]).toEqual('mm');
281+
});
282+
283+
it('should allow am/pm when using 12-hour and no spaces', () => {
284+
var formats = datetime.parseTemplate('hh:mma');
285+
expect(formats.length).toEqual(3);
286+
expect(formats[0]).toEqual('hh');
287+
expect(formats[1]).toEqual('mm');
288+
expect(formats[2]).toEqual('a');
289+
});
290+
291+
it('should allow am/pm when using 12-hour', () => {
292+
var formats = datetime.parseTemplate('hh:mm a');
293+
expect(formats.length).toEqual(3);
294+
expect(formats[0]).toEqual('hh');
295+
expect(formats[1]).toEqual('mm');
296+
expect(formats[2]).toEqual('a');
297+
});
298+
299+
it('should not add am/pm when not using 24-hour', () => {
300+
var formats = datetime.parseTemplate('HH:mm a');
301+
expect(formats.length).toEqual(2);
302+
expect(formats[0]).toEqual('HH');
303+
expect(formats[1]).toEqual('mm');
304+
});
305+
306+
it('should get formats from template "m mm h hh H HH D DD DDD DDDD M MM MMM MMMM YY YYYY"', () => {
307+
var formats = datetime.parseTemplate('m mm h hh H HH D DD DDD DDDD M MM MMM MMMM YY YYYY');
308+
expect(formats[0]).toEqual('m');
309+
expect(formats[1]).toEqual('mm');
310+
expect(formats[2]).toEqual('h');
311+
expect(formats[3]).toEqual('hh');
312+
expect(formats[4]).toEqual('H');
313+
expect(formats[5]).toEqual('HH');
314+
expect(formats[6]).toEqual('D');
315+
expect(formats[7]).toEqual('DD');
316+
expect(formats[8]).toEqual('DDD');
317+
expect(formats[9]).toEqual('DDDD');
318+
expect(formats[10]).toEqual('M');
319+
expect(formats[11]).toEqual('MM');
320+
expect(formats[12]).toEqual('MMM');
321+
expect(formats[13]).toEqual('MMMM');
322+
expect(formats[14]).toEqual('YY');
323+
expect(formats[15]).toEqual('YYYY');
324+
});
325+
326+
it('should get formats from template YYMMMMDDHHmm', () => {
327+
var formats = datetime.parseTemplate('YYMMMMDDHHmm');
276328
expect(formats[0]).toEqual('YY');
277329
expect(formats[1]).toEqual('MMMM');
278330
expect(formats[2]).toEqual('DD');
279-
expect(formats[3]).toEqual('H');
280-
expect(formats[4]).toEqual('m');
281-
expect(formats[5]).toEqual('a');
331+
expect(formats[3]).toEqual('HH');
332+
expect(formats[4]).toEqual('mm');
282333
});
283334

284335
it('should get formats from template MM/DD/YYYY', () => {
@@ -741,7 +792,7 @@ describe('parseISODate', () => {
741792

742793
// pt-br
743794
var customLocale: datetime.LocaleData = {
744-
dayShort: [
795+
dayNames: [
745796
'domingo',
746797
'segunda-feira',
747798
'ter\u00e7a-feira',

0 commit comments

Comments
 (0)