Skip to content

Commit

Permalink
Merge pull request #101 from bmulvihill/time2
Browse files Browse the repository at this point in the history
Changes to Time Implementation
  • Loading branch information
faultyserver authored Dec 30, 2017
2 parents e7c407a + 11c68c8 commit bc91fc0
Show file tree
Hide file tree
Showing 3 changed files with 343 additions and 38 deletions.
136 changes: 135 additions & 1 deletion spec/myst/time_spec.mt
Original file line number Diff line number Diff line change
@@ -1,14 +1,81 @@
require "stdlib/spec.mt"

describe("Time#initialize") do
it("instantiates a new time type") do
it("instantiates second, nanosecond") do
t = %Time{63618825600, 10}
assert(t.year == 2017)
assert(t.month == 1)
assert(t.day == 1)
assert(t.hour == 0)
assert(t.minute == 0)
assert(t.second == 0)
assert(t.nanosecond == 10)
end

it("instantiates year, month, day") do
t = %Time{2017, 1, 2}
assert(t.year == 2017)
assert(t.month == 1)
assert(t.day == 2)
assert(t.hour == 0)
assert(t.minute == 0)
assert(t.second == 0)
assert(t.nanosecond == 0)
end

it("instantiates year, month, day, hour") do
t = %Time{2017, 1, 2, 3}
assert(t.year == 2017)
assert(t.month == 1)
assert(t.day == 2)
assert(t.hour == 3)
assert(t.minute == 0)
assert(t.second == 0)
assert(t.nanosecond == 0)
end

it("instantiates year, month, day, hour, minute") do
t = %Time{2017, 1, 2, 3, 4}
assert(t.year == 2017)
assert(t.month == 1)
assert(t.day == 2)
assert(t.hour == 3)
assert(t.minute == 4)
assert(t.second == 0)
assert(t.nanosecond == 0)
end

it("instantiates year, month, day, hour, minute, second") do
t = %Time{2017, 1, 2, 3, 4, 5}
assert(t.year == 2017)
assert(t.month == 1)
assert(t.day == 2)
assert(t.hour == 3)
assert(t.minute == 4)
assert(t.second == 5)
assert(t.nanosecond == 0)
end

it("instantiates year, month, day, hour, minute, second, nanosecond") do
t = %Time{2017, 1, 2, 3, 4, 5, 6}
assert(t.year == 2017)
assert(t.month == 1)
assert(t.day == 2)
assert(t.hour == 3)
assert(t.minute == 4)
assert(t.second == 5)
assert(t.nanosecond == 6)
end

it("raises invalid time") do
expect_raises { %Time{5, 10000000000} }
expect_raises { %Time{100000, 10, 1} }
expect_raises { %Time{2017, 15, 1} }
expect_raises { %Time{2017, 10, 40} }
expect_raises { %Time{2017, 10, 15, 600} }
expect_raises { %Time{2017, 10, 15, 12, 65} }
expect_raises { %Time{2017, 10, 15, 12, 59, 61} }
expect_raises { %Time{2017, 10, 15, 12, 59, 59, -1} }
end
end

Expand Down Expand Up @@ -74,8 +141,75 @@ describe("Time#-") do
assert(t1 - t2 == -1.0)
end

it("gives fractional seconds") do
t1 = %Time{2017, 1, 2, 3, 4, 5, 7}
t2 = %Time{2017, 1, 2, 3, 4, 6, 8}
assert(t2 - t1 == 1.000000001)
end

it("raises if a non Time type is passed") do
t1 = %Time{2017, 1, 2, 3, 4, 5}
expect_raises { t1 - nil }
end
end

describe("Time#year") do
it("returns the year") do
t = %Time{2017, 1, 2, 3, 4, 5}
assert(t.year == 2017)
end
end

describe("Time#month") do
it("returns the month") do
t = %Time{2017, 1, 2, 3, 4, 5}
assert(t.month == 1)
end
end

describe("Time#day") do
it("returns the day") do
t = %Time{2017, 1, 2, 3, 4, 5}
assert(t.day == 2)
end
end

describe("Time#hour") do
it("returns the hour") do
t = %Time{2017, 1, 2, 3, 4, 5}
assert(t.hour == 3)
end
end

describe("Time#minute") do
it("returns the minute") do
t = %Time{2017, 1, 2, 3, 4, 5}
assert(t.minute == 4)
end
end

describe("Time#second") do
it("returns the second") do
t = %Time{2017, 1, 2, 3, 4, 5}
assert(t.second == 5)
end
end

describe("Time#millisecond") do
it("returns 0 when no nanoseconds") do
t = %Time{2017, 1, 2, 3, 4, 5}
assert(t.millisecond == 0)
end

it("returns the millisecond") do
t = %Time{2017, 1, 2, 3, 4, 5, 6000000}
assert(t.millisecond == 6)
end
end

describe("Time#nanosecond") do
it("returns the nanosecond") do
t = %Time{2017, 1, 2, 3, 4, 5, 6}
assert(t.nanosecond == 6)
end
end
32 changes: 7 additions & 25 deletions src/myst/interpreter/native_lib/time.cr
Original file line number Diff line number Diff line change
@@ -1,31 +1,17 @@
module Myst
class Interpreter
NativeLib.method :static_time_now, Value do
t = Time.now
seconds, nanoseconds = Crystal::System::Time.compute_utc_seconds_and_nanoseconds
offset = Crystal::System::Time.compute_utc_offset(seconds)

instance = NativeLib.instantiate(self, this.as(TType), [
TInteger.new(t.year.to_i64),
TInteger.new(t.month.to_i64),
TInteger.new(t.day.to_i64),
TInteger.new(t.hour.to_i64),
TInteger.new(t.minute.to_i64),
TInteger.new(t.second.to_i64)
TInteger.new(seconds + offset),
TInteger.new(nanoseconds.to_i64)
] of Value)

instance
end

NativeLib.method :time_subtract, Value, other : Value do
case __typeof(other).name
when "Time"
this_time = to_crystal_time(this.as(TInstance))
other_time = to_crystal_time(other.as(TInstance))
TFloat.new((this_time - other_time).total_seconds)
else
raise NativeLib.error("invalid argument for Time#-: #{__typeof(other).name}", callstack)
end
end

NativeLib.method :time_to_s, TInstance, format : TString? do
crystal_time = to_crystal_time(this)

Expand All @@ -42,19 +28,15 @@ module Myst

NativeLib.def_method(time_type, :now, :static_time_now)
NativeLib.def_instance_method(time_type, :to_s, :time_to_s)
NativeLib.def_instance_method(time_type, :-, :time_subtract)

time_type
end

private def to_crystal_time(myst_time : TInstance)
Time.new(
myst_time.ivars["@year"].as(TInteger).value,
myst_time.ivars["@month"].as(TInteger).value,
myst_time.ivars["@day"].as(TInteger).value,
myst_time.ivars["@hour"].as(TInteger).value,
myst_time.ivars["@minute"].as(TInteger).value,
myst_time.ivars["@second"].as(TInteger).value
seconds: myst_time.ivars["@seconds"].as(TInteger).value,
nanoseconds: myst_time.ivars["@nanoseconds"].as(TInteger).value.to_i32,
kind: Time::Kind::Unspecified
)
end
end
Expand Down
Loading

0 comments on commit bc91fc0

Please sign in to comment.