@progress/kendo-dateinputs-common 0.2.0-dev.202301061353 → 0.2.0-dev.202301130811

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { addMonths, cloneDate, createDate, isEqual, getDate, lastDayOfMonth } from '@progress/kendo-date-math';
2
2
  import { Mask } from './mask';
3
3
  import { dateSymbolMap, padZero, unpadZero } from '../dateinput/utils';
4
- import { extend, isPresent, cropTwoDigitYear, setYears, parseToInt, clamp, areDatePartsEqualTo, isNumber } from './utils';
4
+ import { extend, isPresent, cropTwoDigitYear, setYears, parseToInt, clamp, areDatePartsEqualTo, isNumber, isValidDate } from './utils';
5
5
  import { Constants } from './constants';
6
6
  var PREVIOUS_CENTURY_BASE = 1900;
7
7
  var CURRENT_CENTURY_BASE = 2000;
@@ -158,16 +158,18 @@ var DateObject = /** @class */ (function () {
158
158
  partiallyInvalidText += text[i];
159
159
  }
160
160
  else if (this.getInvalidDatePartValue(symbol)) {
161
+ var partsForSegment = this.getPartsForSegment(mask, i);
161
162
  if (symbol === "M") {
162
- if (mask.partMap[i].pattern.length > MONTH_PART_WITH_WORDS_THRESHOLD) {
163
+ var datePartText = (parseToInt(this.getInvalidDatePartValue(symbol)) + JS_MONTH_OFFSET).toString();
164
+ if (partsForSegment.length > MONTH_PART_WITH_WORDS_THRESHOLD) {
163
165
  partiallyInvalidText += formattedDates[symbol][i];
164
166
  }
165
167
  else {
166
168
  if (this.getInvalidDatePartValue(symbol)) {
167
- var month = parseToInt(this.getInvalidDatePartValue(symbol) + JS_MONTH_OFFSET).toString();
168
- var formattedMonth = padZero(Math.abs(mask.partMap[i].pattern.length - month.length)) + month;
169
- partiallyInvalidText += formattedMonth;
170
- i += Math.max(0, formattedMonth.length - 1);
169
+ var formattedDatePart = padZero(partsForSegment.length - datePartText.length) + datePartText;
170
+ partiallyInvalidText += formattedDatePart;
171
+ // add -1 as the first character in the segment is at index i
172
+ i += partsForSegment.length - 1;
171
173
  }
172
174
  else {
173
175
  partiallyInvalidText += formattedDates[symbol][i];
@@ -176,8 +178,11 @@ var DateObject = /** @class */ (function () {
176
178
  }
177
179
  else {
178
180
  if (this.getInvalidDatePartValue(symbol)) {
179
- partiallyInvalidText += this.getInvalidDatePartValue(symbol);
180
- i += Math.max(0, this.getInvalidDatePartValue(symbol).toString().length - 1);
181
+ var datePartText = this.getInvalidDatePartValue(symbol).toString();
182
+ var formattedDatePart = padZero(partsForSegment.length - datePartText.length) + datePartText;
183
+ partiallyInvalidText += formattedDatePart;
184
+ // add -1 as the first character in the segment is at index i
185
+ i += partsForSegment.length - 1;
181
186
  }
182
187
  else {
183
188
  partiallyInvalidText += formattedDates[symbol][i];
@@ -288,16 +293,18 @@ var DateObject = /** @class */ (function () {
288
293
  }
289
294
  };
290
295
  DateObject.prototype.modifyPart = function (symbol, offset) {
296
+ if (!isPresent(symbol) || !isPresent(offset) || offset === 0) {
297
+ return;
298
+ }
291
299
  var newValue = cloneDate(this.value);
292
- var originalValue = cloneDate(this.value);
293
300
  var timeModified = false;
294
301
  var invalidDateFound;
295
- var currentInvalidDatePartValue = 0;
296
- if (!this.autoCorrectParts) {
297
- var isMonth = symbol === "M";
298
- var isDay = symbol === "d" || symbol === "E";
302
+ var isMonth = symbol === "M";
303
+ var isDay = symbol === "d" || symbol === "E";
304
+ var symbolExists = this.getExisting(symbol);
305
+ if (!this.autoCorrectParts && (isDay || isMonth)) {
299
306
  var invalidDateParts = this._partiallyInvalidDate.invalidDateParts || {};
300
- var invalidDatePart = invalidDateParts[symbol];
307
+ var invalidDatePartValue = this.getInvalidDatePartValue(symbol);
301
308
  var year = invalidDateParts.y.value || newValue.getFullYear();
302
309
  var month = invalidDateParts.M.value || newValue.getMonth();
303
310
  var day = invalidDateParts.d.value || invalidDateParts.E.value || newValue.getDate();
@@ -316,33 +323,61 @@ var DateObject = /** @class */ (function () {
316
323
  case 'E':
317
324
  day += offset;
318
325
  break;
319
- case 'h':
320
- case 'H':
321
- hour += offset;
322
- break;
323
- case 'm':
324
- minutes += offset;
325
- break;
326
- case 's':
327
- seconds += offset;
328
- break;
329
- case 'S':
330
- milliseconds += offset;
331
- break;
332
- // case 'a': newValue.setHours(newValue.getHours() + (12 * offset)); timeModified = true; break;
326
+ // case 'h':
327
+ // case 'H': hour += offset; break;
328
+ // case 'm': minutes += offset; break;
329
+ // case 's': seconds += offset; break;
330
+ // case 'S': milliseconds += offset; break;
333
331
  default: break;
334
332
  }
335
333
  if (symbol === "M") {
336
- if ((month < 0 || month > 11) && this.getExisting(symbol)) {
337
- // do not cycle months
338
- this.setExisting(symbol, false);
339
- return;
334
+ if ((month < 0 || month > 11)) {
335
+ if (symbolExists) {
336
+ this.setExisting(symbol, false);
337
+ this.resetInvalidDateSymbol(symbol);
338
+ return;
339
+ }
340
+ }
341
+ if (!symbolExists) {
342
+ if (month < 0) {
343
+ month = clamp(11 + ((month % 11) + 1), 0, 11);
344
+ }
345
+ else {
346
+ var monthValue = isPresent(invalidDatePartValue) ?
347
+ month :
348
+ ((offset - JS_MONTH_OFFSET) % 12);
349
+ month = clamp(monthValue, 0, 11);
350
+ }
351
+ month = clamp(month, 0, 11);
352
+ }
353
+ month = clamp(month, 0, 11);
354
+ }
355
+ else if (symbol === "d") {
356
+ if (symbolExists) {
357
+ if (day <= 0 || day > 31) {
358
+ this.setExisting(symbol, false);
359
+ this.resetInvalidDateSymbol(symbol);
360
+ return;
361
+ }
362
+ }
363
+ else if (!symbolExists) {
364
+ if (isPresent(invalidDatePartValue)) {
365
+ if (day <= 0 || day > 31) {
366
+ this.setExisting(symbol, false);
367
+ this.resetInvalidDateSymbol(symbol);
368
+ return;
369
+ }
370
+ }
371
+ if (offset < 0) {
372
+ var dayValue = isPresent(invalidDatePartValue) ? day : 1 + (31 - Math.abs(offset % 31));
373
+ day = clamp(dayValue, 1, 31);
374
+ }
375
+ else {
376
+ var dayValue = isPresent(invalidDatePartValue) ? day : offset % 31;
377
+ day = clamp(dayValue, 1, 31);
378
+ }
379
+ day = clamp(day, 1, 31);
340
380
  }
341
- // const mask = this.dateFormatString(this.value, this.format);
342
- // const monthPart = mask.partMap.filter(x => x.type === "month");
343
- // if (monthPart && monthPart[0] && monthPart[0].pattern.length > MONTH_PART_WITH_WORDS_THRESHOLD) {
344
- month = (12 + month) % 12;
345
- // }
346
381
  }
347
382
  var dateCandidate = createDate(year, month, day, hour, minutes, seconds, milliseconds);
348
383
  var newValueCandidate = isMonth || isDay ?
@@ -439,92 +474,6 @@ var DateObject = /** @class */ (function () {
439
474
  this.setExisting(symbol, false);
440
475
  }
441
476
  }
442
- else {
443
- // this.modifyDateSymbol()
444
- switch (symbol) {
445
- case 'y':
446
- newValue.setFullYear(newValue.getFullYear() + offset);
447
- break;
448
- case 'M':
449
- newValue = addMonths(this.value, offset);
450
- break;
451
- case 'd':
452
- case 'E':
453
- newValue.setDate(newValue.getDate() + offset);
454
- break;
455
- case 'h':
456
- case 'H':
457
- newValue.setHours(newValue.getHours() + offset);
458
- timeModified = true;
459
- break;
460
- case 'm':
461
- newValue.setMinutes(newValue.getMinutes() + offset);
462
- timeModified = true;
463
- break;
464
- case 's':
465
- newValue.setSeconds(newValue.getSeconds() + offset);
466
- timeModified = true;
467
- break;
468
- case "S":
469
- newValue.setMilliseconds(newValue.getMilliseconds() + offset);
470
- break;
471
- case 'a':
472
- newValue.setHours(newValue.getHours() + (12 * offset));
473
- timeModified = true;
474
- break;
475
- default: break;
476
- }
477
- invalidDateFound = true;
478
- if (invalidDatePart && invalidDatePart.value) {
479
- currentInvalidDatePartValue = parseToInt(invalidDatePart.value);
480
- }
481
- else {
482
- if (!isPresent(invalidDatePart.value)) {
483
- newValue = cloneDate(originalValue);
484
- // this.modifyDateSymbol()
485
- switch (symbol) {
486
- case 'y':
487
- currentInvalidDatePartValue = originalValue.getFullYear();
488
- break;
489
- case 'M':
490
- currentInvalidDatePartValue = originalValue.getMonth();
491
- break;
492
- case 'd':
493
- case 'E':
494
- currentInvalidDatePartValue = originalValue.getDate();
495
- break;
496
- case 'h':
497
- case 'H':
498
- currentInvalidDatePartValue = originalValue.getHours();
499
- break;
500
- case 'm':
501
- currentInvalidDatePartValue = originalValue.getMinutes();
502
- break;
503
- case 's':
504
- currentInvalidDatePartValue = originalValue.getSeconds();
505
- break;
506
- case 'S':
507
- currentInvalidDatePartValue = originalValue.getMilliseconds();
508
- break;
509
- // case 'a': newValue.setHours(newValue.getHours() + (12 * offset)); timeModified = true; break;
510
- default: break;
511
- }
512
- }
513
- else {
514
- }
515
- }
516
- var invalidDatePartValue = Math.max(0, currentInvalidDatePartValue + offset);
517
- if (symbol !== "y") {
518
- invalidDatePartValue = clamp(currentInvalidDatePartValue + offset, 0, 99);
519
- }
520
- this.setInvalidDatePart(symbol, {
521
- value: invalidDatePartValue,
522
- date: cloneDate(newValue),
523
- startDateOffset: (this.getInvalidDatePart(symbol).startDateOffset || 0) + offset,
524
- startDate: cloneDate(this.value)
525
- });
526
- this.setExisting(symbol, false);
527
- }
528
477
  }
529
478
  else {
530
479
  switch (symbol) {
@@ -583,7 +532,7 @@ var DateObject = /** @class */ (function () {
583
532
  */
584
533
  DateObject.prototype.parsePart = function (_a) {
585
534
  var _b;
586
- var symbol = _a.symbol, currentChar = _a.currentChar, resetSegmentValue = _a.resetSegmentValue, cycleSegmentValue = _a.cycleSegmentValue, rawTextValue = _a.rawTextValue, isDeleting = _a.isDeleting;
535
+ var symbol = _a.symbol, currentChar = _a.currentChar, resetSegmentValue = _a.resetSegmentValue, cycleSegmentValue = _a.cycleSegmentValue, rawInputValue = _a.rawTextValue, isDeleting = _a.isDeleting, originalFormat = _a.originalFormat;
587
536
  var isInCaretMode = !cycleSegmentValue;
588
537
  var dateParts = this.dateFormatString(this.value, this.format);
589
538
  var datePartsLiterals = dateParts.partMap
@@ -591,9 +540,20 @@ var DateObject = /** @class */ (function () {
591
540
  .map(function (x, index) {
592
541
  return {
593
542
  datePartIndex: index,
594
- literal: x.pattern
543
+ type: x.type,
544
+ pattern: x.pattern,
545
+ literal: ""
595
546
  };
596
547
  });
548
+ for (var i = 0; i < datePartsLiterals.length; i++) {
549
+ var datePart = datePartsLiterals[i];
550
+ for (var j = 0; j < datePart.pattern.length; j++) {
551
+ if (datePartsLiterals[i + j]) {
552
+ datePartsLiterals[i + j].literal = datePart.pattern[j];
553
+ }
554
+ }
555
+ i += datePart.pattern.length - 1;
556
+ }
597
557
  var shouldResetPart = isInCaretMode && symbol === "M" && dateParts.partMap
598
558
  .filter(function (x) { return x.type === "month"; })
599
559
  .some(function (x) { return x.pattern.length > MONTH_PART_WITH_WORDS_THRESHOLD; });
@@ -606,9 +566,9 @@ var DateObject = /** @class */ (function () {
606
566
  if (isInCaretMode) {
607
567
  for (var i = 0; i < datePartsLiterals.length; i++) {
608
568
  var literal = datePartsLiterals[i].literal;
609
- var rawValueStartsWithLiteral = rawTextValue.startsWith(literal);
610
- var rawValueEndsWithLiteral = rawTextValue.endsWith(literal);
611
- var rawValueHasConsecutiveLiterals = rawTextValue.indexOf(literal + literal) >= 0;
569
+ var rawValueStartsWithLiteral = rawInputValue.startsWith(literal);
570
+ var rawValueEndsWithLiteral = rawInputValue.endsWith(literal);
571
+ var rawValueHasConsecutiveLiterals = rawInputValue.indexOf(literal + literal) >= 0;
612
572
  if (rawValueStartsWithLiteral || rawValueEndsWithLiteral || rawValueHasConsecutiveLiterals) {
613
573
  this.resetLeadingZero();
614
574
  this.setExisting(symbol, false);
@@ -631,38 +591,82 @@ var DateObject = /** @class */ (function () {
631
591
  var prefix = '';
632
592
  var current = '';
633
593
  var datePartText = '';
594
+ var basePrefix = '';
595
+ var baseSuffix = '';
634
596
  var suffix = '';
597
+ var datePartStartIndex = originalFormat.indexOf(symbol);
598
+ var datePartEndIndex = originalFormat.lastIndexOf(symbol);
599
+ var segmentLength = datePartEndIndex - datePartStartIndex + 1;
600
+ var hasFixedFormat = (this.format === baseFormat) ||
601
+ (this.format === originalFormat) ||
602
+ (this.format.length === originalFormat.length);
635
603
  if (isInCaretMode) {
636
- var datePartIndex = 0;
637
- var outOfDatePartBounds = false;
604
+ var processedSegmentCharsCount = 0;
638
605
  for (var i = 0; i < baseDate.length; i++) {
639
- var datePartLiteral = datePartsLiterals[datePartIndex];
640
- if (datePartLiteral && datePartLiteral === baseDate[i]) {
641
- datePartIndex++;
642
- }
643
606
  if (baseFormat[i] === symbol) {
644
607
  var existing = this.getExisting(symbol);
645
608
  current += existing ? baseDate[i] : '0';
646
- var rawInputChar = rawTextValue[i];
647
- if (rawInputChar !== baseDate[i] && rawInputChar === datePartsLiterals[datePartIndex].literal) {
648
- outOfDatePartBounds = true;
649
- }
650
- else if (!outOfDatePartBounds) {
651
- if (rawInputChar === undefined) {
652
- var formatOffset = Math.abs(this.format.length - baseFormat.length);
653
- datePartText += rawTextValue[i - formatOffset] || '';
654
- }
655
- else {
656
- datePartText += rawInputChar || '';
609
+ if (isDeleting) {
610
+ // when deleting, process (segmentLength - 1) chars
611
+ if (processedSegmentCharsCount < segmentLength - 1) {
612
+ datePartText += rawInputValue[i] || "";
657
613
  }
614
+ processedSegmentCharsCount++;
615
+ }
616
+ else {
617
+ datePartText += rawInputValue[i] || "";
658
618
  }
659
619
  replaced = true;
660
620
  }
661
621
  else if (!replaced) {
662
622
  prefix += baseDate[i];
623
+ basePrefix += baseDate[i];
663
624
  }
664
625
  else {
665
626
  suffix += baseDate[i];
627
+ baseSuffix += baseDate[i];
628
+ }
629
+ }
630
+ if (hasFixedFormat) {
631
+ if (originalFormat.length < rawInputValue.length) {
632
+ datePartText += currentChar;
633
+ }
634
+ if (datePartText.length > segmentLength) {
635
+ return extend(parseResult, { value: null, switchToNext: false });
636
+ }
637
+ }
638
+ else {
639
+ processedSegmentCharsCount = 0;
640
+ current = "";
641
+ datePartText = "";
642
+ prefix = "";
643
+ suffix = "";
644
+ replaced = false;
645
+ for (var i = 0; i < originalFormat.length; i++) {
646
+ if (originalFormat[i] === symbol) {
647
+ var existing = this.getExisting(symbol);
648
+ current += existing ? baseDate[i] || "" : '0';
649
+ if (isDeleting) {
650
+ // when deleting, process (segmentLength - 1) chars
651
+ if (processedSegmentCharsCount < segmentLength - 1) {
652
+ datePartText += rawInputValue[i] || "";
653
+ }
654
+ processedSegmentCharsCount++;
655
+ }
656
+ else {
657
+ datePartText += rawInputValue[i] || "";
658
+ }
659
+ replaced = true;
660
+ }
661
+ else if (!replaced) {
662
+ prefix += rawInputValue[i] || "";
663
+ }
664
+ else {
665
+ suffix += rawInputValue[i] || "";
666
+ }
667
+ }
668
+ if (originalFormat.length < rawInputValue.length) {
669
+ datePartText += currentChar;
666
670
  }
667
671
  }
668
672
  }
@@ -697,10 +701,6 @@ var DateObject = /** @class */ (function () {
697
701
  }
698
702
  var partPattern = this.partPattern(dateParts.partMap, symbol);
699
703
  var patternValue = partPattern ? partPattern.pattern : null;
700
- if (isInCaretMode && isDeleting) {
701
- var padPrefix = padZero(Math.abs(current.length - datePartText.length));
702
- current = padPrefix + datePartText;
703
- }
704
704
  if (isInCaretMode) {
705
705
  if (isDeleting && !datePartText) {
706
706
  this.setExisting(symbol, false);
@@ -716,14 +716,30 @@ var DateObject = /** @class */ (function () {
716
716
  if (!this.autoCorrectParts) {
717
717
  tryParse = false;
718
718
  }
719
- var middle = resetSegmentValue ? currentChar : (current.substring(i) + currentChar);
720
- if (!tryParse && isInCaretMode) {
719
+ var middle = resetSegmentValue ?
720
+ currentChar :
721
+ isInCaretMode ?
722
+ datePartText :
723
+ (current.substring(i) + currentChar);
724
+ if (isInCaretMode) {
721
725
  // try to make an exact match as there will be only 1 attempt
726
+ tryParse = false;
722
727
  middle = unpadZero(middle);
723
728
  }
724
729
  var middleNumber = parseInt(middle, 10);
725
730
  var candidateDateString = prefix + middle + suffix;
726
731
  parsedDate = this.intl.parseDate(candidateDateString, this.format, this.localeId);
732
+ if (isInCaretMode && !hasFixedFormat && !isValidDate(parsedDate)) {
733
+ // if part of the date is not available, e.g. "d"
734
+ // but an expanded format like "F" is used
735
+ // the element value can be "EEEE, February 1, 2022 3:04:05 AM"
736
+ // which is not parsable by intl
737
+ // use the base prefix and suffix, e.g. convert the candidate date string
738
+ // to "Thursday, February 1, 2022 3:04:05 AM"
739
+ // as "EEEE, February..." is not parsable
740
+ parsedDate = this.intl.parseDate(basePrefix + middle + baseSuffix, this.format, this.localeId);
741
+ datePartText = middle;
742
+ }
727
743
  var isCurrentCharParsable = !isNaN(parseInt(currentChar, 10)) || (isInCaretMode && isDeleting && currentChar === "");
728
744
  if (!parsedDate && !isNaN(middleNumber) && isCurrentCharParsable) {
729
745
  if (symbol === MONTH_SYMBOL && !month) {
@@ -739,23 +755,47 @@ var DateObject = /** @class */ (function () {
739
755
  }
740
756
  if (symbol === 'y') {
741
757
  parsedDate = createDate(parseInt(middle, 10), this.month ? this.value.getMonth() : 0, this.date ? this.value.getDate() : 1, this.hours ? this.value.getHours() : 0, this.minutes ? this.value.getMinutes() : 0, this.seconds ? this.value.getSeconds() : 0, this.milliseconds ? this.value.getMilliseconds() : 0);
742
- if (this.date && parsedDate.getDate() !== this.value.getDate()) {
758
+ if (((isInCaretMode && isValidDate(parsedDate)) ||
759
+ (!isInCaretMode && parsedDate)) && this.date && parsedDate.getDate() !== this.value.getDate()) {
743
760
  parsedDate = lastDayOfMonth(addMonths(parsedDate, -1));
744
761
  }
745
762
  }
746
763
  }
747
- if (parsedDate) {
764
+ if ((isInCaretMode && isValidDate(parsedDate)) || (!isInCaretMode && parsedDate)) {
748
765
  // move to next segment if the part will overflow with next char
749
766
  // when start from empty date (01, then 010), padded zeros should be trimmed
750
767
  var peekDate = this.intl.parseDate("" + prefix + this.peek(middle, patternValue) + suffix, this.format, this.localeId);
751
768
  var patternLength = this.patternLength(patternValue) || patternValue.length;
752
- var patternSatisfied = (leadingZero + (unpadZero(middle) || currentChar).length) >= patternLength;
753
- var switchToNext = peekDate === null || patternSatisfied;
769
+ var leadingZeroOffset = (this.leadingZero || {})[symbol] || 0;
770
+ var patternSatisfied = (leadingZeroOffset + (unpadZero(middle) || currentChar).length) >= patternLength;
771
+ var switchToNext = peekDate === null ||
772
+ (leadingZero[symbol] && patternValue.length <= middle.length) ||
773
+ patternSatisfied;
754
774
  if (this.shouldNormalizeCentury()) {
755
775
  parsedDate = this.normalizeCentury(parsedDate);
756
776
  }
757
777
  this._value = parsedDate;
758
778
  this.setExisting(symbol, true);
779
+ if (isInCaretMode && switchToNext) {
780
+ if (symbol === "M") {
781
+ if (segmentLength <= MONTH_PART_WITH_WORDS_THRESHOLD) {
782
+ var datePartValue = parseToInt(datePartText);
783
+ if (datePartValue >= 2) {
784
+ switchToNext = true;
785
+ }
786
+ else {
787
+ switchToNext = false;
788
+ }
789
+ }
790
+ }
791
+ else {
792
+ switchToNext = switchToNext ?
793
+ hasFixedFormat ?
794
+ datePartText.length === segmentLength :
795
+ datePartText.length > segmentLength :
796
+ switchToNext;
797
+ }
798
+ }
759
799
  return extend(parseResult, { value: this.value, switchToNext: switchToNext });
760
800
  }
761
801
  }
@@ -778,6 +818,9 @@ var DateObject = /** @class */ (function () {
778
818
  this.leadingZero = !this.isAbbrMonth(dateParts.partMap, symbol) ? (_b = {}, _b[symbol] = true, _b) : null;
779
819
  this.setExisting(symbol, false);
780
820
  }
821
+ if (isInCaretMode && datePartText.length > segmentLength) {
822
+ return extend(parseResult, { value: null, switchToNext: false });
823
+ }
781
824
  if (!this.autoCorrectParts) {
782
825
  this.setExisting(symbol, false);
783
826
  // todo check if string is better
@@ -793,11 +836,14 @@ var DateObject = /** @class */ (function () {
793
836
  }
794
837
  if (isNumber(datePartValue)) {
795
838
  var newDate = this.modifyDateSymbolWithValue(this.value, symbol, datePartValue);
839
+ // if (!isEqual(newDate, this.value)) {
840
+ this.setExisting(symbol, false);
796
841
  this.setInvalidDatePart(symbol, {
797
842
  value: datePartValue,
798
843
  date: cloneDate(newDate),
799
844
  startDate: this._partiallyInvalidDate.startDate || cloneDate(this.value)
800
845
  });
846
+ // }
801
847
  }
802
848
  }
803
849
  return extend(parseResult, { value: null, switchToNext: false });
@@ -961,24 +1007,68 @@ var DateObject = /** @class */ (function () {
961
1007
  var resultText = '';
962
1008
  var resultFormat = '';
963
1009
  var format = mask.symbols;
1010
+ var processTextSymbolsEnded = false;
1011
+ var ignoreFormatSymbolsCount = 0;
1012
+ var formattedDates = this.getFormattedInvalidDates(format);
964
1013
  for (var formatSymbolIndex = format.length - 1; formatSymbolIndex >= 0; formatSymbolIndex--) {
1014
+ var partsForSegment = this.getPartsForSegment(mask, formatSymbolIndex);
965
1015
  if (this.knownParts.indexOf(format[formatSymbolIndex]) === -1 || this.getExisting(format[formatSymbolIndex])) {
966
- resultText = text[formatSymbolIndex] + resultText;
1016
+ if (this.autoCorrectParts) {
1017
+ resultText = text[formatSymbolIndex] + resultText;
1018
+ }
1019
+ else {
1020
+ if (text.length !== format.length) {
1021
+ if (processTextSymbolsEnded) {
1022
+ resultText = text[formatSymbolIndex] + resultText;
1023
+ }
1024
+ else if (ignoreFormatSymbolsCount > 0) {
1025
+ resultText = text[formatSymbolIndex] + resultText;
1026
+ ignoreFormatSymbolsCount--;
1027
+ if (ignoreFormatSymbolsCount <= 0) {
1028
+ processTextSymbolsEnded = true;
1029
+ }
1030
+ }
1031
+ else {
1032
+ resultText = (text[formatSymbolIndex + text.length - format.length] || "") + resultText;
1033
+ }
1034
+ }
1035
+ else {
1036
+ resultText = text[formatSymbolIndex] + resultText;
1037
+ }
1038
+ }
967
1039
  resultFormat = format[formatSymbolIndex] + resultFormat;
968
1040
  }
969
1041
  else {
970
1042
  var symbol = format[formatSymbolIndex];
971
- while (formatSymbolIndex >= 0 && symbol === format[formatSymbolIndex]) {
972
- formatSymbolIndex--;
1043
+ var formatSymbolIndexModifier = 0;
1044
+ if (this.autoCorrectParts || (!this.autoCorrectParts && !this.getInvalidDatePartValue(symbol))) {
1045
+ while (formatSymbolIndex >= 0 && symbol === format[formatSymbolIndex]) {
1046
+ formatSymbolIndex--;
1047
+ }
1048
+ formatSymbolIndex++;
973
1049
  }
974
- formatSymbolIndex++;
975
1050
  if (this.leadingZero && this.leadingZero[symbol]) {
976
1051
  resultText = '0' + resultText;
977
1052
  }
978
1053
  else {
979
1054
  if (!this.autoCorrectParts && this.getInvalidDatePartValue(symbol)) {
980
- var segmentText = text.substr(formatSymbolIndex, mask.partMap[formatSymbolIndex].pattern.length);
981
- resultText = segmentText + resultText;
1055
+ var datePartText = this.getInvalidDatePartValue(symbol).toString();
1056
+ if (symbol === "M") {
1057
+ datePartText = (parseToInt(this.getInvalidDatePartValue(symbol)) + JS_MONTH_OFFSET).toString();
1058
+ if (partsForSegment.length > MONTH_PART_WITH_WORDS_THRESHOLD) {
1059
+ resultText = formattedDates[symbol][formatSymbolIndex] + resultText;
1060
+ }
1061
+ else {
1062
+ datePartText = (parseToInt(this.getInvalidDatePartValue(symbol)) + JS_MONTH_OFFSET).toString();
1063
+ resultText = datePartText + resultText;
1064
+ ignoreFormatSymbolsCount = datePartText.length - partsForSegment.length;
1065
+ }
1066
+ }
1067
+ else {
1068
+ resultText = datePartText + resultText;
1069
+ formatSymbolIndexModifier = datePartText.length - 1;
1070
+ ignoreFormatSymbolsCount = datePartText.length - partsForSegment.length;
1071
+ }
982
1072
  }
983
1073
  else {
984
1074
  resultText = this.dateFieldName(mask.partMap[formatSymbolIndex]) + resultText;
@@ -987,6 +1077,9 @@ var DateObject = /** @class */ (function () {
987
1077
  while (resultFormat.length < resultText.length) {
988
1078
  resultFormat = format[formatSymbolIndex] + resultFormat;
989
1079
  }
1080
+ if (formatSymbolIndexModifier !== 0) {
1081
+ formatSymbolIndex = (formatSymbolIndex - formatSymbolIndexModifier) + (text.length - format.length);
1082
+ }
990
1083
  }
991
1084
  }
992
1085
  return { text: resultText, format: resultFormat };
@@ -1154,6 +1247,32 @@ var DateObject = /** @class */ (function () {
1154
1247
  DateObject.prototype.markDatePartsAsExisting = function () {
1155
1248
  this.modifyExisting(true);
1156
1249
  };
1250
+ /**
1251
+ * @hidden
1252
+ */
1253
+ DateObject.prototype.getPartsForSegment = function (mask, partIndex) {
1254
+ var segmentPart = mask.partMap[partIndex];
1255
+ var partsForSegment = [];
1256
+ for (var maskPartIndex = partIndex; maskPartIndex < mask.partMap.length; maskPartIndex++) {
1257
+ var part = mask.partMap[maskPartIndex];
1258
+ if (segmentPart.type === part.type && segmentPart.pattern === part.pattern) {
1259
+ partsForSegment.push(part);
1260
+ }
1261
+ else {
1262
+ break;
1263
+ }
1264
+ }
1265
+ for (var maskPartIndex = partIndex - 1; maskPartIndex >= 0; maskPartIndex--) {
1266
+ var part = mask.partMap[maskPartIndex];
1267
+ if (segmentPart.type === part.type && segmentPart.pattern === part.pattern) {
1268
+ partsForSegment.unshift(part);
1269
+ }
1270
+ else {
1271
+ break;
1272
+ }
1273
+ }
1274
+ return partsForSegment;
1275
+ };
1157
1276
  return DateObject;
1158
1277
  }());
1159
1278
  export { DateObject };
@@ -125,4 +125,4 @@ export var areDatePartsEqualTo = function (date, year, month, day, hour, minutes
125
125
  /**
126
126
  * @hidden
127
127
  */
128
- export var isDate = function (value) { return isPresent(value) && value.getTime && isNumber(value.getTime()); };
128
+ export var isValidDate = function (value) { return isPresent(value) && value.getTime && isNumber(value.getTime()); };