docs: @SuppressWarnings("deprecation")
      private void set_fields_from_millis(long millis)
      {
          if(millis < MINIMUM_TIMESTAMP_IN_MILLIS){
              throw new IllegalArgumentException("year is less than 1");
          }
  
          Date date = new Date(millis);
  
          // The Date getters return values in the Date's time zone (i.e. the system time zone).
          // The components need to be converted to UTC before being validated for exact ranges, because the offset
          // conversion can affect which values are considered valid. Simply verify that the values can fit in the
          // destination type here. If they do not, they would be out of range no matter the offset.
          _minute = requireByte(date.getMinutes(), "Minute");
          _second = requireByte(date.getSeconds(), "Second");
          _hour = requireByte(date.getHours(), "Hour");
          _day = requireByte(date.getDate(), "Day");
          _month = requireByte(date.getMonth() + 1, "Month");
  
          // Date does not correctly handle year values that represent year 0 or earlier in the system time zone through
          // getYear(). This case is detected and forced to zero.
          int offset = -date.getTimezoneOffset();
          if(offset < 0 && MINIMUM_TIMESTAMP_IN_MILLIS - offset > millis) {
              _year = 0;
          } else {
              _year = requireShort(date.getYear() + 1900, "Year");
          }
  
          // Now apply the offset to convert the components to UTC.
          apply_offset(offset);
  
          // Now that all components are in UTC, they may be validated for exact ranges.
          this._year    = checkAndCastYear(_year);
          this._month   = checkAndCastMonth(_month);
          this._day     = checkAndCastDay(_day, _year, _month);
          this._hour    = checkAndCastHour(_hour);
          this._minute  = checkAndCastMinute(_minute);
          this._second  = checkAndCastSecond(_second);
      }