Calculate the moment when someone has lived for 10^9 seconds.
A gigasecond is 10^9 (1,000,000,000) seconds.
Execute the tests with:
$ mix test
In the test suites, all but the first test have been skipped.
Once you get a test passing, you can unskip the next one by
commenting out the relevant @tag :pending
with a #
symbol.
For example:
# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end
Or, you can enable all the tests by commenting out the
ExUnit.configure
line in the test suite.
# ExUnit.configure exclude: :pending, trace: true
If you're stuck on something, it may help to look at some of the available resources out there where answers might be found.
Chapter 9 in Chris Pine's online Learn to Program tutorial. http://pine.fm/LearnToProgram/?Chapter=09
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
defmodule GigasecondTest do
use ExUnit.Case
# @tag :pending
test "from 4/25/2011" do
assert Gigasecond.from({{2011, 4, 25}, {0, 0, 0}}) == {{2043, 1, 1}, {1, 46, 40}}
end
@tag :pending
test "from 6/13/1977" do
assert Gigasecond.from({{1977, 6, 13}, {0, 0, 0}}) == {{2009, 2, 19}, {1, 46, 40}}
end
@tag :pending
test "from 7/19/1959" do
assert Gigasecond.from({{1959, 7, 19}, {0, 0, 0}}) == {{1991, 3, 27}, {1, 46, 40}}
end
@tag :pending
test "yourself" do
# customize these values for yourself
# your_birthday = {{year1, month1, day1}, {0, 0, 0}}
# assert Gigasecond.from(your_birthday) == {{year2, month2, day2}, {hours, minutes, seconds}}
end
end
ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)
defmodule Gigasecond do
@doc """
Calculate a date one billion seconds after an input date.
"""
@spec from({{pos_integer, pos_integer, pos_integer}, {pos_integer, pos_integer, pos_integer}}) ::
:calendar.datetime()
def from({{year, month, day}, {hours, minutes, seconds}}) do
# piecing the incoming tuples together to get a DateTime object
gd = elem(Date.new(year,month,day), 1)
gt = elem(Time.new(hours,minutes,seconds),1)
gdt = elem(DateTime.new(gd,gt),1)
# using the DateTime add method
gigatime = DateTime.add(gdt, 1000000000)
# formatting the gigatime into tuple pair
{{gigatime.year, gigatime.month, gigatime.day}, {gigatime.hour, gigatime.minute, gigatime.second}}
end
end
I started this challenge by trying to manually convert a billion seconds into the formatted tuple pair, then adding the raw numbers to the parameters of the function. It wasn't long before I realized there was no smart way to factor in the variance in days per month. (A gigasecond is 11,574 days, FYI).
Then I searched and found Elixir's inbuilt Date methods, which contained an add function. Since the incoming times were `{{pairs of}, {tuples}}` I needed to piece them together to create a DateTime object.
Once I got that done, I was pleasantly surprised to find that all I needed to do was `.add(formattedTime, one billion seconds)`.
Level up your programming skills with 3,450 exercises across 52 languages, and insightful discussion with our volunteer team of welcoming mentors. Exercism is 100% free forever.
Sign up Learn More
Community comments