How can I compare to minutes to something like local time

Why are you answering a question with a question? :grinning_face_with_smiling_eyes:

I am trying to understand what does your data represent exactly so I can try and help you.

So it’s elapsed minutes since current week’s Monday midnight, correct?

Yes something like that

Then you’d need to get the date for beginning of the week convert it to a datetime with zero time Time.new!(0,0,0), and add minutes * 60 seconds to it. You might also need to use a timezone other than UTC for calculations to be correct (comparing to DateTime.utc_now probably would work fine anyways).

1 Like

So do you mean with start_time and end_time there should be a date also?

I might not fully understand the problem, but based on minutes being relative to beginning of the week, yes, each minute in your dataset would need to be using a reference date to get a correct datetime.

iex(1)> minutes = 3600
3600
iex(2)> bow = Date.beginning_of_week(Date.utc_today)
~D[2021-09-13]
iex(3)> reference = DateTime.new!(bow, Time.new!(0,0,0))
~U[2021-09-13 00:00:00Z]
iex(4)> DateTime.add(reference, minutes * 60)
~U[2021-09-15 12:00:00Z]

Yes it makes sense.

I have one more question. How can I check if this ~U[2021-09-15 11:44:25.320726Z]
lies between this [~U[2021-09-15 12:00:00Z], ~U[2021-09-16 08:00:00Z]]. Is there any in built function for this?

I know there is Time.diff/2.

1 Like

You’d use DateTime.compare twice.

iex(5)> dt = ~U[2021-09-15 11:44:25.320726Z]
~U[2021-09-15 11:44:25.320726Z]
iex(6)> interval =  [~U[2021-09-15 12:00:00Z], ~U[2021-09-16 08:00:00Z]]
[~U[2021-09-15 12:00:00Z], ~U[2021-09-16 08:00:00Z]]
iex(7)> [from, to] = interval
[~U[2021-09-15 12:00:00Z], ~U[2021-09-16 08:00:00Z]]
iex(8)> DateTime.compare(dt, from)
:lt
iex(9)> DateTime.compare(dt, to)
:lt
iex(10)> between = fn date, [from, to] ->
...(10)>   after_from? = DateTime.compare(date, from) == :gt
...(10)>   before_to? = DateTime.compare(date, to) == :lt
...(10)>   after_from? and before_to?
...(10)> end
#Function<43.40011524/2 in :erl_eval.expr/5>
iex(11)> between.(dt, interval)
false

Another way would be to store start_time as datetime, and a duration (in minutes)…

This allow easy conversion, from start, stop and duration.

1 Like

Yeah this is also good. I was trying with Time.diff/2.

I don’t think Time.diff would work for your use-case as you’ve described here.

1 Like

I maintain the little library Tox. Maybe Tox could be helpful for you.

iex(1)> interval = fn [s, e] ->
...(1)>   b = DateTime.utc_now() |> Tox.DateTime.beginning_of_week()
...(1)>   s = Tox.DateTime.shift(b, minute: s)
...(1)>   e = Tox.DateTime.shift(b, minute: e)
...(1)>   Tox.Interval.new!(s, e)
...(1)> end
#Function<44.40011524/1 in :erl_eval.expr/5>
iex(2)> i = interval.([3600, 4800])
#Tox.Interval<[2021-09-15T12:00:00.000000Z/2021-09-16T08:00:00.000000Z[>
iex(3)> Tox.Interval.contains?(i, ~U[2021-09-15 12:00:00Z])
true
iex(4)> Tox.Interval.contains?(i, ~U[2021-09-16 12:00:00Z])
false
2 Likes

This is really nice. Thanks :slight_smile:

1 Like

I have one more question
Can we convert local DateTime to integer also?
DateTime.utc_now() = ~U[2021-09-16 13:31:56.389124Z]
something like in minutes? or second?

Yes, we can subtract the reference from it with DateTime.diff. But why? In my experience, it’s much less error prone to work with proper date(time) types than integers.

Yes but how? In this case, you need two DateTime, right?

I’m trying to test with both. In any case I will learn something when I will write few test cases.

I think it might be time for you to do some research on your own. I’ve provided enough info in the snippets above.

1 Like

Sure thanks