Q:

How to change timezone without changing date value

My scenario is this:
I have a datepicker that accepts input from the user and it assumes the date/time picked is local time.  I can't seem to change this behavior.  The user should actually be picking the date/time in Europe/London time as they are booking a service in London at that time. 
Lets say they are booking a flight from London at 5AM.
So I have this date the user picked (from New Zealand):
2019-08-01T05:00:00+12:00 (NZ time)

I need to change this to:
2019-08-01T05:00:00+01:00 (Europe/London time)

After that I am sending to server and storing as UTC.
I am using momentjs if that helps.
Edit:
Latest attempt:
I just need to figure out how to get the timezone offset from the exact time the user entered so I have daylight savings covered.
e.g. below I am getting the UK offset for the day before so may have DST issues
const moment = require('moment-timezone');

const nzd = '2019-08-01T05:00:00+12:00'; // This is the date my user entered via the datepicker

const ukTempString = moment(new Date(nzd.slice(0, -6))).tz('Europe/London').format('YYYY-MM-DDTHH:mm:ssZ'); // 2019-07-31T18:00:00+01:00
const ukOffset = ukTempString.substr(ukTempString.length - 6); // +01:00

const ukString = nzd.slice(0, -6) + ukOffset; // 2019-08-01T05:00:00+01:00
const ukDate = new Date(ukString);  // I can then this to the backend

Edit:
Current solution:
No DST in UK example:
 let nzd = moment('2019-10-27T05:00:00+13:00'); // This is the date my user entered via the datepicker
 let nzString = nzd.format('YYYY-MM-DDTHH:mm:ssZ');
 let ukd = moment().tz('Europe/London');

 ukd.set(nzd.toObject());
 console.log(ukd.format('YYYY-MM-DDTHH:mm:ssZ')); // 2019-10-27T05:00:00+00:00

 let ukDate = new Date(ukd.format('YYYY-MM-DDTHH:mm:ssZ')); // I can then this to the backend
 console.log(ukDate.toUTCString()); // Sun, 27 Oct 2019 05:00:00 GMT

Has DST in UK example (same code):
 nzd = moment('2019-10-27T00:30:00+13:00'); // This is the date my user entered via the datepicker
 nzString = nzd.format('YYYY-MM-DDTHH:mm:ssZ');
 ukd = moment().tz('Europe/London');
 ukd.set(nzd.toObject());

 console.log(ukd.format('YYYY-MM-DDTHH:mm:ssZ')); // 2019-10-27T00:30:00+01:00

 ukDate = new Date(ukd.format('YYYY-MM-DDTHH:mm:ssZ')); // I can then this to the backend
 console.log(ukDate.toUTCString()); // Sat, 26 Oct 2019 23:30:00 GMT

A:

If you are not doing any date time conversion (like in your example), and just changing the time zone offset in the end of the string, just do a string operation, like this:

var nzd = '2019-08-01T05:00:00+12:00'
var ukd = nzd.slice(0, -6) + '+01:00'
console.log(ukd) // outputs 2019-08-01T05:00:00+01:00

If you need to convert the full date and time, as you are using momentjs, you could use moment-timezone instead: https://momentjs.com/timezone/ . Then the following code do the trick:

const moment = require('moment-timezone')
var nz = moment('2019-08-01T05:00:00+12:00')
var uk = nz.tz('Europe/London').format()
console.log(uk) // outputs 2019-07-31T18:00:00+01:00

If you want to get the time zone offset string, also use moment-timezone:

let ukd = "2019-10-27T01:59:00".split('T')
let finalDate = moment.tz(ukd[0] + "T" + ukd[1], "YYYY-MM-DDTHH:mm:ss", true, "Europe/London").tz('Europe/London').format('Z');
console.log(finalDate) // last minute still in DST, outputs +01:00

ukd = "2019-10-27T02:01:00".split('T')
finalDate = moment.tz(ukd[0] + "T" + ukd[1], "YYYY-MM-DDTHH:mm:ss", true, "Europe/London").tz('Europe/London').format('Z');
console.log(finalDate)  // first minute after DST, outputs +00:00

This seems hacky and not clean code, but it's due to a bug in timezone that parses as UTC date instead of timezone date.

