-
Notifications
You must be signed in to change notification settings - Fork 218
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for DateTime and NaiveDateTime (#87)
* Added DateTime support * Standardized Faker.Date with Faker.DateTime * Updated CHANGELOG * Updated USAGE.md * Don't test against now() for DateTime.t * Fixed test for Faker.DateTime.forward/1 * Removed private now() function * Cleaned up Faker.DateTime.between\2 implementation; fixed tests * Added Faker.DateTime.between(Date.T, Date.t) :: DateTime.t implementation * Fixed comments * Added NaiveDateTime support for Faker.DateTime.between/2 * Fixed comment for NaiveDateTime version of Faker.DateTime.between/2 * Removed unused variable * Added NaiveDateTime support * Updated CHANGELOG.md and USAGE.md * Use NaiveDateTime in USAGE * Added copy and paste examples for Faker.DateTime.between/2 and Faker.NaiveDateTime.between/2
- Loading branch information
1 parent
8d8dd3e
commit 5d685da
Showing
8 changed files
with
322 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
if Version.match?(System.version(), ">= 1.3.0") do | ||
defmodule Faker.DateTime do | ||
@microseconds_per_day 86400000000 | ||
|
||
@doc """ | ||
Returns a random date in the past up to N days, today not included | ||
""" | ||
@spec backward(integer) :: DateTime.t | ||
def backward(days) do | ||
forward(-days) | ||
end | ||
|
||
@doc """ | ||
Returns a random date in the future up to N days, today not included | ||
""" | ||
@spec forward(integer) :: DateTime.t | ||
def forward(days) do | ||
sign = if days < 0, do: -1, else: 1 | ||
|
||
today = DateTime.utc_now() |> to_timestamp | ||
from = today + sign * @microseconds_per_day # add or subtract extra day to avoid returning today | ||
to = from + @microseconds_per_day * days | ||
|
||
unix_between(from, to) | ||
end | ||
|
||
@doc """ | ||
Returns a random date & time between two dates | ||
""" | ||
@spec between(Date.t, Date.t) :: DateTime.t | ||
def between(%Date{} = from, %Date{} = to) do | ||
between(date_to_datetime(from), date_to_datetime(to)) | ||
end | ||
|
||
@doc """ | ||
Returns a random `DateTime.t` between two `NaiveDateTime.t`'s | ||
""" | ||
@spec between(NaiveDateTime.t, NaiveDateTime.t) :: DateTime.t | ||
def between(%NaiveDateTime{} = from, %NaiveDateTime{} = to) do | ||
between(naivedatetime_to_datetime(from), naivedatetime_to_datetime(to)) | ||
end | ||
|
||
@doc """ | ||
Returns a random `DateTime.t` between two `DateTime.t`'s | ||
""" | ||
@spec between(DateTime.t, DateTime.t) :: DateTime.t | ||
def between(from, to) do | ||
unix_between(to_timestamp(from), to_timestamp(to)) | ||
end | ||
|
||
# private | ||
|
||
defp date_to_datetime(date) do | ||
%DateTime{calendar: Calendar.ISO, day: date.day, hour: 0, minute: 0, | ||
month: date.month, second: 0, time_zone: "Etc/UTC", | ||
utc_offset: 0, std_offset: 0, year: date.year, zone_abbr: "UTC"} | ||
end | ||
|
||
defp naivedatetime_to_datetime(naivedatetime) do | ||
%DateTime{calendar: naivedatetime.calendar, day: naivedatetime.day, | ||
hour: naivedatetime.hour, minute: naivedatetime.minute, | ||
month: naivedatetime.month, second: naivedatetime.second, | ||
time_zone: "Etc/UTC", utc_offset: 0, std_offset: 0, | ||
year: naivedatetime.year, zone_abbr: "UTC"} | ||
end | ||
|
||
defp to_timestamp(datetime) do | ||
DateTime.to_unix(datetime, :microseconds) | ||
end | ||
|
||
defp unix_between(from, to) do | ||
diff = to - from | ||
sign = if diff < 0, do: -1, else: 1 | ||
|
||
from + sign * :crypto.rand_uniform(0, abs(diff)) | ||
|> DateTime.from_unix!(:microseconds) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
if Version.match?(System.version(), ">= 1.3.0") do | ||
defmodule Faker.NaiveDateTime do | ||
@doc """ | ||
Returns a random date in the past up to N days, today not included | ||
""" | ||
@spec backward(integer) :: NaiveDateTime.t | ||
def backward(days) do | ||
forward(-days) | ||
end | ||
|
||
@doc """ | ||
Returns a random date in the future up to N days, today not included | ||
""" | ||
@spec forward(integer) :: NaiveDateTime.t | ||
def forward(days) do | ||
Faker.DateTime.forward(days) | ||
|> DateTime.to_naive | ||
end | ||
|
||
@doc """ | ||
Returns a random `NaiveDateTime.t` between two `NaiveDateTime.t`'s | ||
""" | ||
@spec between(NaiveDateTime.t, NaiveDateTime.t) :: NaiveDateTime.t | ||
def between(from, to) do | ||
Faker.DateTime.between(from, to) | ||
|> DateTime.to_naive | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
if Version.match?(System.version(), ">= 1.3.0") do | ||
defmodule DateTimeTest do | ||
use ExUnit.Case, async: true | ||
|
||
test "forward/1" do | ||
now = DateTime.utc_now() | ||
forwarded_date = Faker.DateTime.forward(10) | ||
assert %DateTime{ | ||
year: year, month: month, day: day, hour: hour, minute: minute, | ||
second: second, microsecond: microsecond | ||
} = forwarded_date | ||
assert now.year < year || now.month < month | ||
|| now.hour < hour || now.minute < minute | ||
|| now.day < day || now.second < second | ||
|| now.microsecond < microsecond | ||
end | ||
|
||
test "backward/1" do | ||
now = DateTime.utc_now() | ||
backward_date = Faker.DateTime.backward(10) | ||
assert %DateTime{ | ||
year: year, month: month, day: day, hour: hour, minute: minute, | ||
second: second, microsecond: microsecond | ||
} = backward_date | ||
assert now.year > year || now.month > month | ||
|| now.hour > hour || now.minute > minute | ||
|| now.day > day || now.second > second | ||
|| now.microsecond > microsecond | ||
end | ||
|
||
test "between/2 for Date.t" do | ||
from_date = DateTime.utc_now() |> DateTime.to_date | ||
to_date = Faker.DateTime.forward(50) |> DateTime.to_date | ||
between_date = Faker.DateTime.between(from_date, to_date) | ||
assert %DateTime{year: year, month: month, day: day} | ||
= between_date | ||
assert from_date.year <= year || from_date.month <= month | ||
|| from_date.day <= day | ||
assert to_date.year >= year || to_date.month >= month | ||
|| to_date.day >= day | ||
end | ||
|
||
test "between/2 for NaiveDateTime.t" do | ||
from_datetime = DateTime.utc_now() | ||
from_date = from_datetime |> DateTime.to_date | ||
from_time = from_datetime |> DateTime.to_time | ||
{:ok, from_naivedatetime} = NaiveDateTime.new(from_date, from_time) | ||
|
||
to_datetime = Faker.DateTime.forward(50) | ||
to_date = to_datetime |> DateTime.to_date | ||
to_time = to_datetime |> DateTime.to_time | ||
{:ok, to_naivedatetime} = NaiveDateTime.new(to_date, to_time) | ||
|
||
between_date = Faker.DateTime.between(from_naivedatetime, to_naivedatetime) | ||
assert %DateTime{ | ||
year: year, month: month, day: day, hour: hour, minute: minute, | ||
second: second, microsecond: microsecond | ||
} = between_date | ||
assert from_naivedatetime.year <= year || from_naivedatetime.month <= month | ||
|| from_naivedatetime.hour <= hour || from_naivedatetime.minute <= minute | ||
|| from_naivedatetime.day <= day || from_naivedatetime.second <= second | ||
|| from_naivedatetime.microsecond <= microsecond | ||
assert to_naivedatetime.year >= year || to_naivedatetime.month >= month | ||
|| to_naivedatetime.hour >= hour || to_naivedatetime.minute >= minute | ||
|| to_naivedatetime.day >= day || to_naivedatetime.second >= second | ||
|| to_naivedatetime.microsecond >= microsecond | ||
end | ||
|
||
test "between/2 for DateTime.t" do | ||
from_date = DateTime.utc_now() | ||
to_date = Faker.DateTime.forward(50) | ||
between_date = Faker.DateTime.between(from_date, to_date) | ||
assert %DateTime{ | ||
year: year, month: month, day: day, hour: hour, minute: minute, | ||
second: second, microsecond: microsecond | ||
} = between_date | ||
assert from_date.year <= year || from_date.month <= month | ||
|| from_date.hour <= hour || from_date.minute <= minute | ||
|| from_date.day <= day || from_date.second <= second | ||
|| from_date.microsecond <= microsecond | ||
assert to_date.year >= year || to_date.month >= month | ||
|| to_date.hour >= hour || to_date.minute >= minute | ||
|| to_date.day >= day || to_date.second >= second | ||
|| to_date.microsecond >= microsecond | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
if Version.match?(System.version(), ">= 1.3.0") do | ||
defmodule NaiveDateTimeTest do | ||
use ExUnit.Case, async: true | ||
|
||
test "forward/1" do | ||
now_datetime = DateTime.utc_now() | ||
now_date = now_datetime |> DateTime.to_date | ||
now_time = now_datetime |> DateTime.to_time | ||
{:ok, now} = NaiveDateTime.new(now_date, now_time) | ||
|
||
forwarded_date = Faker.NaiveDateTime.forward(10) | ||
assert %NaiveDateTime{ | ||
year: year, month: month, day: day, hour: hour, minute: minute, | ||
second: second, microsecond: microsecond | ||
} = forwarded_date | ||
assert now.year < year || now.month < month | ||
|| now.hour < hour || now.minute < minute | ||
|| now.day < day || now.second < second | ||
|| now.microsecond < microsecond | ||
end | ||
|
||
test "backward/1" do | ||
now_datetime = DateTime.utc_now() | ||
now_date = now_datetime |> DateTime.to_date | ||
now_time = now_datetime |> DateTime.to_time | ||
{:ok, now} = NaiveDateTime.new(now_date, now_time) | ||
|
||
backward_date = Faker.NaiveDateTime.backward(10) | ||
assert %NaiveDateTime{ | ||
year: year, month: month, day: day, hour: hour, minute: minute, | ||
second: second, microsecond: microsecond | ||
} = backward_date | ||
assert now.year > year || now.month > month | ||
|| now.hour > hour || now.minute > minute | ||
|| now.day > day || now.second > second | ||
|| now.microsecond > microsecond | ||
end | ||
|
||
test "between/2" do | ||
from_datetime = DateTime.utc_now() | ||
from_date = from_datetime |> DateTime.to_date | ||
from_time = from_datetime |> DateTime.to_time | ||
{:ok, from_naivedatetime} = NaiveDateTime.new(from_date, from_time) | ||
|
||
to_datetime = Faker.DateTime.forward(50) | ||
to_date = to_datetime |> DateTime.to_date | ||
to_time = to_datetime |> DateTime.to_time | ||
{:ok, to_naivedatetime} = NaiveDateTime.new(to_date, to_time) | ||
|
||
between_date = Faker.DateTime.between(from_naivedatetime, to_naivedatetime) | ||
assert %DateTime{ | ||
year: year, month: month, day: day, hour: hour, minute: minute, | ||
second: second, microsecond: microsecond | ||
} = between_date | ||
assert from_naivedatetime.year <= year || from_naivedatetime.month <= month | ||
|| from_naivedatetime.hour <= hour || from_naivedatetime.minute <= minute | ||
|| from_naivedatetime.day <= day || from_naivedatetime.second <= second | ||
|| from_naivedatetime.microsecond <= microsecond | ||
assert to_naivedatetime.year >= year || to_naivedatetime.month >= month | ||
|| to_naivedatetime.hour >= hour || to_naivedatetime.minute >= minute | ||
|| to_naivedatetime.day >= day || to_naivedatetime.second >= second | ||
|| to_naivedatetime.microsecond >= microsecond | ||
end | ||
end | ||
end |