2017-10-24 7 views
1

내 목표는 date_time과 date 사이의 시간 차이를 찾는 것입니다. 이 방법으로이 작업을 수행하려고합니다.Elixir/Phoenix의 DateTime 2 시간 간의 차이

pry(1)> dt1 
#DateTime<2017-10-24 05:12:46.000000Z> 

pry(2)> Ecto.DateTime.to_erl(dt1) 
** (FunctionClauseError) no function clause matching in Ecto.DateTime.to_erl/1  

    The following arguments were given to Ecto.DateTime.to_erl/1: 

     # 1 
     #DateTime<2017-10-24 05:12:46.000000Z> 

    Attempted function clauses (showing 1 out of 1): 

     def to_erl(%Ecto.DateTime{year: year, month: month, day: day, hour: hour, min: min, sec: sec}) 

    (ecto) lib/ecto/date_time.ex:608: Ecto.DateTime.to_erl/1 
    # ............ 

해결 방법? 또는 내 목표를 달성하기위한 더 좋은 방법이 있습니까? 내가, 아니 제 3 자 라이브러리를 타이멕스를 사용하지 않고 그것을 사용하지 않습니다

. Elixir/Erlang/Phoenix에 내장 된 플레이어 만.

답변

2

당신은 DateTime.diff/3 사용할 수 있습니다

iex> dt1 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT", 
...>     hour: 23, minute: 0, second: 7, microsecond: {0, 0}, 
...>     utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"} 
iex> dt2 = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET", 
...>     hour: 23, minute: 0, second: 7, microsecond: {0, 0}, 
...>     utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"} 
iex> DateTime.diff(dt1, dt2) 
18000 
iex> DateTime.diff(dt2, dt1) 
-18000 

DateTime.diff/3 이후 반환 초 당신이이 같은 결과에서 시간을 계산하는 데 :

result_in_hours = result_in_seconds/(60*60) 
2

무시 시간대를 완전히 여기에 (그것이 그렇게하기 모든 것을 UTC로 변환하는 것이 가장 쉽고, 지역에 상관없이 캐스트하십시오.) 순수 얼랭 (Erlang) 방식은이 선을 따라 뭔가를하는 것입니다.

1> Event = {{2017,05,23},{13,11,23}}. 
{{2017,5,23},{13,11,23}} 
2> Now = calendar:local_time(). 
{{2017,10,24},{14,44,1}} 
3> EventGSec = calendar:datetime_to_gregorian_seconds(Event). 
63662764283 
4> NowGSec = calendar:datetime_to_gregorian_seconds(Now). 
63676075441 
5> Elapsed = NowGSec - EventGSec. 
13311158  
6> calendar:seconds_to_daystime(Elapsed). 
{154,{1,32,38}} 

정확한 해결책은 필요한 해상도에 따라 달라집니다. 내가 거기에 확신

-

-spec elapsed_time(calendar:datetime()) -> {Days, Time} 
    when Days :: non_neg_integer(), 
     Time :: calendar:time(). 

elapsed_time(Event) -> 
    Now = calendar:local_time(), 
    EventGSec = calendar:datetime_to_gregorian_seconds(Event), 
    NowGSec = calendar:datetime_to_gregorian_seconds(Now), 
    Elapsed = NowGSec - EventGSec, 
    calendar:seconds_to_daystime(Elapsed). 

(why would you ever do that?을하지만, 물론, 위 한 줄에 구성 될 수 있음) : 형태 {Days, {Hours, Minutes, Seconds}}의 튜플을 반환하는 함수로 그 추출하는 것은 우리를 제공합니다 전혀 다른 방식으로 일을하는 와일드 엘릭서 라이브러리입니다. 그 (것)들과 가진 재미를보십시오. 이 대답은 기본 네이티브 라이브러리에만 적용됩니다. Erlang 표준 라이브러리의 대부분의 시간 함수는 이전 erlang:now() 타임 스탬프 형식 (현재 사용되지 않음) 대신 정수 기반 시간 단위 (초, 밀리 초 또는 나노 초)를 기반으로합니다. 위의 함수 버전을 작성해야하는 정확한 방법은 사용자가 요구하는 해상도의 종류와 원래 입력의 형식에 따라 다릅니다 (예 : Unix-era nanoseconds는 자신이 처리하는 타임 스탬프 유형에 대해 매우 일반적입니다. datetime 데이터 유형에는 적용 할 수 없음).

기억 : 시간 계산이 까다 롭고 미묘하며 가장자리 경우에 올바르게 진행되기 어려움. 대부분의 언어에 대한 표준 라이브러리는 실제로 많은 TZ를 가져오고 시간 차이는 잘못 발행됩니다. 문제가 없다면 걱정하지 마십시오. 어쨌든 표준 문서의 Time and Time Correction in Erlang 페이지를 감추는 것이 좋습니다. 현재 상황에 적용되지 않더라도 미묘한 타이밍 문제가 중요한 상황에 처할 것입니다.

0

이 답변은 주제 작성자 이전에 추가되었으며 자신의 질문을 편집했으며 범위에서 외부 라이브러리를 제외 시켰습니다. 내가 타이멕스 매우 유용 어쩌면 사람뿐만 아니라 그것을 사용에 관심이있을 것이다 그러나 나는 그것을 삭제 아니에요 난 강력하게 Timex 라이브러리를 사용하는 것이 좋습니다

을 (내가 타이멕스 제작자와는 아무 상관이 없다). 다양한 형식과 시간대로 날짜/시간 계산에 적합합니다.

Timex.diff(dt1, DateTime.utc_now, :hours) 

당신은 3/DIFF 문서 here을 찾을 수 있습니다 그래서 쉽게 시간 차이를 계산하기 위해 귀하의 경우에 당신은 할 필요가있다.