class TimeZoneWrapper {

    private final TimeZone timeZone;
    private final long currentTimestamp;

    public TimeZoneWrapper(TimeZone timeZone, long currentTimestamp) {
        this.timeZone = timeZone;
        this.currentTimestamp = currentTimestamp;
    }

    private String getTimeZoneText() {
        int offset = timeZone.getOffset(currentTimestamp);
        long hours = TimeUnit.MILLISECONDS.toHours(offset);
        long minutes = TimeUnit.MILLISECONDS.toMinutes(offset)
            - TimeUnit.HOURS.toMinutes(hours);
        minutes = Math.abs(minutes);

        if (hours >= 0) {
            return String.format("%s (GMT+%d:%02d)", timeZone.getID(), hours, minutes);
        } else {
            return String.format("%s (GMT%d:%02d)", timeZone.getID(), hours, minutes);
        }
    }

    @Override
    public int hashCode() {<FILL_FUNCTION_BODY>}

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final TimeZoneWrapper other = (TimeZoneWrapper) obj;
        return this.timeZone == other.timeZone || (this.timeZone != null && this.timeZone.equals(other.timeZone));
    }

    @Override
    public String toString() {
        return getTimeZoneText();
    }

    public TimeZone getTimeZone() {
        return timeZone;
    }
}

        int hash = 5;
        hash = 97 * hash + (this.timeZone != null ? this.timeZone.hashCode() : 0);
        return hash;
    
<no_super_class>