code: function (input, keepLocalTime) {
              var offset = this._offset || 0,
                  localAdjust;
              if (input != null) {
                  if (typeof input === 'string') {
                      input = utcOffsetFromString(input);
                  }
                  if (Math.abs(input) < 16) {
                      input = input * 60;
                  }
                  if (!this._isUTC && keepLocalTime) {
                      localAdjust = this._dateUtcOffset();
                  }
                  this._offset = input;
                  this._isUTC = true;
                  if (localAdjust != null) {
                      this.add(localAdjust, 'm');
                  }
                  if (offset !== input) {
                      if (!keepLocalTime || this._changeInProgress) {
                          addOrSubtractDurationFromMoment(this,
                                  moment.duration(input - offset, 'm'), 1, false);
                      } else if (!this._changeInProgress) {
                          this._changeInProgress = true;
                          moment.updateOffset(this, true);
                          this._changeInProgress = null;
                      }
                  }
  
                  return this;
              } else {
                  return this._isUTC ? offset : this._dateUtcOffset();
              }
          }
docs: keepLocalTime = true means only change the timezone, without affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset +0200, so we adjust the time as needed, to be valid.  Keeping the time actually adds/subtracts (one hour) from the actual represented time. That is why we call updateOffset a second time. In case it wants us to change the offset again _changeInProgress == true case, then we have to adjust, because there is no such time in the given timezone.