mirror of
				https://github.com/therootcompany/tz.js
				synced 2025-11-03 22:32:47 +00:00 
			
		
		
		
	make Prettier
This commit is contained in:
		
							parent
							
								
									aaa31a25b9
								
							
						
					
					
						commit
						ff9e266052
					
				
							
								
								
									
										1
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.prettierignore
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					*.min.js
 | 
				
			||||||
							
								
								
									
										7
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "printWidth": 80,
 | 
				
			||||||
 | 
					  "tabWidth": 2,
 | 
				
			||||||
 | 
					  "singleQuote": false,
 | 
				
			||||||
 | 
					  "bracketSpacing": true,
 | 
				
			||||||
 | 
					  "semi": true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										74
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										74
									
								
								README.md
									
									
									
									
									
								
							@ -1,8 +1,7 @@
 | 
				
			|||||||
# [xtz.js](https://github.com/therootcompany/tz.js)
 | 
					# [xtz.js](https://github.com/therootcompany/tz.js)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
A fast, lightweight, zero-dependency library to
 | 
					A fast, lightweight, zero-dependency library to translate between Time Zones and UTC with native `Intl.DateTimeFormat`
 | 
				
			||||||
translate between Time Zones and UTC with native
 | 
					in ~100 LoC. For Node.js & Browsers.
 | 
				
			||||||
`Intl.DateTimeFormat` in ~100 LoC. For Node.js & Browsers.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
XTZ is a poor man's Temporal polyfill, but just for time zones.
 | 
					XTZ is a poor man's Temporal polyfill, but just for time zones.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -50,14 +49,14 @@ utcDate.toISOString();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Features
 | 
					# Features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-   [x] Translate a UTC time to a Time Zone
 | 
					- [x] Translate a UTC time to a Time Zone
 | 
				
			||||||
-   [x] Translate a Zoned time to UTC
 | 
					- [x] Translate a Zoned time to UTC
 | 
				
			||||||
-   [x] Handles **Daylight Savings**, Weird Time Zones, etc...
 | 
					- [x] Handles **Daylight Savings**, Weird Time Zones, etc...
 | 
				
			||||||
    -   [x] Well-tested `npm run test`
 | 
					  - [x] Well-tested `npm run test`
 | 
				
			||||||
-   [x] Lightweight (No deps)
 | 
					- [x] Lightweight (No deps)
 | 
				
			||||||
    -   5kb Source + Comments
 | 
					  - 5kb Source + Comments
 | 
				
			||||||
    -   2.5kb Minified
 | 
					  - 2.5kb Minified
 | 
				
			||||||
    -   <1kb `gzip`d
 | 
					  - <1kb `gzip`d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Compatible with Browsers, and Node.js.
 | 
					Compatible with Browsers, and Node.js.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -83,10 +82,10 @@ var TZ = require("xtz");
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# API
 | 
					# API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-   `toTimeZone(utcDate, timeZone)`
 | 
					- `toTimeZone(utcDate, timeZone)`
 | 
				
			||||||
-   `toTimeZoneISOString(isoString, timeZone)`
 | 
					- `toTimeZoneISOString(isoString, timeZone)`
 | 
				
			||||||
-   `toUTC(dtString, timeZone)`
 | 
					- `toUTC(dtString, timeZone)`
 | 
				
			||||||
-   `toUTCISOString(dtString, timeZone)`
 | 
					- `toUTCISOString(dtString, timeZone)`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## `toTimeZone(utcDate, timeZone)`
 | 
					## `toTimeZone(utcDate, timeZone)`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -115,8 +114,8 @@ You can also use a date object with an absolute UTC time:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
```js
 | 
					```js
 | 
				
			||||||
var tzDate = TZ.toTimeZone(
 | 
					var tzDate = TZ.toTimeZone(
 | 
				
			||||||
    new Date("2021-11-07T08:15:59.000Z"),
 | 
					  new Date("2021-11-07T08:15:59.000Z"),
 | 
				
			||||||
    "America/New_York"
 | 
					  "America/New_York"
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -155,12 +154,13 @@ Or our bespoke date object:
 | 
				
			|||||||
var utcDate = TZ.toUTC("2021-11-07 03:15:59.000", "America/New_York");
 | 
					var utcDate = TZ.toUTC("2021-11-07 03:15:59.000", "America/New_York");
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can also use a date object as the source time, but the date's UTC time will be treated as **_relative to time zone_** rather than absolute (this is a workaround for JavaScript's lack of bi-directional timezone support).
 | 
					You can also use a date object as the source time, but the date's UTC time will be treated as **_relative to time
 | 
				
			||||||
 | 
					zone_** rather than absolute (this is a workaround for JavaScript's lack of bi-directional timezone support).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```js
 | 
					```js
 | 
				
			||||||
var utcDate = TZ.toUTC(
 | 
					var utcDate = TZ.toUTC(
 | 
				
			||||||
    new Date("2021-11-07T03:15:59.000Z"),
 | 
					  new Date("2021-11-07T03:15:59.000Z"),
 | 
				
			||||||
    "America/New_York"
 | 
					  "America/New_York"
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -173,30 +173,32 @@ utcDate.toISOString();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
> In 2021 Daylight Savings (in the US)
 | 
					> In 2021 Daylight Savings (in the US)
 | 
				
			||||||
>
 | 
					>
 | 
				
			||||||
> -   begins at 2am on March 14th
 | 
					> - begins at 2am on March 14th
 | 
				
			||||||
> -   ends at 2am on November 7th
 | 
					> - ends at 2am on November 7th
 | 
				
			||||||
>
 | 
					>
 | 
				
			||||||
> See <https://www.timeanddate.com/time/change/usa>.
 | 
					> See <https://www.timeanddate.com/time/change/usa>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Q: What happens in March when 2am is skipped?
 | 
					Q: What happens in March when 2am is skipped?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-   A: Although 2am is not a valid time, rather than throwing an error this library will resolve to 1am instead, which is an hour early in real ("tick-tock" or "monotonic") time.
 | 
					- A: Although 2am is not a valid time, rather than throwing an error this library will resolve to 1am instead, which
 | 
				
			||||||
    ```js
 | 
					  is an hour early in real ("tick-tock" or "monotonic") time.
 | 
				
			||||||
    var utcDate = TZ.toUTC("2021-03-14 02:15:59.000", "America/New_York");
 | 
					  ```js
 | 
				
			||||||
    utcDate.toISOString();
 | 
					  var utcDate = TZ.toUTC("2021-03-14 02:15:59.000", "America/New_York");
 | 
				
			||||||
    // "2021-03-14T02:15:59.000-0400"
 | 
					  utcDate.toISOString();
 | 
				
			||||||
    // (same as "2021-03-14T01:15:59.000-0500")
 | 
					  // "2021-03-14T02:15:59.000-0400"
 | 
				
			||||||
    ```
 | 
					  // (same as "2021-03-14T01:15:59.000-0500")
 | 
				
			||||||
 | 
					  ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Q: What happens in November when 2am happens twice?
 | 
					Q: What happens in November when 2am happens twice?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-   A: Although both 2ams are distinguishable with ISO offset times, only the first can be resolved from a local time with this library.
 | 
					- A: Although both 2ams are distinguishable with ISO offset times, only the first can be resolved from a local time
 | 
				
			||||||
    ```js
 | 
					  with this library.
 | 
				
			||||||
    var utcDate = TZ.toUTC("2021-11-07 01:15:59.000", "America/New_York");
 | 
					  ```js
 | 
				
			||||||
    utcDate.toISOString();
 | 
					  var utcDate = TZ.toUTC("2021-11-07 01:15:59.000", "America/New_York");
 | 
				
			||||||
    // "2021-11-07T01:15:59.000-0400", same as "2021-11-07T05:15:59.000Z"
 | 
					  utcDate.toISOString();
 | 
				
			||||||
    // (an hour before the 2nd 2am at "2021-11-07T01:15:59.000-0500")
 | 
					  // "2021-11-07T01:15:59.000-0400", same as "2021-11-07T05:15:59.000Z"
 | 
				
			||||||
    ```
 | 
					  // (an hour before the 2nd 2am at "2021-11-07T01:15:59.000-0500")
 | 
				
			||||||
 | 
					  ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# List of Time Zones
 | 
					# List of Time Zones
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										142
									
								
								examples.js
									
									
									
									
									
								
							
							
						
						
									
										142
									
								
								examples.js
									
									
									
									
									
								
							@ -1,89 +1,81 @@
 | 
				
			|||||||
var XTZ;
 | 
					var XTZ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function () {
 | 
					(function () {
 | 
				
			||||||
    "use strict";
 | 
					  "use strict";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!XTZ) {
 | 
					  if (!XTZ) {
 | 
				
			||||||
        try {
 | 
					    try {
 | 
				
			||||||
            XTZ = require("xtz");
 | 
					      XTZ = require("xtz");
 | 
				
			||||||
        } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
            XTZ = require("./xtz.js");
 | 
					      XTZ = require("./xtz.js");
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var TZ = XTZ;
 | 
					  var TZ = XTZ;
 | 
				
			||||||
    var tzDate;
 | 
					  var tzDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
    // UTC-absolute time translated to a Time Zone
 | 
					  // UTC-absolute time translated to a Time Zone
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
    function demo1() {
 | 
					  function demo1() {
 | 
				
			||||||
        console.info("What's the UTC equivalent of 8:15am in New York?");
 | 
					    console.info("What's the UTC equivalent of 8:15am in New York?");
 | 
				
			||||||
        console.info();
 | 
					    console.info();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        console.info("\t// during daylight savings");
 | 
					    console.info("\t// during daylight savings");
 | 
				
			||||||
        console.info(
 | 
					    console.info(`\tXTZ.toUTC("2021-03-14 08:15:59.000", "America/New_York")`);
 | 
				
			||||||
            `\tXTZ.toUTC("2021-03-14 08:15:59.000", "America/New_York")`
 | 
					    console.info(`\ttzDate.toISOString()`);
 | 
				
			||||||
        );
 | 
					    tzDate = XTZ.toUTC("2021-03-14 08:15:59.000", "America/New_York");
 | 
				
			||||||
        console.info(`\ttzDate.toISOString()`);
 | 
					    console.info(
 | 
				
			||||||
        tzDate = XTZ.toUTC("2021-03-14 08:15:59.000", "America/New_York");
 | 
					      "\t" + tzDate.toISOString(),
 | 
				
			||||||
        console.info(
 | 
					      "// same as",
 | 
				
			||||||
            "\t" + tzDate.toISOString(),
 | 
					      new Date(tzDate.toISOString()).toISOString()
 | 
				
			||||||
            "// same as",
 | 
					    );
 | 
				
			||||||
            new Date(tzDate.toISOString()).toISOString()
 | 
					    console.info();
 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        console.info();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        console.info("\t// during standard time");
 | 
					    console.info("\t// during standard time");
 | 
				
			||||||
        console.info(
 | 
					    console.info(`\tXTZ.toUTC("2021-11-07 08:15:59.000", "America/New_York")`);
 | 
				
			||||||
            `\tXTZ.toUTC("2021-11-07 08:15:59.000", "America/New_York")`
 | 
					    console.info(`\ttzDate.toISOString()`);
 | 
				
			||||||
        );
 | 
					    tzDate = XTZ.toUTC("2021-11-07 08:15:59.000", "America/New_York");
 | 
				
			||||||
        console.info(`\ttzDate.toISOString()`);
 | 
					    console.info(
 | 
				
			||||||
        tzDate = XTZ.toUTC("2021-11-07 08:15:59.000", "America/New_York");
 | 
					      "\t" + tzDate.toISOString(),
 | 
				
			||||||
        console.info(
 | 
					      "// same as",
 | 
				
			||||||
            "\t" + tzDate.toISOString(),
 | 
					      new Date(tzDate.toISOString()).toISOString()
 | 
				
			||||||
            "// same as",
 | 
					    );
 | 
				
			||||||
            new Date(tzDate.toISOString()).toISOString()
 | 
					    console.info();
 | 
				
			||||||
        );
 | 
					  }
 | 
				
			||||||
        console.info();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
    // Time Zone-relative time translated to UTC
 | 
					  // Time Zone-relative time translated to UTC
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
    function demo2() {
 | 
					  function demo2() {
 | 
				
			||||||
        console.info(
 | 
					    console.info("What time is it in New York at 8:15am on March 14th UTC?");
 | 
				
			||||||
            "What time is it in New York at 8:15am on March 14th UTC?"
 | 
					    console.info();
 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        console.info();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        console.info("\t// during daylight savings");
 | 
					    console.info("\t// during daylight savings");
 | 
				
			||||||
        console.info(
 | 
					    console.info(
 | 
				
			||||||
            `\tXTZ.toTimeZone("2021-03-14T08:15:59.000Z", "America/New_York")`
 | 
					      `\tXTZ.toTimeZone("2021-03-14T08:15:59.000Z", "America/New_York")`
 | 
				
			||||||
        );
 | 
					    );
 | 
				
			||||||
        console.info(`\ttzDate.toISOString()`);
 | 
					    console.info(`\ttzDate.toISOString()`);
 | 
				
			||||||
        tzDate = XTZ.toTimeZone("2021-03-14T08:15:59.000Z", "America/New_York");
 | 
					    tzDate = XTZ.toTimeZone("2021-03-14T08:15:59.000Z", "America/New_York");
 | 
				
			||||||
        console.info(
 | 
					    console.info(
 | 
				
			||||||
            "\t" + tzDate.toISOString(),
 | 
					      "\t" + tzDate.toISOString(),
 | 
				
			||||||
            "// same as",
 | 
					      "// same as",
 | 
				
			||||||
            new Date(tzDate.toISOString()).toISOString()
 | 
					      new Date(tzDate.toISOString()).toISOString()
 | 
				
			||||||
        );
 | 
					    );
 | 
				
			||||||
        console.info();
 | 
					    console.info();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        console.info("\t// during standard time");
 | 
					    console.info("\t// during standard time");
 | 
				
			||||||
        console.info(
 | 
					    console.info(`\tXTZ.toUTC("2021-11-07T08:15:59.000Z", "America/New_York")`);
 | 
				
			||||||
            `\tXTZ.toUTC("2021-11-07T08:15:59.000Z", "America/New_York")`
 | 
					    console.info(`\ttzDate.toISOString()`);
 | 
				
			||||||
        );
 | 
					    tzDate = XTZ.toUTC("2021-11-07T08:15:59.000Z", "America/New_York");
 | 
				
			||||||
        console.info(`\ttzDate.toISOString()`);
 | 
					    console.info(
 | 
				
			||||||
        tzDate = XTZ.toUTC("2021-11-07T08:15:59.000Z", "America/New_York");
 | 
					      "\t" + tzDate.toISOString(),
 | 
				
			||||||
        console.info(
 | 
					      "// same as",
 | 
				
			||||||
            "\t" + tzDate.toISOString(),
 | 
					      new Date(tzDate.toISOString()).toISOString()
 | 
				
			||||||
            "// same as",
 | 
					    );
 | 
				
			||||||
            new Date(tzDate.toISOString()).toISOString()
 | 
					    console.info();
 | 
				
			||||||
        );
 | 
					  }
 | 
				
			||||||
        console.info();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    demo1();
 | 
					  demo1();
 | 
				
			||||||
    demo2();
 | 
					  demo2();
 | 
				
			||||||
})();
 | 
					})();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										556
									
								
								test.js
									
									
									
									
									
								
							
							
						
						
									
										556
									
								
								test.js
									
									
									
									
									
								
							@ -3,314 +3,314 @@
 | 
				
			|||||||
var TZ = require("./");
 | 
					var TZ = require("./");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function testUtcToTz(t) {
 | 
					function testUtcToTz(t) {
 | 
				
			||||||
    var result = TZ.toTimeZone.apply(TZ, t.inputs).toISOString();
 | 
					  var result = TZ.toTimeZone.apply(TZ, t.inputs).toISOString();
 | 
				
			||||||
    if (t.result !== result) {
 | 
					  if (t.result !== result) {
 | 
				
			||||||
        throw new Error(
 | 
					    throw new Error(
 | 
				
			||||||
            `Invalid UTC to TZ conversion for ${t.desc}:\n` +
 | 
					      `Invalid UTC to TZ conversion for ${t.desc}:\n` +
 | 
				
			||||||
                `\tExpected: ${t.result}\n` +
 | 
					        `\tExpected: ${t.result}\n` +
 | 
				
			||||||
                `\tActual: ${result}\n`
 | 
					        `\tActual: ${result}\n`
 | 
				
			||||||
        );
 | 
					    );
 | 
				
			||||||
    }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function testTzToUtc(t) {
 | 
					function testTzToUtc(t) {
 | 
				
			||||||
    var result = TZ.toUTC.apply(TZ, t.inputs);
 | 
					  var result = TZ.toUTC.apply(TZ, t.inputs);
 | 
				
			||||||
    if (t.result !== result.toISOString()) {
 | 
					  if (t.result !== result.toISOString()) {
 | 
				
			||||||
        console.log(result);
 | 
					    console.log(result);
 | 
				
			||||||
        throw new Error(
 | 
					    throw new Error(
 | 
				
			||||||
            `Invalid TZ to UTC conversion for ${t.desc}:\n` +
 | 
					      `Invalid TZ to UTC conversion for ${t.desc}:\n` +
 | 
				
			||||||
                `\tExpected: ${t.result}\n` +
 | 
					        `\tExpected: ${t.result}\n` +
 | 
				
			||||||
                `\tActual: ${result.toISOString()}\n`
 | 
					        `\tActual: ${result.toISOString()}\n`
 | 
				
			||||||
        );
 | 
					    );
 | 
				
			||||||
    }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// At this real UTC time, what does the timezone translate it to?
 | 
					// At this real UTC time, what does the timezone translate it to?
 | 
				
			||||||
[
 | 
					[
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
    // Start-of-DST Tests
 | 
					  // Start-of-DST Tests
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // [Start]
 | 
					  // [Start]
 | 
				
			||||||
    // What time is '2021-03-14 01:15:59.000 in New York' in UTC? // 2021-03-14 06:15:59.000
 | 
					  // What time is '2021-03-14 01:15:59.000 in New York' in UTC? // 2021-03-14 06:15:59.000
 | 
				
			||||||
    //                                                            // 2021-03-14T01:15:59.000-0500
 | 
					  //                                                            // 2021-03-14T01:15:59.000-0500
 | 
				
			||||||
    // What time is '2021-03-14 02:15:59.000 in New York' in UTC? // 2021-03-14 07:15:59.000
 | 
					  // What time is '2021-03-14 02:15:59.000 in New York' in UTC? // 2021-03-14 07:15:59.000
 | 
				
			||||||
    //                                                            // 2021-03-14T03:15:59.000-0400
 | 
					  //                                                            // 2021-03-14T03:15:59.000-0400
 | 
				
			||||||
    // What time is '2021-03-14 03:15:59.000 in New York' in UTC? // 2021-03-14 07:15:59.000
 | 
					  // What time is '2021-03-14 03:15:59.000 in New York' in UTC? // 2021-03-14 07:15:59.000
 | 
				
			||||||
    //                                                            // 2021-03-14T03:15:59.000-0400
 | 
					  //                                                            // 2021-03-14T03:15:59.000-0400
 | 
				
			||||||
    // What time is '2021-03-14 04:15:59.000 in New York' in UTC? // 2021-03-14 08:15:59.000
 | 
					  // What time is '2021-03-14 04:15:59.000 in New York' in UTC? // 2021-03-14 08:15:59.000
 | 
				
			||||||
    //                                                            // 2021-03-14T04:15:59.000-0400
 | 
					  //                                                            // 2021-03-14T04:15:59.000-0400
 | 
				
			||||||
    // [End]
 | 
					  // [End]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 12:15am NY -0500 => -0400
 | 
					  // 12:15am NY -0500 => -0400
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 12:15am NY EST",
 | 
					    desc: "UTC to 12:15am NY EST",
 | 
				
			||||||
        inputs: ["2021-03-14T05:15:59.000Z", "America/New_York"],
 | 
					    inputs: ["2021-03-14T05:15:59.000Z", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T00:15:59.000-0500",
 | 
					    result: "2021-03-14T00:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 12:15am NY EST (2)",
 | 
					    desc: "UTC to 12:15am NY EST (2)",
 | 
				
			||||||
        inputs: ["2021-03-14T00:15:59.000-0500", "America/New_York"],
 | 
					    inputs: ["2021-03-14T00:15:59.000-0500", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T00:15:59.000-0500",
 | 
					    result: "2021-03-14T00:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    // 1:15am NY (non-DST)
 | 
					  // 1:15am NY (non-DST)
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 1:15am NY EST",
 | 
					    desc: "UTC to 1:15am NY EST",
 | 
				
			||||||
        inputs: ["2021-03-14T06:15:59.000Z", "America/New_York"],
 | 
					    inputs: ["2021-03-14T06:15:59.000Z", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T01:15:59.000-0500",
 | 
					    result: "2021-03-14T01:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 1:15am NY EST (2)",
 | 
					    desc: "UTC to 1:15am NY EST (2)",
 | 
				
			||||||
        inputs: ["2021-03-14T01:15:59.000-0500", "America/New_York"],
 | 
					    inputs: ["2021-03-14T01:15:59.000-0500", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T01:15:59.000-0500",
 | 
					    result: "2021-03-14T01:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // NOTE: Can't 2:15am NY, because it does not exist (skipped by DST)
 | 
					  // NOTE: Can't 2:15am NY, because it does not exist (skipped by DST)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 3:15am NY (DST)
 | 
					  // 3:15am NY (DST)
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 3:15am NY EDT",
 | 
					    desc: "UTC to 3:15am NY EDT",
 | 
				
			||||||
        inputs: ["2021-03-14T07:15:59.000Z", "America/New_York"],
 | 
					    inputs: ["2021-03-14T07:15:59.000Z", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T03:15:59.000-0400",
 | 
					    result: "2021-03-14T03:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 3:15am NY EDT (2)",
 | 
					    desc: "UTC to 3:15am NY EDT (2)",
 | 
				
			||||||
        inputs: ["2021-03-14T03:15:59.000-0400", "America/New_York"],
 | 
					    inputs: ["2021-03-14T03:15:59.000-0400", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T03:15:59.000-0400",
 | 
					    result: "2021-03-14T03:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    // 4:15am NY
 | 
					  // 4:15am NY
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 4:15am NY EDT",
 | 
					    desc: "UTC to 4:15am NY EDT",
 | 
				
			||||||
        inputs: ["2021-03-14T08:15:59.000Z", "America/New_York"],
 | 
					    inputs: ["2021-03-14T08:15:59.000Z", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T04:15:59.000-0400",
 | 
					    result: "2021-03-14T04:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 4:15am NY EDT (2)",
 | 
					    desc: "UTC to 4:15am NY EDT (2)",
 | 
				
			||||||
        inputs: ["2021-03-14T04:15:59.000-0400", "America/New_York"],
 | 
					    inputs: ["2021-03-14T04:15:59.000-0400", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T04:15:59.000-0400",
 | 
					    result: "2021-03-14T04:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
    // End-of-DST Tests
 | 
					  // End-of-DST Tests
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // [Start]
 | 
					  // [Start]
 | 
				
			||||||
    // What time is '2021-11-07 01:15:59.000 in New York' in UTC? // 2021-11-07 05:15:59.000
 | 
					  // What time is '2021-11-07 01:15:59.000 in New York' in UTC? // 2021-11-07 05:15:59.000
 | 
				
			||||||
    //                                                            // 2021-11-07T01:15:59.000-0400
 | 
					  //                                                            // 2021-11-07T01:15:59.000-0400
 | 
				
			||||||
    //                                                            // 2021-11-07 06:15:59.000
 | 
					  //                                                            // 2021-11-07 06:15:59.000
 | 
				
			||||||
    //                                                            // 2021-11-07T01:15:59.000-0500
 | 
					  //                                                            // 2021-11-07T01:15:59.000-0500
 | 
				
			||||||
    // What time is '2021-11-07 02:15:59.000 in New York' in UTC? // 2021-11-07 07:15:59.000
 | 
					  // What time is '2021-11-07 02:15:59.000 in New York' in UTC? // 2021-11-07 07:15:59.000
 | 
				
			||||||
    //                                                            // 2021-11-07T02:15:59.000-0500
 | 
					  //                                                            // 2021-11-07T02:15:59.000-0500
 | 
				
			||||||
    // What time is '2021-11-07 03:15:59.000 in New York' in UTC? // 2021-11-07 08:15:59.000
 | 
					  // What time is '2021-11-07 03:15:59.000 in New York' in UTC? // 2021-11-07 08:15:59.000
 | 
				
			||||||
    // [End]
 | 
					  // [End]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 12:15am NY -0400 => -0500
 | 
					  // 12:15am NY -0400 => -0500
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 2021 Nov 7, 12:15am NY EDT",
 | 
					    desc: "UTC to 2021 Nov 7, 12:15am NY EDT",
 | 
				
			||||||
        inputs: ["2021-11-07T04:15:59.000Z", "America/New_York"],
 | 
					    inputs: ["2021-11-07T04:15:59.000Z", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T00:15:59.000-0400",
 | 
					    result: "2021-11-07T00:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 2021 Nov 7, 12:15am NY EDT (2)",
 | 
					    desc: "UTC to 2021 Nov 7, 12:15am NY EDT (2)",
 | 
				
			||||||
        inputs: ["2021-11-07T00:15:59.000-0400", "America/New_York"],
 | 
					    inputs: ["2021-11-07T00:15:59.000-0400", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T00:15:59.000-0400",
 | 
					    result: "2021-11-07T00:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    // 1:15am NY (DST) -0400
 | 
					  // 1:15am NY (DST) -0400
 | 
				
			||||||
    // NOTE: 1:15am happens TWICE (with different offsets)
 | 
					  // NOTE: 1:15am happens TWICE (with different offsets)
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 2021 Nov 7, 1:15am NY EDT",
 | 
					    desc: "UTC to 2021 Nov 7, 1:15am NY EDT",
 | 
				
			||||||
        inputs: ["2021-11-07T05:15:59.000Z", "America/New_York"],
 | 
					    inputs: ["2021-11-07T05:15:59.000Z", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T01:15:59.000-0400",
 | 
					    result: "2021-11-07T01:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 2021 Nov 7, 1:15am NY EDT (2)",
 | 
					    desc: "UTC to 2021 Nov 7, 1:15am NY EDT (2)",
 | 
				
			||||||
        inputs: ["2021-11-07T01:15:59.000-0400", "America/New_York"],
 | 
					    inputs: ["2021-11-07T01:15:59.000-0400", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T01:15:59.000-0400",
 | 
					    result: "2021-11-07T01:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    // 1:15am NY (non-DST) -0500
 | 
					  // 1:15am NY (non-DST) -0500
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 2021 Nov 7, 1:15am NY EST",
 | 
					    desc: "UTC to 2021 Nov 7, 1:15am NY EST",
 | 
				
			||||||
        inputs: ["2021-11-07T06:15:59.000Z", "America/New_York"],
 | 
					    inputs: ["2021-11-07T06:15:59.000Z", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T01:15:59.000-0500",
 | 
					    result: "2021-11-07T01:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 2021 Nov 7, 1:15am NY EST (2)",
 | 
					    desc: "UTC to 2021 Nov 7, 1:15am NY EST (2)",
 | 
				
			||||||
        inputs: ["2021-11-07T01:15:59.000-0500", "America/New_York"],
 | 
					    inputs: ["2021-11-07T01:15:59.000-0500", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T01:15:59.000-0500",
 | 
					    result: "2021-11-07T01:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    // 2:15am NY -0500
 | 
					  // 2:15am NY -0500
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 2021 Nov 7, 2:15am NY EST",
 | 
					    desc: "UTC to 2021 Nov 7, 2:15am NY EST",
 | 
				
			||||||
        inputs: ["2021-11-07T07:15:59.000Z", "America/New_York"],
 | 
					    inputs: ["2021-11-07T07:15:59.000Z", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T02:15:59.000-0500",
 | 
					    result: "2021-11-07T02:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 2021 Nov 7, 2:15am NY EST (2)",
 | 
					    desc: "UTC to 2021 Nov 7, 2:15am NY EST (2)",
 | 
				
			||||||
        inputs: ["2021-11-07T02:15:59.000-0500", "America/New_York"],
 | 
					    inputs: ["2021-11-07T02:15:59.000-0500", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T02:15:59.000-0500",
 | 
					    result: "2021-11-07T02:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    // 3:15am NY
 | 
					  // 3:15am NY
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 2021 Nov 7, 3:15am NY EST",
 | 
					    desc: "UTC to 2021 Nov 7, 3:15am NY EST",
 | 
				
			||||||
        inputs: ["2021-11-07T08:15:59.000Z", "America/New_York"],
 | 
					    inputs: ["2021-11-07T08:15:59.000Z", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T03:15:59.000-0500",
 | 
					    result: "2021-11-07T03:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to 2021 Nov 7, 3:15am NY EST (2)",
 | 
					    desc: "UTC to 2021 Nov 7, 3:15am NY EST (2)",
 | 
				
			||||||
        inputs: ["2021-11-07T03:15:59.000-0500", "America/New_York"],
 | 
					    inputs: ["2021-11-07T03:15:59.000-0500", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T03:15:59.000-0500",
 | 
					    result: "2021-11-07T03:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
    // Positive Offset Test
 | 
					  // Positive Offset Test
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Colombo +0530 (not DST)
 | 
					  // Colombo +0530 (not DST)
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to Asia/Colombo (1)",
 | 
					    desc: "UTC to Asia/Colombo (1)",
 | 
				
			||||||
        inputs: ["2021-03-14T08:15:59.000Z", "Asia/Colombo"],
 | 
					    inputs: ["2021-03-14T08:15:59.000Z", "Asia/Colombo"],
 | 
				
			||||||
        result: "2021-03-14T13:45:59.000+0530",
 | 
					    result: "2021-03-14T13:45:59.000+0530",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to Asia/Colombo (2)",
 | 
					    desc: "UTC to Asia/Colombo (2)",
 | 
				
			||||||
        inputs: ["2021-03-14T13:45:59.000+0530", "Asia/Colombo"],
 | 
					    inputs: ["2021-03-14T13:45:59.000+0530", "Asia/Colombo"],
 | 
				
			||||||
        result: "2021-03-14T13:45:59.000+0530",
 | 
					    result: "2021-03-14T13:45:59.000+0530",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to Asia/Colombo (3)",
 | 
					    desc: "UTC to Asia/Colombo (3)",
 | 
				
			||||||
        inputs: ["2021-11-07T08:15:59.000Z", "Asia/Colombo"],
 | 
					    inputs: ["2021-11-07T08:15:59.000Z", "Asia/Colombo"],
 | 
				
			||||||
        result: "2021-11-07T13:45:59.000+0530",
 | 
					    result: "2021-11-07T13:45:59.000+0530",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        desc: "UTC to Asia/Colombo (4)",
 | 
					    desc: "UTC to Asia/Colombo (4)",
 | 
				
			||||||
        inputs: ["2021-11-07T13:45:59.000+0530", "Asia/Colombo"],
 | 
					    inputs: ["2021-11-07T13:45:59.000+0530", "Asia/Colombo"],
 | 
				
			||||||
        result: "2021-11-07T13:45:59.000+0530",
 | 
					    result: "2021-11-07T13:45:59.000+0530",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
].forEach(testUtcToTz);
 | 
					].forEach(testUtcToTz);
 | 
				
			||||||
console.info("Pass: UTC to TZ for America/New_York and Asia/Colombo");
 | 
					console.info("Pass: UTC to TZ for America/New_York and Asia/Colombo");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[
 | 
					[
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
    // Start-of-DST Tests
 | 
					  // Start-of-DST Tests
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // [Start]
 | 
					  // [Start]
 | 
				
			||||||
    // What time is '2021-03-14 01:15:59.000 in New York' in UTC? // 2021-03-14 06:15:59.000
 | 
					  // What time is '2021-03-14 01:15:59.000 in New York' in UTC? // 2021-03-14 06:15:59.000
 | 
				
			||||||
    //                                                            // 2021-03-14T01:15:59.000-0500
 | 
					  //                                                            // 2021-03-14T01:15:59.000-0500
 | 
				
			||||||
    // What time is '2021-03-14 02:15:59.000 in New York' in UTC? // 2021-03-14 07:15:59.000
 | 
					  // What time is '2021-03-14 02:15:59.000 in New York' in UTC? // 2021-03-14 07:15:59.000
 | 
				
			||||||
    //                                                            // 2021-03-14T03:15:59.000-0400
 | 
					  //                                                            // 2021-03-14T03:15:59.000-0400
 | 
				
			||||||
    // What time is '2021-03-14 03:15:59.000 in New York' in UTC? // 2021-03-14 07:15:59.000
 | 
					  // What time is '2021-03-14 03:15:59.000 in New York' in UTC? // 2021-03-14 07:15:59.000
 | 
				
			||||||
    //                                                            // 2021-03-14T03:15:59.000-0400
 | 
					  //                                                            // 2021-03-14T03:15:59.000-0400
 | 
				
			||||||
    // What time is '2021-03-14 04:15:59.000 in New York' in UTC? // 2021-03-14 08:15:59.000
 | 
					  // What time is '2021-03-14 04:15:59.000 in New York' in UTC? // 2021-03-14 08:15:59.000
 | 
				
			||||||
    //                                                            // 2021-03-14T04:15:59.000-0400
 | 
					  //                                                            // 2021-03-14T04:15:59.000-0400
 | 
				
			||||||
    // [End]
 | 
					  // [End]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 12:15am NY -0500 => -0400
 | 
					  // 12:15am NY -0500 => -0400
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // 2021-03-14T05:15:59.000Z
 | 
					    // 2021-03-14T05:15:59.000Z
 | 
				
			||||||
        desc: "2021 Mar 14, 12:15am NY EST to UTC",
 | 
					    desc: "2021 Mar 14, 12:15am NY EST to UTC",
 | 
				
			||||||
        inputs: ["2021-03-14 00:15:59.000", "America/New_York"],
 | 
					    inputs: ["2021-03-14 00:15:59.000", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T00:15:59.000-0500",
 | 
					    result: "2021-03-14T00:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    // 1:15am NY (non-DST)
 | 
					  // 1:15am NY (non-DST)
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // 2021-03-14T06:15:59.000Z
 | 
					    // 2021-03-14T06:15:59.000Z
 | 
				
			||||||
        desc: "2021 Mar 14, 1:15am NY EST to UTC",
 | 
					    desc: "2021 Mar 14, 1:15am NY EST to UTC",
 | 
				
			||||||
        inputs: ["2021-03-14 01:15:59.000", "America/New_York"],
 | 
					    inputs: ["2021-03-14 01:15:59.000", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T01:15:59.000-0500",
 | 
					    result: "2021-03-14T01:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // NOTE: Can't 2:15am NY, because it does not exist (skipped by DST)
 | 
					  // NOTE: Can't 2:15am NY, because it does not exist (skipped by DST)
 | 
				
			||||||
    // This test is here to document the "undefined" behavior
 | 
					  // This test is here to document the "undefined" behavior
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // Both 2021-03-14T06:15:59.000Z and 2021-03-14T07:15:59.000Z
 | 
					    // Both 2021-03-14T06:15:59.000Z and 2021-03-14T07:15:59.000Z
 | 
				
			||||||
        // would be reasonable substitutions, I think
 | 
					    // would be reasonable substitutions, I think
 | 
				
			||||||
        desc: "2021 Mar 14, 2:15am NY ExT to UTC",
 | 
					    desc: "2021 Mar 14, 2:15am NY ExT to UTC",
 | 
				
			||||||
        inputs: ["2021-03-14 02:15:59.000", "America/New_York"],
 | 
					    inputs: ["2021-03-14 02:15:59.000", "America/New_York"],
 | 
				
			||||||
        //result: "2021-03-14T01:15:59.000-0500", // 2021-03-14T06:15:59.000Z
 | 
					    //result: "2021-03-14T01:15:59.000-0500", // 2021-03-14T06:15:59.000Z
 | 
				
			||||||
        result: "2021-03-14T02:15:59.000-0400", // 2021-03-14T06:15:59.000Z
 | 
					    result: "2021-03-14T02:15:59.000-0400", // 2021-03-14T06:15:59.000Z
 | 
				
			||||||
        //result: "2021-03-14T02:15:59.000-0500", // 2021-03-14T07:15:59.000Z
 | 
					    //result: "2021-03-14T02:15:59.000-0500", // 2021-03-14T07:15:59.000Z
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 3:15am NY (DST)
 | 
					  // 3:15am NY (DST)
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // 2021-03-14T07:15:59.000Z
 | 
					    // 2021-03-14T07:15:59.000Z
 | 
				
			||||||
        desc: "2021 Mar 14, 3:15am NY EDT to UTC",
 | 
					    desc: "2021 Mar 14, 3:15am NY EDT to UTC",
 | 
				
			||||||
        inputs: ["2021-03-14 03:15:59.000", "America/New_York"],
 | 
					    inputs: ["2021-03-14 03:15:59.000", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T03:15:59.000-0400",
 | 
					    result: "2021-03-14T03:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    // 4:15am NY
 | 
					  // 4:15am NY
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // 2021-03-14T08:15:59.000Z
 | 
					    // 2021-03-14T08:15:59.000Z
 | 
				
			||||||
        desc: "2021 Mar 14, 4:15am NY EDT to UTC",
 | 
					    desc: "2021 Mar 14, 4:15am NY EDT to UTC",
 | 
				
			||||||
        inputs: ["2021-03-14 04:15:59.000", "America/New_York"],
 | 
					    inputs: ["2021-03-14 04:15:59.000", "America/New_York"],
 | 
				
			||||||
        result: "2021-03-14T04:15:59.000-0400",
 | 
					    result: "2021-03-14T04:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
    // End-of-DST Tests
 | 
					  // End-of-DST Tests
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // [Start]
 | 
					  // [Start]
 | 
				
			||||||
    // What time is '2021-11-07 01:15:59.000 in New York' in UTC? // 2021-11-07 05:15:59.000
 | 
					  // What time is '2021-11-07 01:15:59.000 in New York' in UTC? // 2021-11-07 05:15:59.000
 | 
				
			||||||
    //                                                            // 2021-11-07T01:15:59.000-0400
 | 
					  //                                                            // 2021-11-07T01:15:59.000-0400
 | 
				
			||||||
    //                                                            // 2021-11-07 06:15:59.000
 | 
					  //                                                            // 2021-11-07 06:15:59.000
 | 
				
			||||||
    //                                                            // 2021-11-07T01:15:59.000-0500
 | 
					  //                                                            // 2021-11-07T01:15:59.000-0500
 | 
				
			||||||
    // What time is '2021-11-07 02:15:59.000 in New York' in UTC? // 2021-11-07 07:15:59.000
 | 
					  // What time is '2021-11-07 02:15:59.000 in New York' in UTC? // 2021-11-07 07:15:59.000
 | 
				
			||||||
    //                                                            // 2021-11-07T02:15:59.000-0500
 | 
					  //                                                            // 2021-11-07T02:15:59.000-0500
 | 
				
			||||||
    // What time is '2021-11-07 03:15:59.000 in New York' in UTC? // 2021-11-07 08:15:59.000
 | 
					  // What time is '2021-11-07 03:15:59.000 in New York' in UTC? // 2021-11-07 08:15:59.000
 | 
				
			||||||
    // [End]
 | 
					  // [End]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 12:15am NY -0400 => -0500
 | 
					  // 12:15am NY -0400 => -0500
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // 2021-11-07T04:15:59.000Z
 | 
					    // 2021-11-07T04:15:59.000Z
 | 
				
			||||||
        desc: "2021 Nov 7, 12:15am NY EDT to UTC",
 | 
					    desc: "2021 Nov 7, 12:15am NY EDT to UTC",
 | 
				
			||||||
        inputs: ["2021-11-07 00:15:59.000", "America/New_York"],
 | 
					    inputs: ["2021-11-07 00:15:59.000", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T00:15:59.000-0400",
 | 
					    result: "2021-11-07T00:15:59.000-0400",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 1:15am NY (DST) -0400
 | 
					  // 1:15am NY (DST) -0400
 | 
				
			||||||
    // NOTE: 1:15am happens TWICE (with different offsets), so we skip one
 | 
					  // NOTE: 1:15am happens TWICE (with different offsets), so we skip one
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // ==> 2021-11-07T05:15:59.000Z
 | 
					    // ==> 2021-11-07T05:15:59.000Z
 | 
				
			||||||
        // [Skip] 2021-11-07T06:15:59.000Z
 | 
					    // [Skip] 2021-11-07T06:15:59.000Z
 | 
				
			||||||
        desc: "2021 Nov 7, 1:15am NY ExT to UTC",
 | 
					    desc: "2021 Nov 7, 1:15am NY ExT to UTC",
 | 
				
			||||||
        inputs: ["2021-11-07 01:15:59.000", "America/New_York"],
 | 
					    inputs: ["2021-11-07 01:15:59.000", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T01:15:59.000-0400", // 2021-11-07T05:15:59.000Z
 | 
					    result: "2021-11-07T01:15:59.000-0400", // 2021-11-07T05:15:59.000Z
 | 
				
			||||||
        //result: "2021-11-07T01:15:59.000-0500", // 2021-11-07T06:15:59.000Z
 | 
					    //result: "2021-11-07T01:15:59.000-0500", // 2021-11-07T06:15:59.000Z
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 2:15am NY -0500
 | 
					  // 2:15am NY -0500
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // 2021-11-07T07:15:59.000Z
 | 
					    // 2021-11-07T07:15:59.000Z
 | 
				
			||||||
        desc: "2021 Nov 7, 2:15am NY EST to UTC",
 | 
					    desc: "2021 Nov 7, 2:15am NY EST to UTC",
 | 
				
			||||||
        inputs: ["2021-11-07 02:15:59.000", "America/New_York"],
 | 
					    inputs: ["2021-11-07 02:15:59.000", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T02:15:59.000-0500",
 | 
					    result: "2021-11-07T02:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    // 3:15am NY
 | 
					  // 3:15am NY
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // 2021-11-07T08:15:59.000Z
 | 
					    // 2021-11-07T08:15:59.000Z
 | 
				
			||||||
        desc: "2021 Nov 7, 3:15am NY EST to UTC",
 | 
					    desc: "2021 Nov 7, 3:15am NY EST to UTC",
 | 
				
			||||||
        inputs: ["2021-11-07 03:15:59.000", "America/New_York"],
 | 
					    inputs: ["2021-11-07 03:15:59.000", "America/New_York"],
 | 
				
			||||||
        result: "2021-11-07T03:15:59.000-0500",
 | 
					    result: "2021-11-07T03:15:59.000-0500",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
    // Positive Offset Test
 | 
					  // Positive Offset Test
 | 
				
			||||||
    //
 | 
					  //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Colombo +0530 (not DST)
 | 
					  // Colombo +0530 (not DST)
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // 2021-03-14T08:15:59.000Z
 | 
					    // 2021-03-14T08:15:59.000Z
 | 
				
			||||||
        desc: "Asia/Colombo to UTC (1)",
 | 
					    desc: "Asia/Colombo to UTC (1)",
 | 
				
			||||||
        inputs: ["2021-03-14 13:45:59.000", "Asia/Colombo"],
 | 
					    inputs: ["2021-03-14 13:45:59.000", "Asia/Colombo"],
 | 
				
			||||||
        result: "2021-03-14T13:45:59.000+0530",
 | 
					    result: "2021-03-14T13:45:59.000+0530",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
    {
 | 
					  {
 | 
				
			||||||
        // 2021-03-14T08:15:59.000Z
 | 
					    // 2021-03-14T08:15:59.000Z
 | 
				
			||||||
        desc: "Asia/Colombo to UTC (2)",
 | 
					    desc: "Asia/Colombo to UTC (2)",
 | 
				
			||||||
        inputs: ["2021-11-07 13:45:59.000", "Asia/Colombo"],
 | 
					    inputs: ["2021-11-07 13:45:59.000", "Asia/Colombo"],
 | 
				
			||||||
        result: "2021-11-07T13:45:59.000+0530",
 | 
					    result: "2021-11-07T13:45:59.000+0530",
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
].forEach(testTzToUtc);
 | 
					].forEach(testTzToUtc);
 | 
				
			||||||
console.info("Pass: TZ to UTC for America/New_York and Asia/Colombo");
 | 
					console.info("Pass: TZ to UTC for America/New_York and Asia/Colombo");
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										347
									
								
								xtz.js
									
									
									
									
									
								
							
							
						
						
									
										347
									
								
								xtz.js
									
									
									
									
									
								
							@ -1,182 +1,179 @@
 | 
				
			|||||||
var XTZ;
 | 
					var XTZ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(function () {
 | 
					(function () {
 | 
				
			||||||
    "use strict";
 | 
					  "use strict";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function toTimeZone(date, timeZone) {
 | 
					  function toTimeZone(date, timeZone) {
 | 
				
			||||||
        // ISO string or existing date object
 | 
					    // ISO string or existing date object
 | 
				
			||||||
        date = new Date(date);
 | 
					    date = new Date(date);
 | 
				
			||||||
        var options = {
 | 
					    var options = {
 | 
				
			||||||
            timeZone: timeZone,
 | 
					      timeZone: timeZone,
 | 
				
			||||||
            year: "numeric",
 | 
					      year: "numeric",
 | 
				
			||||||
            month: "numeric",
 | 
					      month: "numeric",
 | 
				
			||||||
            day: "numeric",
 | 
					      day: "numeric",
 | 
				
			||||||
            hour12: false,
 | 
					      hour12: false,
 | 
				
			||||||
            hour: "numeric",
 | 
					      hour: "numeric",
 | 
				
			||||||
            minute: "numeric",
 | 
					      minute: "numeric",
 | 
				
			||||||
            second: "numeric",
 | 
					      second: "numeric",
 | 
				
			||||||
            fractionalSecondDigits: 3,
 | 
					      fractionalSecondDigits: 3,
 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var tzOptions = Object.assign({ timeZoneName: "long" }, options);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Every country uses the same year and months, right?
 | 
					 | 
				
			||||||
        var formater = new Intl.DateTimeFormat("default", tzOptions);
 | 
					 | 
				
			||||||
        var parts = formater.formatToParts(date);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var whole = {};
 | 
					 | 
				
			||||||
        parts.forEach(function (part) {
 | 
					 | 
				
			||||||
            var val = part.value;
 | 
					 | 
				
			||||||
            switch (part.type) {
 | 
					 | 
				
			||||||
                case "literal":
 | 
					 | 
				
			||||||
                    // ignore separators and whitespace characters
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                case "timeZoneName":
 | 
					 | 
				
			||||||
                    // keep as is - it's a string
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                case "month":
 | 
					 | 
				
			||||||
                    // months are 0-indexed for new Date()
 | 
					 | 
				
			||||||
                    val = parseInt(val, 10) - 1;
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                case "hour":
 | 
					 | 
				
			||||||
                    // because sometimes 24 is used instead of 0, make 24 0
 | 
					 | 
				
			||||||
                    val = parseInt(val, 10) % 24;
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                case "fractionalSecond":
 | 
					 | 
				
			||||||
                    // fractionalSecond is a dumb name - should be millisecond
 | 
					 | 
				
			||||||
                    whole.millisecond = parseInt(val, 10);
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                default:
 | 
					 | 
				
			||||||
                    val = parseInt(val, 10);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            // whole.month = 0;
 | 
					 | 
				
			||||||
            whole[part.type] = val;
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        whole.timeZone = timeZone;
 | 
					 | 
				
			||||||
        whole.offset = getOffset(date, whole);
 | 
					 | 
				
			||||||
        whole.toISOString = _toOffsetISOString;
 | 
					 | 
				
			||||||
        return whole;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function toTimeZoneISOString(date, timeZone) {
 | 
					 | 
				
			||||||
        var whole = toTimeZone(date, timeZone);
 | 
					 | 
				
			||||||
        return toOffsetISOString(whole);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function _toOffsetISOString() {
 | 
					 | 
				
			||||||
        return toOffsetISOString(this);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function getOffset(utcDate, tzD2) {
 | 
					 | 
				
			||||||
        var tzDate = new Date(toOffsetISOString(tzD2));
 | 
					 | 
				
			||||||
        var diff =
 | 
					 | 
				
			||||||
            Math.round(tzDate.valueOf() - utcDate.valueOf()) / (60 * 1000);
 | 
					 | 
				
			||||||
        return diff;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function p2(x) {
 | 
					 | 
				
			||||||
        return String(x).padStart(2, "0");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function p3(x) {
 | 
					 | 
				
			||||||
        return String(x).padStart(3, "0");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function formatOffset(minutes) {
 | 
					 | 
				
			||||||
        if (!minutes) {
 | 
					 | 
				
			||||||
            return "Z";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var h = Math.floor(Math.abs(minutes) / 60);
 | 
					 | 
				
			||||||
        var m = Math.abs(minutes) % 60;
 | 
					 | 
				
			||||||
        var offset = "";
 | 
					 | 
				
			||||||
        if (minutes > 0) {
 | 
					 | 
				
			||||||
            offset = "+";
 | 
					 | 
				
			||||||
        } else if (minutes < 0) {
 | 
					 | 
				
			||||||
            offset = "-";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // +0500, -0730
 | 
					 | 
				
			||||||
        return (
 | 
					 | 
				
			||||||
            offset +
 | 
					 | 
				
			||||||
            h.toString().padStart(2, "0") +
 | 
					 | 
				
			||||||
            m.toString().padStart(2, "0")
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function toOffsetISOString(d) {
 | 
					 | 
				
			||||||
        var offset = formatOffset(d.offset);
 | 
					 | 
				
			||||||
        return (
 | 
					 | 
				
			||||||
            `${d.year}-${p2(d.month + 1)}-${p2(d.day)}` +
 | 
					 | 
				
			||||||
            `T${p2(d.hour)}:${p2(d.minute)}:${p2(d.second)}.${p3(
 | 
					 | 
				
			||||||
                d.millisecond
 | 
					 | 
				
			||||||
            )}${offset}`
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function toUTC(dt, tz) {
 | 
					 | 
				
			||||||
        if ("string" === typeof dt) {
 | 
					 | 
				
			||||||
            // Either of these formats should work:
 | 
					 | 
				
			||||||
            // 2021-03-14 01:15:59
 | 
					 | 
				
			||||||
            // 2021-03-14T01:15:59Z
 | 
					 | 
				
			||||||
            dt = dt
 | 
					 | 
				
			||||||
                .replace("T", " ")
 | 
					 | 
				
			||||||
                .replace("Z", "")
 | 
					 | 
				
			||||||
                .replace(" ", "T")
 | 
					 | 
				
			||||||
                .replace(/$/, "Z");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        var utcDate = new Date(dt);
 | 
					 | 
				
			||||||
        var tzD2 = toTimeZone(utcDate, tz);
 | 
					 | 
				
			||||||
        var offset = tzD2.offset;
 | 
					 | 
				
			||||||
        tzD2.offset = "";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var deltaDate = new Date(utcDate);
 | 
					 | 
				
			||||||
        deltaDate.setUTCMinutes(deltaDate.getUTCMinutes() - offset);
 | 
					 | 
				
			||||||
        var tzD3 = toTimeZone(deltaDate, tz);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (
 | 
					 | 
				
			||||||
            tzD3.hour === utcDate.getUTCHours() &&
 | 
					 | 
				
			||||||
            tzD3.minute === utcDate.getUTCMinutes()
 | 
					 | 
				
			||||||
        ) {
 | 
					 | 
				
			||||||
            return tzD3;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var diff = tzD3.offset - offset;
 | 
					 | 
				
			||||||
        var h = Math.floor(Math.abs(diff) / 60);
 | 
					 | 
				
			||||||
        var m = Math.abs(diff) % 60;
 | 
					 | 
				
			||||||
        var sign = Math.abs(diff) / diff;
 | 
					 | 
				
			||||||
        tzD3.hour -= h * sign;
 | 
					 | 
				
			||||||
        tzD3.minute -= m * sign;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return tzD3;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function toUTCISOString(date, timeZone) {
 | 
					 | 
				
			||||||
        var whole = toUTC(date, timeZone);
 | 
					 | 
				
			||||||
        return toOffsetISOString(whole);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    XTZ = {
 | 
					 | 
				
			||||||
        // bespoke date =>
 | 
					 | 
				
			||||||
        // 2021-11-07T3:15:59-0500
 | 
					 | 
				
			||||||
        toOffsetISOString: toOffsetISOString,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // -240 => -0400
 | 
					 | 
				
			||||||
        formatOffset: formatOffset,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // [ "2021-11-07T08:15:59Z", "America/New_York" ]
 | 
					 | 
				
			||||||
        // => "2021-11-07T03:15:59-0500" // 2021-11-07 03:15:59
 | 
					 | 
				
			||||||
        toTimeZone: toTimeZone,
 | 
					 | 
				
			||||||
        toTimeZoneISOString: toTimeZoneISOString,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // [ "2021-11-07 03:15:59", "America/New_York" ]
 | 
					 | 
				
			||||||
        // => "2021-11-07T03:15:59-0500" // 2021-11-07T08:15:59Z
 | 
					 | 
				
			||||||
        toUTC: toUTC,
 | 
					 | 
				
			||||||
        toUTCISOString: toUTCISOString,
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ("undefined" != typeof module && module.exports) {
 | 
					    var tzOptions = Object.assign({ timeZoneName: "long" }, options);
 | 
				
			||||||
        module.exports = XTZ;
 | 
					
 | 
				
			||||||
 | 
					    // Every country uses the same year and months, right?
 | 
				
			||||||
 | 
					    var formater = new Intl.DateTimeFormat("default", tzOptions);
 | 
				
			||||||
 | 
					    var parts = formater.formatToParts(date);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var whole = {};
 | 
				
			||||||
 | 
					    parts.forEach(function (part) {
 | 
				
			||||||
 | 
					      var val = part.value;
 | 
				
			||||||
 | 
					      switch (part.type) {
 | 
				
			||||||
 | 
					        case "literal":
 | 
				
			||||||
 | 
					          // ignore separators and whitespace characters
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					        case "timeZoneName":
 | 
				
			||||||
 | 
					          // keep as is - it's a string
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case "month":
 | 
				
			||||||
 | 
					          // months are 0-indexed for new Date()
 | 
				
			||||||
 | 
					          val = parseInt(val, 10) - 1;
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case "hour":
 | 
				
			||||||
 | 
					          // because sometimes 24 is used instead of 0, make 24 0
 | 
				
			||||||
 | 
					          val = parseInt(val, 10) % 24;
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case "fractionalSecond":
 | 
				
			||||||
 | 
					          // fractionalSecond is a dumb name - should be millisecond
 | 
				
			||||||
 | 
					          whole.millisecond = parseInt(val, 10);
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					          val = parseInt(val, 10);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      // whole.month = 0;
 | 
				
			||||||
 | 
					      whole[part.type] = val;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    whole.timeZone = timeZone;
 | 
				
			||||||
 | 
					    whole.offset = getOffset(date, whole);
 | 
				
			||||||
 | 
					    whole.toISOString = _toOffsetISOString;
 | 
				
			||||||
 | 
					    return whole;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function toTimeZoneISOString(date, timeZone) {
 | 
				
			||||||
 | 
					    var whole = toTimeZone(date, timeZone);
 | 
				
			||||||
 | 
					    return toOffsetISOString(whole);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function _toOffsetISOString() {
 | 
				
			||||||
 | 
					    return toOffsetISOString(this);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getOffset(utcDate, tzD2) {
 | 
				
			||||||
 | 
					    var tzDate = new Date(toOffsetISOString(tzD2));
 | 
				
			||||||
 | 
					    var diff = Math.round(tzDate.valueOf() - utcDate.valueOf()) / (60 * 1000);
 | 
				
			||||||
 | 
					    return diff;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function p2(x) {
 | 
				
			||||||
 | 
					    return String(x).padStart(2, "0");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function p3(x) {
 | 
				
			||||||
 | 
					    return String(x).padStart(3, "0");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function formatOffset(minutes) {
 | 
				
			||||||
 | 
					    if (!minutes) {
 | 
				
			||||||
 | 
					      return "Z";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}());
 | 
					
 | 
				
			||||||
 | 
					    var h = Math.floor(Math.abs(minutes) / 60);
 | 
				
			||||||
 | 
					    var m = Math.abs(minutes) % 60;
 | 
				
			||||||
 | 
					    var offset = "";
 | 
				
			||||||
 | 
					    if (minutes > 0) {
 | 
				
			||||||
 | 
					      offset = "+";
 | 
				
			||||||
 | 
					    } else if (minutes < 0) {
 | 
				
			||||||
 | 
					      offset = "-";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // +0500, -0730
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      offset + h.toString().padStart(2, "0") + m.toString().padStart(2, "0")
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function toOffsetISOString(d) {
 | 
				
			||||||
 | 
					    var offset = formatOffset(d.offset);
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      `${d.year}-${p2(d.month + 1)}-${p2(d.day)}` +
 | 
				
			||||||
 | 
					      `T${p2(d.hour)}:${p2(d.minute)}:${p2(d.second)}.${p3(
 | 
				
			||||||
 | 
					        d.millisecond
 | 
				
			||||||
 | 
					      )}${offset}`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function toUTC(dt, tz) {
 | 
				
			||||||
 | 
					    if ("string" === typeof dt) {
 | 
				
			||||||
 | 
					      // Either of these formats should work:
 | 
				
			||||||
 | 
					      // 2021-03-14 01:15:59
 | 
				
			||||||
 | 
					      // 2021-03-14T01:15:59Z
 | 
				
			||||||
 | 
					      dt = dt
 | 
				
			||||||
 | 
					        .replace("T", " ")
 | 
				
			||||||
 | 
					        .replace("Z", "")
 | 
				
			||||||
 | 
					        .replace(" ", "T")
 | 
				
			||||||
 | 
					        .replace(/$/, "Z");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    var utcDate = new Date(dt);
 | 
				
			||||||
 | 
					    var tzD2 = toTimeZone(utcDate, tz);
 | 
				
			||||||
 | 
					    var offset = tzD2.offset;
 | 
				
			||||||
 | 
					    tzD2.offset = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var deltaDate = new Date(utcDate);
 | 
				
			||||||
 | 
					    deltaDate.setUTCMinutes(deltaDate.getUTCMinutes() - offset);
 | 
				
			||||||
 | 
					    var tzD3 = toTimeZone(deltaDate, tz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (
 | 
				
			||||||
 | 
					      tzD3.hour === utcDate.getUTCHours() &&
 | 
				
			||||||
 | 
					      tzD3.minute === utcDate.getUTCMinutes()
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					      return tzD3;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var diff = tzD3.offset - offset;
 | 
				
			||||||
 | 
					    var h = Math.floor(Math.abs(diff) / 60);
 | 
				
			||||||
 | 
					    var m = Math.abs(diff) % 60;
 | 
				
			||||||
 | 
					    var sign = Math.abs(diff) / diff;
 | 
				
			||||||
 | 
					    tzD3.hour -= h * sign;
 | 
				
			||||||
 | 
					    tzD3.minute -= m * sign;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return tzD3;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function toUTCISOString(date, timeZone) {
 | 
				
			||||||
 | 
					    var whole = toUTC(date, timeZone);
 | 
				
			||||||
 | 
					    return toOffsetISOString(whole);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  XTZ = {
 | 
				
			||||||
 | 
					    // bespoke date =>
 | 
				
			||||||
 | 
					    // 2021-11-07T3:15:59-0500
 | 
				
			||||||
 | 
					    toOffsetISOString: toOffsetISOString,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // -240 => -0400
 | 
				
			||||||
 | 
					    formatOffset: formatOffset,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // [ "2021-11-07T08:15:59Z", "America/New_York" ]
 | 
				
			||||||
 | 
					    // => "2021-11-07T03:15:59-0500" // 2021-11-07 03:15:59
 | 
				
			||||||
 | 
					    toTimeZone: toTimeZone,
 | 
				
			||||||
 | 
					    toTimeZoneISOString: toTimeZoneISOString,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // [ "2021-11-07 03:15:59", "America/New_York" ]
 | 
				
			||||||
 | 
					    // => "2021-11-07T03:15:59-0500" // 2021-11-07T08:15:59Z
 | 
				
			||||||
 | 
					    toUTC: toUTC,
 | 
				
			||||||
 | 
					    toUTCISOString: toUTCISOString,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ("undefined" != typeof module && module.exports) {
 | 
				
			||||||
 | 
					    module.exports = XTZ;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					})();
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user