public static function of(int $hours, int $minutes = 0, int $seconds = 0) : TimeZoneOffset
    {
        Field\TimeZoneOffsetHour::check($hours);
        Field\TimeZoneOffsetMinute::check($minutes);
        Field\TimeZoneOffsetSecond::check($seconds);

        $err = ($hours > 0 && ($minutes < 0 || $seconds < 0))
            || ($hours < 0 && ($minutes > 0 || $seconds > 0))
            || ($minutes > 0 && $seconds < 0)
            || ($minutes < 0 && $seconds > 0);

        if ($err) {
            throw new DateTimeException('Time zone offset hours, minutes and seconds must have the same sign');
        }

        $totalSeconds = $hours * LocalTime::SECONDS_PER_HOUR
            + $minutes * LocalTime::SECONDS_PER_MINUTE
            + $seconds;

        Field\TimeZoneOffsetTotalSeconds::check($totalSeconds);

        return new TimeZoneOffset($totalSeconds);
    }