Repository: mitsuhiko/minijinja (language: rust)

Issue:
Wrong datetime iso format
## Reproduction steps

```
fn main() {
    let mut env = minijinja::Environment::new();
    env.add_global("TIMEZONE", "America/Chicago");
    minijinja_contrib::add_to_environment(&mut env);

    let expr = env
        .compile_expression("1687624642.5|datetimeformat(format='iso')")
        .unwrap();

    println!("{}", expr.eval(()).unwrap());
}
```

## Actual

2023-06-24T11:37:22+-05:00

## Expected

2023-06-24T11:37:22-05:00

## Fix
https://github.com/mitsuhiko/minijinja/blob/main/minijinja-contrib/src/filters/datetime.rs#L160
to  
"[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]"




Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4675f7bb..9b3cbcaf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@ All notable changes to MiniJinja are documented here.
 
 ## 1.0.6
 
+- Fixed iso datetime formatting not handling negative offsets correctly.  #327
 - Re-report `Value` directly from the crate root for convenience.
 - It's now possible to `deserialize` from a `Value`.  Additionally the
   `ViaDeserialize<T>` argument type was added to support value conversions
diff --git a/minijinja-contrib/src/filters/datetime.rs b/minijinja-contrib/src/filters/datetime.rs
index 8629701e..d0cd833a 100644
--- a/minijinja-contrib/src/filters/datetime.rs
+++ b/minijinja-contrib/src/filters/datetime.rs
@@ -157,7 +157,7 @@ pub fn datetimeformat(state: &State, value: Value, kwargs: Kwargs) -> Result<Str
                 "long" => "[month repr:long] [day padding:none] [year] [hour]:[minute]:[second]",
                 "full" => "[weekday], [month repr:long] [day padding:none] [year] [hour]:[minute]:[second].[subsecond]",
                 "iso" => {
-                    "[year]-[month]-[day]T[hour]:[minute]:[second]+[offset_hour]:[offset_minute]"
+                    "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]"
                 }
                 "unix" => "[unix_timestamp]",
                 other => other,
@@ -228,7 +228,7 @@ pub fn timeformat(state: &State, value: Value, kwargs: Kwargs) -> Result<String,
                 "long" => "[hour]:[minute]:[second]",
                 "full" => "[hour]:[minute]:[second].[subsecond]",
                 "iso" => {
-                    "[year]-[month]-[day]T[hour]:[minute]:[second]+[offset_hour]:[offset_minute]"
+                    "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]"
                 }
                 "unix" => "[unix_timestamp]",
                 other => other,


Test patch:
diff --git a/minijinja-contrib/tests/datetime.rs b/minijinja-contrib/tests/datetime.rs
index 7e040e8b..8a12b34c 100644
--- a/minijinja-contrib/tests/datetime.rs
+++ b/minijinja-contrib/tests/datetime.rs
@@ -44,6 +44,21 @@ fn test_datetimeformat() {
     assert_eq!(expr.eval(()).unwrap().to_string(), "19:37");
 }
 
+#[test]
+fn test_datetimeformat_iso_negative() {
+    let mut env = minijinja::Environment::new();
+    env.add_global("TIMEZONE", "America/Chicago");
+    minijinja_contrib::add_to_environment(&mut env);
+
+    let expr = env
+        .compile_expression("1687624642.5|datetimeformat(format='iso')")
+        .unwrap();
+    assert_eq!(
+        expr.eval(()).unwrap().to_string(),
+        "2023-06-24T11:37:22-05:00"
+    )
+}
+
 #[test]
 fn test_datetimeformat_time_rs() {
     let mut env = minijinja::Environment::new();