diff --git a/CHANGELOG.md b/CHANGELOG.md index 36fe4f2e66..8edfc05e49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `jj git fetch` now accepts `-b` as a shorthand for `--branch`, making it more consistent with other commands that accept a branch +* In the templating language, Timestamps now have a `.local()` method for + converting to the local timezone. + ### Fixed bugs * On Windows, symlinks in the repo are now materialized as regular files in the diff --git a/cli/src/template_builder.rs b/cli/src/template_builder.rs index c26fb801e8..13933158b6 100644 --- a/cli/src/template_builder.rs +++ b/cli/src/template_builder.rs @@ -571,6 +571,17 @@ fn build_timestamp_method<'a, L: TemplateLanguage<'a>>( timestamp })) } + "local" => { + template_parser::expect_no_arguments(function)?; + let tz_offset = chrono::Local::now().offset().local_minus_utc() / 60; + language.wrap_timestamp(TemplateFunction::new( + self_property, + move |mut timestamp| { + timestamp.tz_offset = tz_offset; + timestamp + }, + )) + } _ => return Err(TemplateParseError::no_such_method("Timestamp", function)), }; Ok(property) diff --git a/cli/tests/test_commit_template.rs b/cli/tests/test_commit_template.rs index 6639923159..13eda0c4fa 100644 --- a/cli/tests/test_commit_template.rs +++ b/cli/tests/test_commit_template.rs @@ -122,6 +122,27 @@ fn test_log_author_timestamp_utc() { "###); } +#[cfg(unix)] +#[test] +fn test_log_author_timestamp_local() { + let mut test_env = TestEnvironment::default(); + test_env.jj_cmd_ok(test_env.env_root(), &["init", "repo", "--git"]); + let repo_path = test_env.env_root().join("repo"); + + test_env.add_env_var("TZ", "UTC-05:30"); + let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "author.timestamp().local()"]); + insta::assert_snapshot!(stdout, @r###" + @ 2001-02-03 02:35:07.000 +05:30 + ◉ 1970-01-01 05:30:00.000 +05:30 + "###); + test_env.add_env_var("TZ", "UTC+10:00"); + let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "author.timestamp().local()"]); + insta::assert_snapshot!(stdout, @r###" + @ 2001-02-02 11:05:07.000 -10:00 + ◉ 1969-12-31 14:00:00.000 -10:00 + "###); +} + #[test] fn test_log_default() { let test_env = TestEnvironment::default(); diff --git a/docs/templates.md b/docs/templates.md index 65af9ebe78..cbeaec3aeb 100644 --- a/docs/templates.md +++ b/docs/templates.md @@ -187,6 +187,7 @@ The following methods are defined. * `.format(format: String) -> String`: Format with [the specified strftime-like format string](https://docs.rs/chrono/latest/chrono/format/strftime/). * `.utc() -> Timestamp`: Convert timestamp into UTC timezone. +* `.local() -> Timestamp`: Convert timestamp into local timezone. ### TimestampRange type