1

I am looking for a way to convert a Javascript date object in local time assuming a timezone like America/New_York:

2019-01-04T00:00:00.000Z

I'd like to convert this to a date object in UTC.

2019-01-04T05:00:00.000Z

const timezone = 'America/New_York';
const localMidnight = new Date(Date.UTC(2019, 0, 4)) // 2019-01-04T00:00:00.000Z
moment.tz(localMidnight, timezone).utc().toDate()

Here this is still returning the same as the input 2019-01-04T00:00:00.000Z.

> m(localMidnight, 'America/New_York').tz('utc').toDate()
2019-01-04T00:00:00.000Z
> m(localMidnight, 'America/New_York').tz('UTC').toDate()
2019-01-04T00:00:00.000Z
> m(localMidnight, 'America/New_York').utc().toDate()
2019-01-04T00:00:00.000Z
ThomasReggi
  • 55,053
  • 85
  • 237
  • 424
  • Is this what you're trying to do? https://stackoverflow.com/questions/10087819/convert-date-to-another-timezone-in-javascript – Pietro Nadalini Jan 04 '19 at 20:28
  • Updated, I tried this is not working as well. – ThomasReggi Jan 04 '19 at 20:30
  • try `new Date(2019,0,1).toGMTString()` – ic3b3rg Jan 04 '19 at 20:35
  • or `new Date(2019,0,1).toISOString()` to get the format you posted – ic3b3rg Jan 04 '19 at 20:38
  • 3
    This question is confusing :-) A date string with `Z` at the end is already UTC, not local. Do you have an actual date object or a string? Why would you use `Date.UTC` to get a non-UTC date? An actual date object is already aware of its UTC time, use `.toISOString` to see it. – str Jan 04 '19 at 20:43
  • Are you really asking "I want to generate a Date for midnight in a particular timezone, then generate an ISO 8601 formatted timestamp using UTC"? – RobG Jan 05 '19 at 04:20

3 Answers3

0

It seems like the problem was with the format of the date you created, in this example you can see that .toISOString() adds a Z at the end, and for the moment.tz method to work you need to remove that letter from the format.

Here's an example creating a new date in 'America/New_York' and changing the time zone to UTC

const timezone = 'America/New_York';
const localMidnight = new Date(2019, 01, 04);

console.log("Original time:")
console.log(localMidnight.toISOString());

console.log("Converted to UTC:");
console.log(moment.tz(localMidnight.toISOString().slice(0, -1), timezone).utc().format());   
<script type="text/javascript" src="http://momentjs.com/downloads/moment.min.js"></script>
<script type="text/javascript" src="http://momentjs.com/downloads/moment-timezone-with-data.min.js"></script>
Pietro Nadalini
  • 1,722
  • 3
  • 13
  • 32
  • I don't know what you think this is doing, but it seems wrong. I get "Original time: 2019-02-03T14:00:00.000Z" which is correct, then "Converted to UTC: 2019-02-03T19:00:00Z" which is wrong because the first string is already UTC. The second is just shifted 5 hours. The equivalent time in New York would be 2019-02-03T09:00:00.000-05:00. Or midnight at the start of 2019-01-04 in New York is 2019-01-04T05:00:00Z. – RobG Jan 05 '19 at 04:44
0

To achieve expected result, use below option

Syntax - moment(date).tz(timezone).utc().format()

For format-YYYY-MM-DDTHH:mm:ss.SSSZ use toISOString() instead of format()

const timezone = 'America/New_York';
const localMidnight = new Date(Date.UTC(2019, 0, 4))
console.log("newTime in utc",  moment(localMidnight).tz(timezone).utc().format())
console.log("newTime",  moment(localMidnight).tz(timezone).utc().toISOString())
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.js"></script>

codepen - https://codepen.io/nagasai/pen/gZegqd?editors=1010

Naga Sai A
  • 10,771
  • 1
  • 21
  • 40
  • I get "*Error: Moment Timezone has no data for America/New_York.*". Your *localMidnight* is not local midnight unless the host is set to UTC, `new Date(Date.UTC(2019, 0, 4))` creates a Date for 2019-01-04T00:00:00Z. – RobG Jan 05 '19 at 04:38
  • @RobG, fixed that error which was due to missing moment-timezone-with-data js file – Naga Sai A Jan 07 '19 at 15:36
  • You can remove *moment-timezone.min.js*. The code still does nothing useful, `new Date(Date.UTC(2019, 0, 4))` creates a date for midnight UTC, not local. Using moment.js's *.utc* method means all calculations and methods use UTC and the default output format is ISO 8601. You'll get exactly the same result without moment.js and using *toISOString* instead. – RobG Jan 07 '19 at 20:29
0

What I think you want is to create a date based on a date and time in a particular timezone, then create an ISO 8601 timestamp for UTC.

Comments in the following should be sufficient, but ask if you need more help.

// Create a moment for midnight in America/New_York
var newYork = moment.tz("2019-01-04 00:00", "America/New_York");

// Create an ISO 8601 timestamp UTC
console.log(newYork.utc().format()); // 2019-01-04T05:00:00Z
<script type="text/javascript" src="http://momentjs.com/downloads/moment.min.js"></script>
<script type="text/javascript" src="http://momentjs.com/downloads/moment-timezone-with-data.min.js"></script>

Note that calling utc triggers UTC mode, which has side effects in addition to formatting as ISO 8601 and UTC.

RobG
  • 142,382
  • 31
  • 172
  • 209