date-and-time 3.4.0 → 3.5.0

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.
@@ -303,12 +303,14 @@ proto.addMonths = function (dateObj, months, utc) {
303
303
  if (utc) {
304
304
  d.setUTCMonth(d.getUTCMonth() + months);
305
305
  if (d.getUTCDate() < dateObj.getUTCDate()) {
306
- return (this || date).addDays(d, -d.getUTCDate(), utc);
306
+ d.setUTCDate(0);
307
+ return d;
307
308
  }
308
309
  } else {
309
310
  d.setMonth(d.getMonth() + months);
310
311
  if (d.getDate() < dateObj.getDate()) {
311
- return (this || date).addDays(d, -d.getDate(), utc);
312
+ d.setDate(0);
313
+ return d;
312
314
  }
313
315
  }
314
316
  return d;
@@ -322,58 +324,54 @@ proto.addMonths = function (dateObj, months, utc) {
322
324
  * @returns {Date} The Date object after adding the value
323
325
  */
324
326
  proto.addDays = function (dateObj, days, utc) {
325
- return (this || date).addHours(dateObj, days * 24, utc);
327
+ var d = new Date(dateObj.getTime());
328
+
329
+ if (utc) {
330
+ d.setUTCDate(d.getUTCDate() + days);
331
+ } else {
332
+ d.setDate(d.getDate() + days);
333
+ }
334
+ return d;
326
335
  };
327
336
 
328
337
  /**
329
338
  * Adding hours
330
339
  * @param {Date} dateObj - A Date object
331
340
  * @param {number} hours - Number of hours to add
332
- * @param {boolean} [utc] - Calculates as UTC
333
341
  * @returns {Date} The Date object after adding the value
334
342
  */
335
- proto.addHours = function (dateObj, hours, utc) {
336
- return (this || date).addMinutes(dateObj, hours * 60, utc);
343
+ proto.addHours = function (dateObj, hours) {
344
+ return new Date(dateObj.getTime() + hours * 60 * 60 * 1000);
337
345
  };
338
346
 
339
347
  /**
340
348
  * Adding minutes
341
349
  * @param {Date} dateObj - A Date object
342
350
  * @param {number} minutes - Number of minutes to add
343
- * @param {boolean} [utc] - Calculates as UTC
344
351
  * @returns {Date} The Date object after adding the value
345
352
  */
346
- proto.addMinutes = function (dateObj, minutes, utc) {
347
- return (this || date).addSeconds(dateObj, minutes * 60, utc);
353
+ proto.addMinutes = function (dateObj, minutes) {
354
+ return new Date(dateObj.getTime() + minutes * 60 * 1000);
348
355
  };
349
356
 
350
357
  /**
351
358
  * Adding seconds
352
359
  * @param {Date} dateObj - A Date object
353
360
  * @param {number} seconds - Number of seconds to add
354
- * @param {boolean} [utc] - Calculates as UTC
355
361
  * @returns {Date} The Date object after adding the value
356
362
  */
357
- proto.addSeconds = function (dateObj, seconds, utc) {
358
- return (this || date).addMilliseconds(dateObj, seconds * 1000, utc);
363
+ proto.addSeconds = function (dateObj, seconds) {
364
+ return new Date(dateObj.getTime() + seconds * 1000);
359
365
  };
360
366
 
361
367
  /**
362
368
  * Adding milliseconds
363
369
  * @param {Date} dateObj - A Date object
364
370
  * @param {number} milliseconds - Number of milliseconds to add
365
- * @param {boolean} [utc] - Calculates as UTC
366
371
  * @returns {Date} The Date object after adding the value
367
372
  */
368
- proto.addMilliseconds = function (dateObj, milliseconds, utc) {
369
- var d = new Date(dateObj.getTime());
370
-
371
- if (utc) {
372
- d.setUTCMilliseconds(d.getUTCMilliseconds() + milliseconds);
373
- } else {
374
- d.setMilliseconds(d.getMilliseconds() + milliseconds);
375
- }
376
- return d;
373
+ proto.addMilliseconds = function (dateObj, milliseconds) {
374
+ return new Date(dateObj.getTime() + milliseconds);
377
375
  };
378
376
 
379
377
  /**
@@ -535,34 +535,59 @@ var plugin = function (proto, date) {
535
535
  };
536
536
  var options = {
537
537
  hour12: false, weekday: 'short', year: 'numeric', month: 'numeric', day: 'numeric',
538
- hour: 'numeric', minute: 'numeric', second: 'numeric', fractionalSecondDigits: 3
538
+ hour: 'numeric', minute: 'numeric', second: 'numeric', fractionalSecondDigits: 3,
539
+ timeZone: 'UTC'
539
540
  };
540
- var formatTZ = function (dateObj, arg, timeZone) {
541
- var parts = (function () {
542
- options.timeZone = timeZone || undefined;
543
- var array = new Intl.DateTimeFormat('en-US', options).formatToParts(dateObj);
544
- var values = {};
541
+ var cache = {
542
+ utc: new Intl.DateTimeFormat('en-US', options)
543
+ };
544
+ var getDateTimeFormat = function (timeZone) {
545
+ if (timeZone) {
546
+ var tz = timeZone.toLowerCase();
545
547
 
546
- for (var i = 0, len = array.length; i < len; i++) {
547
- var type = array[i].type;
548
- var value = array[i].value;
548
+ if (!cache[tz]) {
549
+ options.timeZone = timeZone;
550
+ cache[tz] = new Intl.DateTimeFormat('en-US', options);
551
+ }
552
+ return cache[tz];
553
+ }
554
+ options.timeZone = undefined;
555
+ return new Intl.DateTimeFormat('en-US', options);
556
+ };
557
+ var formatToParts = function (dateTimeFormat, dateObjOrTime) {
558
+ var array = dateTimeFormat.formatToParts(dateObjOrTime),
559
+ values = {};
549
560
 
550
- switch (type) {
551
- case 'weekday':
552
- values[type] = 'SunMonTueWedThuFriSat'.indexOf(value) / 3;
553
- break;
554
- case 'year':
555
- case 'month':
556
- case 'day':
557
- case 'hour':
558
- case 'minute':
559
- case 'second':
560
- case 'fractionalSecond':
561
- values[type] = value | 0;
562
- }
561
+ for (var i = 0, len = array.length; i < len; i++) {
562
+ var type = array[i].type,
563
+ value = array[i].value;
564
+
565
+ switch (type) {
566
+ case 'weekday':
567
+ values[type] = 'SunMonTueWedThuFriSat'.indexOf(value) / 3;
568
+ break;
569
+ case 'hour':
570
+ values[type] = value % 24;
571
+ break;
572
+ case 'year':
573
+ case 'month':
574
+ case 'day':
575
+ case 'minute':
576
+ case 'second':
577
+ case 'fractionalSecond':
578
+ values[type] = value | 0;
563
579
  }
564
- return values;
565
- }());
580
+ }
581
+ return values;
582
+ };
583
+ var getTimeFromParts = function (parts) {
584
+ return Date.UTC(
585
+ parts.year, parts.month - (parts.year < 100 ? 1900 * 12 + 1 : 1), parts.day,
586
+ parts.hour, parts.minute, parts.second, parts.fractionalSecond
587
+ );
588
+ };
589
+ var formatTZ = function (dateObj, arg, timeZone) {
590
+ var parts = formatToParts(getDateTimeFormat(timeZone), dateObj);
566
591
 
567
592
  return date.format({
568
593
  getFullYear: function () { return parts.year; },
@@ -575,18 +600,14 @@ var plugin = function (proto, date) {
575
600
  getDay: function () { return parts.weekday; },
576
601
  getTime: function () { return dateObj.getTime(); },
577
602
  getTimezoneOffset: function () {
578
- return (dateObj.getTime() - Date.UTC(
579
- parts.year, parts.month - (parts.year < 100 ? 1900 * 12 + 1 : 1), parts.day,
580
- parts.hour, parts.minute, parts.second, parts.fractionalSecond
581
- )) / 60000 | 0;
603
+ return (dateObj.getTime() - getTimeFromParts(parts)) / 60000 | 0;
582
604
  },
583
605
  getTimezoneName: function () { return timeZone || undefined; }
584
606
  }, arg);
585
607
  };
586
- var parseTZ = function (dateString, arg, timeZone) {
587
- var pattern = typeof arg === 'string' ? date.compile(arg) : arg;
588
- var dateObj = date.parse(dateString, pattern, !!timeZone);
589
-
608
+ var parseTZ = function (arg1, arg2, timeZone) {
609
+ var pattern = typeof arg2 === 'string' ? date.compile(arg2) : arg2;
610
+ var dateObj = typeof arg1 === 'string' ? date.parse(arg1, pattern, !!timeZone) : arg1;
590
611
  var hasZ = function (array) {
591
612
  for (var i = 1, len = array.length; i < len; i++) {
592
613
  if (!array[i].indexOf('Z')) {
@@ -610,10 +631,8 @@ var plugin = function (proto, date) {
610
631
  return Array.isArray(value) ? value : [];
611
632
  };
612
633
 
613
- options.timeZone = 'UTC';
614
- var dateString2 = new Intl.DateTimeFormat('en-US', options).format(dateObj);
615
- options.timeZone = timeZone || undefined;
616
- var dateTimeFormat = new Intl.DateTimeFormat('en-US', options);
634
+ var dateString2 = getDateTimeFormat('UTC').format(dateObj);
635
+ var dateTimeFormat = getDateTimeFormat(timeZone);
617
636
  var offset = getOffset(timeZone);
618
637
  var comparer = function (d) {
619
638
  return dateString2 === dateTimeFormat.format(d);
@@ -630,6 +649,39 @@ var plugin = function (proto, date) {
630
649
  var transformTZ = function (dateString, arg1, arg2, timeZone) {
631
650
  return formatTZ(date.parse(dateString, arg1), arg2, timeZone);
632
651
  };
652
+ var normalizeDateParts = function (parts, adjustEOM) {
653
+ var d = new Date(Date.UTC(
654
+ parts.year, parts.month - (parts.year < 100 ? 1900 * 12 + 1 : 1), parts.day
655
+ ));
656
+
657
+ if (adjustEOM && d.getUTCDate() < parts.day) {
658
+ d.setUTCDate(0);
659
+ }
660
+ parts.year = d.getUTCFullYear();
661
+ parts.month = d.getUTCMonth() + 1;
662
+ parts.day = d.getUTCDate();
663
+
664
+ return parts;
665
+ };
666
+ var addYearsTZ = function (dateObj, years, timeZone) {
667
+ return addMonthsTZ(dateObj, years * 12, timeZone);
668
+ };
669
+ var addMonthsTZ = function (dateObj, months, timeZone) {
670
+ var parts = formatToParts(getDateTimeFormat(timeZone), dateObj);
671
+
672
+ parts.month += months;
673
+ var dateObj2 = parseTZ(new Date(getTimeFromParts(normalizeDateParts(parts, true))), [], timeZone);
674
+
675
+ return isNaN(dateObj2.getTime()) ? date.addMonths(dateObj, months, true) : dateObj2;
676
+ };
677
+ var addDaysTZ = function (dateObj, days, timeZone) {
678
+ var parts = formatToParts(getDateTimeFormat(timeZone), dateObj);
679
+
680
+ parts.day += days;
681
+ var dateObj2 = parseTZ(new Date(getTimeFromParts(normalizeDateParts(parts, false))), [], timeZone);
682
+
683
+ return isNaN(dateObj2.getTime()) ? date.addDays(dateObj, days, true) : dateObj2;
684
+ };
633
685
 
634
686
  var name = 'timezone';
635
687
 
@@ -661,7 +713,10 @@ var plugin = function (proto, date) {
661
713
  extender: {
662
714
  formatTZ: formatTZ,
663
715
  parseTZ: parseTZ,
664
- transformTZ: transformTZ
716
+ transformTZ: transformTZ,
717
+ addYearsTZ: addYearsTZ,
718
+ addMonthsTZ: addMonthsTZ,
719
+ addDaysTZ: addDaysTZ
665
720
  }
666
721
  });
667
722
  return name;
@@ -535,34 +535,59 @@ var plugin = function (proto, date) {
535
535
  };
536
536
  var options = {
537
537
  hour12: false, weekday: 'short', year: 'numeric', month: 'numeric', day: 'numeric',
538
- hour: 'numeric', minute: 'numeric', second: 'numeric', fractionalSecondDigits: 3
538
+ hour: 'numeric', minute: 'numeric', second: 'numeric', fractionalSecondDigits: 3,
539
+ timeZone: 'UTC'
539
540
  };
540
- var formatTZ = function (dateObj, arg, timeZone) {
541
- var parts = (function () {
542
- options.timeZone = timeZone || undefined;
543
- var array = new Intl.DateTimeFormat('en-US', options).formatToParts(dateObj);
544
- var values = {};
541
+ var cache = {
542
+ utc: new Intl.DateTimeFormat('en-US', options)
543
+ };
544
+ var getDateTimeFormat = function (timeZone) {
545
+ if (timeZone) {
546
+ var tz = timeZone.toLowerCase();
545
547
 
546
- for (var i = 0, len = array.length; i < len; i++) {
547
- var type = array[i].type;
548
- var value = array[i].value;
548
+ if (!cache[tz]) {
549
+ options.timeZone = timeZone;
550
+ cache[tz] = new Intl.DateTimeFormat('en-US', options);
551
+ }
552
+ return cache[tz];
553
+ }
554
+ options.timeZone = undefined;
555
+ return new Intl.DateTimeFormat('en-US', options);
556
+ };
557
+ var formatToParts = function (dateTimeFormat, dateObjOrTime) {
558
+ var array = dateTimeFormat.formatToParts(dateObjOrTime),
559
+ values = {};
549
560
 
550
- switch (type) {
551
- case 'weekday':
552
- values[type] = 'SunMonTueWedThuFriSat'.indexOf(value) / 3;
553
- break;
554
- case 'year':
555
- case 'month':
556
- case 'day':
557
- case 'hour':
558
- case 'minute':
559
- case 'second':
560
- case 'fractionalSecond':
561
- values[type] = value | 0;
562
- }
561
+ for (var i = 0, len = array.length; i < len; i++) {
562
+ var type = array[i].type,
563
+ value = array[i].value;
564
+
565
+ switch (type) {
566
+ case 'weekday':
567
+ values[type] = 'SunMonTueWedThuFriSat'.indexOf(value) / 3;
568
+ break;
569
+ case 'hour':
570
+ values[type] = value % 24;
571
+ break;
572
+ case 'year':
573
+ case 'month':
574
+ case 'day':
575
+ case 'minute':
576
+ case 'second':
577
+ case 'fractionalSecond':
578
+ values[type] = value | 0;
563
579
  }
564
- return values;
565
- }());
580
+ }
581
+ return values;
582
+ };
583
+ var getTimeFromParts = function (parts) {
584
+ return Date.UTC(
585
+ parts.year, parts.month - (parts.year < 100 ? 1900 * 12 + 1 : 1), parts.day,
586
+ parts.hour, parts.minute, parts.second, parts.fractionalSecond
587
+ );
588
+ };
589
+ var formatTZ = function (dateObj, arg, timeZone) {
590
+ var parts = formatToParts(getDateTimeFormat(timeZone), dateObj);
566
591
 
567
592
  return date.format({
568
593
  getFullYear: function () { return parts.year; },
@@ -575,18 +600,14 @@ var plugin = function (proto, date) {
575
600
  getDay: function () { return parts.weekday; },
576
601
  getTime: function () { return dateObj.getTime(); },
577
602
  getTimezoneOffset: function () {
578
- return (dateObj.getTime() - Date.UTC(
579
- parts.year, parts.month - (parts.year < 100 ? 1900 * 12 + 1 : 1), parts.day,
580
- parts.hour, parts.minute, parts.second, parts.fractionalSecond
581
- )) / 60000 | 0;
603
+ return (dateObj.getTime() - getTimeFromParts(parts)) / 60000 | 0;
582
604
  },
583
605
  getTimezoneName: function () { return timeZone || undefined; }
584
606
  }, arg);
585
607
  };
586
- var parseTZ = function (dateString, arg, timeZone) {
587
- var pattern = typeof arg === 'string' ? date.compile(arg) : arg;
588
- var dateObj = date.parse(dateString, pattern, !!timeZone);
589
-
608
+ var parseTZ = function (arg1, arg2, timeZone) {
609
+ var pattern = typeof arg2 === 'string' ? date.compile(arg2) : arg2;
610
+ var dateObj = typeof arg1 === 'string' ? date.parse(arg1, pattern, !!timeZone) : arg1;
590
611
  var hasZ = function (array) {
591
612
  for (var i = 1, len = array.length; i < len; i++) {
592
613
  if (!array[i].indexOf('Z')) {
@@ -610,10 +631,8 @@ var plugin = function (proto, date) {
610
631
  return Array.isArray(value) ? value : [];
611
632
  };
612
633
 
613
- options.timeZone = 'UTC';
614
- var dateString2 = new Intl.DateTimeFormat('en-US', options).format(dateObj);
615
- options.timeZone = timeZone || undefined;
616
- var dateTimeFormat = new Intl.DateTimeFormat('en-US', options);
634
+ var dateString2 = getDateTimeFormat('UTC').format(dateObj);
635
+ var dateTimeFormat = getDateTimeFormat(timeZone);
617
636
  var offset = getOffset(timeZone);
618
637
  var comparer = function (d) {
619
638
  return dateString2 === dateTimeFormat.format(d);
@@ -630,6 +649,39 @@ var plugin = function (proto, date) {
630
649
  var transformTZ = function (dateString, arg1, arg2, timeZone) {
631
650
  return formatTZ(date.parse(dateString, arg1), arg2, timeZone);
632
651
  };
652
+ var normalizeDateParts = function (parts, adjustEOM) {
653
+ var d = new Date(Date.UTC(
654
+ parts.year, parts.month - (parts.year < 100 ? 1900 * 12 + 1 : 1), parts.day
655
+ ));
656
+
657
+ if (adjustEOM && d.getUTCDate() < parts.day) {
658
+ d.setUTCDate(0);
659
+ }
660
+ parts.year = d.getUTCFullYear();
661
+ parts.month = d.getUTCMonth() + 1;
662
+ parts.day = d.getUTCDate();
663
+
664
+ return parts;
665
+ };
666
+ var addYearsTZ = function (dateObj, years, timeZone) {
667
+ return addMonthsTZ(dateObj, years * 12, timeZone);
668
+ };
669
+ var addMonthsTZ = function (dateObj, months, timeZone) {
670
+ var parts = formatToParts(getDateTimeFormat(timeZone), dateObj);
671
+
672
+ parts.month += months;
673
+ var dateObj2 = parseTZ(new Date(getTimeFromParts(normalizeDateParts(parts, true))), [], timeZone);
674
+
675
+ return isNaN(dateObj2.getTime()) ? date.addMonths(dateObj, months, true) : dateObj2;
676
+ };
677
+ var addDaysTZ = function (dateObj, days, timeZone) {
678
+ var parts = formatToParts(getDateTimeFormat(timeZone), dateObj);
679
+
680
+ parts.day += days;
681
+ var dateObj2 = parseTZ(new Date(getTimeFromParts(normalizeDateParts(parts, false))), [], timeZone);
682
+
683
+ return isNaN(dateObj2.getTime()) ? date.addDays(dateObj, days, true) : dateObj2;
684
+ };
633
685
 
634
686
  var name = 'timezone';
635
687
 
@@ -661,7 +713,10 @@ var plugin = function (proto, date) {
661
713
  extender: {
662
714
  formatTZ: formatTZ,
663
715
  parseTZ: parseTZ,
664
- transformTZ: transformTZ
716
+ transformTZ: transformTZ,
717
+ addYearsTZ: addYearsTZ,
718
+ addMonthsTZ: addMonthsTZ,
719
+ addDaysTZ: addDaysTZ
665
720
  }
666
721
  });
667
722
  return name;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "date-and-time",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "A Minimalist DateTime utility for Node.js and the browser",
5
5
  "main": "date-and-time.js",
6
6
  "module": "esm/date-and-time.es.js",
@@ -51,8 +51,8 @@
51
51
  "devDependencies": {
52
52
  "@rollup/plugin-terser": "^0.4.4",
53
53
  "expect.js": "^0.3.1",
54
- "mocha": "^10.6.0",
55
- "rollup": "^4.18.0",
54
+ "mocha": "^10.7.3",
55
+ "rollup": "^4.20.0",
56
56
  "tsd": "^0.31.1"
57
57
  }
58
58
  }
@@ -74,6 +74,33 @@ declare module '../date-and-time' {
74
74
  * @returns A formatted string
75
75
  */
76
76
  export function transformTZ(dateString: string, compiledObj1: string[], compiledObj2: string[], timeZone?: string): string;
77
+
78
+ /**
79
+ * Adding years considering time zones
80
+ * @param dateObj - A Date object
81
+ * @param years - The number of years to add
82
+ * @param [timeZone] - The time zone to use for the calculation
83
+ * @returns The Date object after adding the specified number of years
84
+ */
85
+ export function addYearsTZ(dateObj: Date, years: number, timeZone?: string): Date;
86
+
87
+ /**
88
+ * Adding months considering time zones
89
+ * @param dateObj - A Date object
90
+ * @param months - The number of months to add
91
+ * @param [timeZone] - The time zone to use for the calculation
92
+ * @returns The Date object after adding the specified number of months
93
+ */
94
+ export function addMonthsTZ(dateObj: Date, months: number, timeZone?: string): Date;
95
+
96
+ /**
97
+ * Adding days considering time zones
98
+ * @param dateObj - A Date object
99
+ * @param days - The number of days to add
100
+ * @param [timeZone] - The time zone to use for the calculation
101
+ * @returns The Date object after adding the specified number of days
102
+ */
103
+ export function addDaysTZ(dateObj: Date, days: number, timeZone?: string): Date;
77
104
  }
78
105
 
79
106
  export default function (proto: unknown, date?: unknown): string;
@@ -541,34 +541,59 @@
541
541
  };
542
542
  var options = {
543
543
  hour12: false, weekday: 'short', year: 'numeric', month: 'numeric', day: 'numeric',
544
- hour: 'numeric', minute: 'numeric', second: 'numeric', fractionalSecondDigits: 3
544
+ hour: 'numeric', minute: 'numeric', second: 'numeric', fractionalSecondDigits: 3,
545
+ timeZone: 'UTC'
545
546
  };
546
- var formatTZ = function (dateObj, arg, timeZone) {
547
- var parts = (function () {
548
- options.timeZone = timeZone || undefined;
549
- var array = new Intl.DateTimeFormat('en-US', options).formatToParts(dateObj);
550
- var values = {};
547
+ var cache = {
548
+ utc: new Intl.DateTimeFormat('en-US', options)
549
+ };
550
+ var getDateTimeFormat = function (timeZone) {
551
+ if (timeZone) {
552
+ var tz = timeZone.toLowerCase();
551
553
 
552
- for (var i = 0, len = array.length; i < len; i++) {
553
- var type = array[i].type;
554
- var value = array[i].value;
554
+ if (!cache[tz]) {
555
+ options.timeZone = timeZone;
556
+ cache[tz] = new Intl.DateTimeFormat('en-US', options);
557
+ }
558
+ return cache[tz];
559
+ }
560
+ options.timeZone = undefined;
561
+ return new Intl.DateTimeFormat('en-US', options);
562
+ };
563
+ var formatToParts = function (dateTimeFormat, dateObjOrTime) {
564
+ var array = dateTimeFormat.formatToParts(dateObjOrTime),
565
+ values = {};
555
566
 
556
- switch (type) {
557
- case 'weekday':
558
- values[type] = 'SunMonTueWedThuFriSat'.indexOf(value) / 3;
559
- break;
560
- case 'year':
561
- case 'month':
562
- case 'day':
563
- case 'hour':
564
- case 'minute':
565
- case 'second':
566
- case 'fractionalSecond':
567
- values[type] = value | 0;
568
- }
567
+ for (var i = 0, len = array.length; i < len; i++) {
568
+ var type = array[i].type,
569
+ value = array[i].value;
570
+
571
+ switch (type) {
572
+ case 'weekday':
573
+ values[type] = 'SunMonTueWedThuFriSat'.indexOf(value) / 3;
574
+ break;
575
+ case 'hour':
576
+ values[type] = value % 24;
577
+ break;
578
+ case 'year':
579
+ case 'month':
580
+ case 'day':
581
+ case 'minute':
582
+ case 'second':
583
+ case 'fractionalSecond':
584
+ values[type] = value | 0;
569
585
  }
570
- return values;
571
- }());
586
+ }
587
+ return values;
588
+ };
589
+ var getTimeFromParts = function (parts) {
590
+ return Date.UTC(
591
+ parts.year, parts.month - (parts.year < 100 ? 1900 * 12 + 1 : 1), parts.day,
592
+ parts.hour, parts.minute, parts.second, parts.fractionalSecond
593
+ );
594
+ };
595
+ var formatTZ = function (dateObj, arg, timeZone) {
596
+ var parts = formatToParts(getDateTimeFormat(timeZone), dateObj);
572
597
 
573
598
  return date.format({
574
599
  getFullYear: function () { return parts.year; },
@@ -581,18 +606,14 @@
581
606
  getDay: function () { return parts.weekday; },
582
607
  getTime: function () { return dateObj.getTime(); },
583
608
  getTimezoneOffset: function () {
584
- return (dateObj.getTime() - Date.UTC(
585
- parts.year, parts.month - (parts.year < 100 ? 1900 * 12 + 1 : 1), parts.day,
586
- parts.hour, parts.minute, parts.second, parts.fractionalSecond
587
- )) / 60000 | 0;
609
+ return (dateObj.getTime() - getTimeFromParts(parts)) / 60000 | 0;
588
610
  },
589
611
  getTimezoneName: function () { return timeZone || undefined; }
590
612
  }, arg);
591
613
  };
592
- var parseTZ = function (dateString, arg, timeZone) {
593
- var pattern = typeof arg === 'string' ? date.compile(arg) : arg;
594
- var dateObj = date.parse(dateString, pattern, !!timeZone);
595
-
614
+ var parseTZ = function (arg1, arg2, timeZone) {
615
+ var pattern = typeof arg2 === 'string' ? date.compile(arg2) : arg2;
616
+ var dateObj = typeof arg1 === 'string' ? date.parse(arg1, pattern, !!timeZone) : arg1;
596
617
  var hasZ = function (array) {
597
618
  for (var i = 1, len = array.length; i < len; i++) {
598
619
  if (!array[i].indexOf('Z')) {
@@ -616,10 +637,8 @@
616
637
  return Array.isArray(value) ? value : [];
617
638
  };
618
639
 
619
- options.timeZone = 'UTC';
620
- var dateString2 = new Intl.DateTimeFormat('en-US', options).format(dateObj);
621
- options.timeZone = timeZone || undefined;
622
- var dateTimeFormat = new Intl.DateTimeFormat('en-US', options);
640
+ var dateString2 = getDateTimeFormat('UTC').format(dateObj);
641
+ var dateTimeFormat = getDateTimeFormat(timeZone);
623
642
  var offset = getOffset(timeZone);
624
643
  var comparer = function (d) {
625
644
  return dateString2 === dateTimeFormat.format(d);
@@ -636,6 +655,39 @@
636
655
  var transformTZ = function (dateString, arg1, arg2, timeZone) {
637
656
  return formatTZ(date.parse(dateString, arg1), arg2, timeZone);
638
657
  };
658
+ var normalizeDateParts = function (parts, adjustEOM) {
659
+ var d = new Date(Date.UTC(
660
+ parts.year, parts.month - (parts.year < 100 ? 1900 * 12 + 1 : 1), parts.day
661
+ ));
662
+
663
+ if (adjustEOM && d.getUTCDate() < parts.day) {
664
+ d.setUTCDate(0);
665
+ }
666
+ parts.year = d.getUTCFullYear();
667
+ parts.month = d.getUTCMonth() + 1;
668
+ parts.day = d.getUTCDate();
669
+
670
+ return parts;
671
+ };
672
+ var addYearsTZ = function (dateObj, years, timeZone) {
673
+ return addMonthsTZ(dateObj, years * 12, timeZone);
674
+ };
675
+ var addMonthsTZ = function (dateObj, months, timeZone) {
676
+ var parts = formatToParts(getDateTimeFormat(timeZone), dateObj);
677
+
678
+ parts.month += months;
679
+ var dateObj2 = parseTZ(new Date(getTimeFromParts(normalizeDateParts(parts, true))), [], timeZone);
680
+
681
+ return isNaN(dateObj2.getTime()) ? date.addMonths(dateObj, months, true) : dateObj2;
682
+ };
683
+ var addDaysTZ = function (dateObj, days, timeZone) {
684
+ var parts = formatToParts(getDateTimeFormat(timeZone), dateObj);
685
+
686
+ parts.day += days;
687
+ var dateObj2 = parseTZ(new Date(getTimeFromParts(normalizeDateParts(parts, false))), [], timeZone);
688
+
689
+ return isNaN(dateObj2.getTime()) ? date.addDays(dateObj, days, true) : dateObj2;
690
+ };
639
691
 
640
692
  var name = 'timezone';
641
693
 
@@ -667,7 +719,10 @@
667
719
  extender: {
668
720
  formatTZ: formatTZ,
669
721
  parseTZ: parseTZ,
670
- transformTZ: transformTZ
722
+ transformTZ: transformTZ,
723
+ addYearsTZ: addYearsTZ,
724
+ addMonthsTZ: addMonthsTZ,
725
+ addDaysTZ: addDaysTZ
671
726
  }
672
727
  });
673
728
  return name;