From 97f2794d0188af5bd4b765c76e23bb91ca8cd757 Mon Sep 17 00:00:00 2001 From: Sijawusz Pur Rahnama Date: Mon, 30 Jun 2025 16:11:45 +0200 Subject: [PATCH 1/2] Add `Time::Location#{to,from}_json` --- spec/std/json/serialization_spec.cr | 10 ++++++++++ src/json/from_json.cr | 4 ++++ src/json/to_json.cr | 6 ++++++ 3 files changed, 20 insertions(+) diff --git a/spec/std/json/serialization_spec.cr b/spec/std/json/serialization_spec.cr index cf6af88736b0..a205cec351c1 100644 --- a/spec/std/json/serialization_spec.cr +++ b/spec/std/json/serialization_spec.cr @@ -496,6 +496,10 @@ describe "JSON serialization" do Time.from_json(%("20161116T095548-03:00")).to_utc.should eq(Time.utc(2016, 11, 16, 12, 55, 48)) end + it "deserializes Time::Location" do + Time::Location.from_json(%("UTC")).should eq(Time::Location.load("UTC")) + end + describe "parse exceptions" do it "has correct location when raises in NamedTuple#from_json" do ex = expect_raises(JSON::ParseException) do @@ -816,6 +820,12 @@ describe "JSON serialization" do end end + describe "Time::Location" do + it "#to_json" do + Time::Location.load("UTC").to_json.should eq(%("UTC")) + end + end + it "provide symmetric encoding and decoding for Union types" do a = 1.as(Float64 | Int32) b = (Float64 | Int32).from_json(a.to_json) diff --git a/src/json/from_json.cr b/src/json/from_json.cr index ef36b296ab66..c8b3b4ceaca7 100644 --- a/src/json/from_json.cr +++ b/src/json/from_json.cr @@ -478,6 +478,10 @@ def Time.new(pull : JSON::PullParser) Time::Format::ISO_8601_DATE_TIME.parse(pull.read_string) end +def Time::Location.new(pull : JSON::PullParser) + load(pull.read_string) +end + struct Time::Format def from_json(pull : JSON::PullParser) : Time string = pull.read_string diff --git a/src/json/to_json.cr b/src/json/to_json.cr index 7e52b5663786..1035eac64698 100644 --- a/src/json/to_json.cr +++ b/src/json/to_json.cr @@ -171,6 +171,12 @@ struct NamedTuple end end +class Time::Location + def to_json(json : JSON::Builder) : Nil + json.string(to_s) + end +end + struct Time::Format def to_json(value : Time, json : JSON::Builder) : Nil json.string do |io| From ba7b99d68429677c43110141b7e45c6134bb0220 Mon Sep 17 00:00:00 2001 From: Sijawusz Pur Rahnama Date: Mon, 30 Jun 2025 16:12:08 +0200 Subject: [PATCH 2/2] Add `Time::Location#{to,from}_yaml` --- spec/std/yaml/serialization_spec.cr | 9 +++++++++ src/yaml/from_yaml.cr | 8 ++++++++ src/yaml/to_yaml.cr | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/spec/std/yaml/serialization_spec.cr b/spec/std/yaml/serialization_spec.cr index 9a4e713f0768..90a231e0b802 100644 --- a/spec/std/yaml/serialization_spec.cr +++ b/spec/std/yaml/serialization_spec.cr @@ -397,6 +397,10 @@ describe "YAML serialization" do expect_raises(YAML::ParseException) { Time.from_yaml(%(!!timestamp "2001-12-14\\v21:59:43.10 -5")) } end + it "deserializes Time::Location" do + Time::Location.from_yaml("UTC").should eq(Time::Location.load("UTC")) + end + it "deserializes bytes" do Bytes.from_yaml("!!binary aGVsbG8=").should eq("hello".to_slice) end @@ -665,6 +669,11 @@ describe "YAML serialization" do assert_yaml_document_end(time.to_yaml, "--- 2010-11-12 01:02:03.456000000\n") end + it "does for time location" do + location = Time::Location.load("UTC") + assert_yaml_document_end(location.to_yaml, "--- UTC\n") + end + it "does for bytes" do yaml = "hello".to_slice.to_yaml diff --git a/src/yaml/from_yaml.cr b/src/yaml/from_yaml.cr index 227adb64c3c0..bc954afc0df3 100644 --- a/src/yaml/from_yaml.cr +++ b/src/yaml/from_yaml.cr @@ -331,6 +331,14 @@ def Time.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node) parse_scalar(ctx, node, Time) end +def Time::Location.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node) + unless node.is_a?(YAML::Nodes::Scalar) + node.raise "Expected scalar, not #{node.kind}" + end + + load(node.value) +end + struct Time::Format def from_yaml(ctx : YAML::ParseContext, node : YAML::Nodes::Node) : Time unless node.is_a?(YAML::Nodes::Scalar) diff --git a/src/yaml/to_yaml.cr b/src/yaml/to_yaml.cr index 3211b9187ed0..7c9fdb2c778e 100644 --- a/src/yaml/to_yaml.cr +++ b/src/yaml/to_yaml.cr @@ -238,6 +238,12 @@ struct Time end end +class Time::Location + def to_yaml(yaml : YAML::Nodes::Builder) : Nil + yaml.scalar to_s + end +end + struct Time::Format def to_yaml(value : Time, yaml : YAML::Nodes::Builder) : Nil yaml.scalar format(value)