Experiments >

Grouping by date

Experiment #21015th July, 2021by Joshua Nussbaum

For my startup project, I built an integration with Skubana.

Every few hours, my app calls their API to pull down the latest shipments. The range of data is specified as a from and to date params in the query string.

Ideally I make the requests in time batches. I need some code to take a to and from time and split it up.

Code

So I came up with this, it splits the time in equal chunks, and any remainder time is a smaller chunk at the end

defmodule DateUtils do
  def time_blocks(from, to, size) do
    seconds = DateTime.diff(to, from)
    groups = (seconds / size) |> Float.ceil() |> trunc()

    blocks = generate_blocks(from, to, size, groups)

    Enum.zip([from|blocks], blocks)
  end

  defp generate_blocks(from, to, size, groups) do
    for n <- 1..groups do
      if n == groups do
        to
      else
        DateTime.add(from, n*size, :second)
      end
    end
  end
end

Demo

> from = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "UTC",
               hour: 12, minute: 0, second: 0, microsecond: {0, 0},
               utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
> to = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "UTC", 
               hour: 23, minute: 0, second: 0, microsecond: {0, 0},
               utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}

> DateUtils.time_blocks(from, to, 60*60*4) |> IO.inspect
[
  {~U[2000-02-29 12:00:00Z], ~U[2000-02-29 16:00:00Z]},
  {~U[2000-02-29 16:00:00Z], ~U[2000-02-29 20:00:00Z]},
  {~U[2000-02-29 20:00:00Z], ~U[2000-02-29 23:00:00Z]}
]
view all experiments

Stay tuned in

Learn how to add more experimentation to your workflow