Как заменить utcOffset из Moment.js на date-fns или обычный JavaScript

Я перехожу с Moment.js на date-fns и столкнулся с проблемой при конвертации функции UTC смещения. У меня есть старый код на Moment.js, который работает правильно, но я не могу найти аналогичную функциональность в date-fns или нативном JavaScript.

Исходный код на Moment.js:

var startDate = new Date('2019-09-09T05:00:00Z');
var finalResult = this.moment(startDate).utcOffset(-5).set({ hour: 0, minute: 0, second: 0, millisecond: 0 }).utc().format();

Результат: 2019-09-09T05:00:00Z

Мой код для конвертации:

function convertOffsetToUTC() {
    var startDate = new Date('2019-09-09T05:00:00Z');
    var processedTime = new Date(startDate);
    var offsetFromDB = -5; // значение временной зоны из базы данных
    
    var timeDifference = offsetFromDB * 60 - processedTime.getTimezoneOffset();
    var adjustedTime = new Date(processedTime.getTime() + timeDifference * 60 * 1000);
    
    adjustedTime.setHours(0, 0, 0, 0);
    
    return convertToUTCFormat(makeUTCDate(adjustedTime));
}

function convertToUTCFormat(dateObj) {
    return format(dateObj, 'yyyy-MM-dd') + 'T' + format(dateObj, 'HH:mm:ss') + 'Z';
}

function makeUTCDate(inputDate) {
    var localOffset = inputDate.getTimezoneOffset();
    return Math.sign(localOffset) !== -1 ? addMinutes(inputDate, localOffset) : subMinutes(inputDate, Math.abs(localOffset));
}

Но результат получается 2019-09-08T18:30:00Z, что не соответствует ожидаемому.

Возможно, я неправильно применяю смещение к дате. Буду благодарен за помощь и предложения по решению этой проблемы.

У тебя проблема в том, что ты смешиваешь локальное время с utc. moment().utcOffset(-5) создаёт время в зоне UTC-5, а потом .utc() просто меняет представление без изменения самого момента времени.

Попробуй так с date-fns:

var startDate = new Date('2019-09-09T05:00:00Z');
var offsetHours = -5;
var adjustedDate = addHours(startDate, offsetHours);
var resetTime = startOfDay(adjustedDate);
var backToOriginal = subHours(resetTime, offsetHours);
return formatISO(backToOriginal);

Твоя ошибка в том что ты применяешь смещение дважды - один раз вручную, потом ещё раз через getTimezoneOffset. А момент делает это внутри себя правильно.

А что если попробовать через zonedTimeToUtc из date-fns-tz? Мне кажется проблема в том что ты пытаешься вручную считать смещения, а момент это делает автоматически. Какая у тебя локальная временная зона? Может быть именно от неё зависит результат?

Тут дело в том, что момент работает не так как кажется. moment().utcOffset(-5).set({hour: 0}).utc() сначала переводит время в UTC-5, обнуляет часы в этой зоне, а потом показывает в UTC.

Проще всего через нативный JS:

var date = new Date('2019-09-09T05:00:00Z');
var utcTime = date.getTime() + (-5 * 60 * 60 * 1000); // смещение -5 часов
var newDate = new Date(utcTime);
newDate.setUTCHours(0, 0, 0, 0); // обнуляем время в UTC
var result = newDate.toISOString();

Твоя функция слишком сложная, а логика момента довольно простая если разобраться.