pub fn parse_timezone_offset(tz: &str) -> crate::errors::GitResult<i32> {
    use crate::errors::GitError;

    if tz.len() != 5 {
        return Err(GitError::ParseError(format!(
            "invalid timezone format: {tz}"
        )));
    }

    let sign: i32 = if tz.starts_with('+') {
        1
    } else if tz.starts_with('-') {
        -1
    } else {
        return Err(GitError::ParseError(format!(
            "invalid timezone sign: {tz}"
        )));
    };

    let hours: i32 = tz[1..3].parse().map_err(|_| {
        GitError::ParseError(format!("invalid timezone hours: {tz}"))
    })?;
    let minutes: i32 = tz[3..5].parse().map_err(|_| {
        GitError::ParseError(format!("invalid timezone minutes: {tz}"))
    })?;

    Ok(sign * (hours * 60 + minutes))
}
pub fn parse_iso_timezone(iso_date: &str) -> crate::errors::GitResult<i32> {
    let tz_part =
        iso_date.rsplit_once(' ').map(|(_, tz)| tz).ok_or_else(|| {
            crate::errors::GitError::ParseError(format!(
                "ISO date missing timezone: {iso_date}"
            ))
        })?;

    parse_timezone_offset(tz_part)
}
pub fn format_git_timestamp(secs: i64, offset_minutes: i32) -> String {
    let sign = if offset_minutes >= 0 { '+' } else { '-' };
    let abs_offset = offset_minutes.abs();
    let hours = abs_offset / 60;
    let mins = abs_offset % 60;
    format!("{} {}{:02}{:02}", secs, sign, hours, mins)
}
