Pobieranie aktualnej daty i / godziny w Elixirze

83

Wydaje się, że to naprawdę głupie pytanie, ale jak uzyskać i wyświetlić aktualną datę lub godzinę w Elixirze? Próbowałem przeglądać dokumenty, ale nic nie mogłem znaleźć. Czy muszę używać funkcji Erlang?

Graham Conzett
źródło

Odpowiedzi:

56

Aby dokładniej odpowiedzieć na Twoje pytanie (chociaż naprawdę doceniam zalecenie Onorio dotyczące korzystania z Timex!), Możesz pobrać aktualną datę i godzinę ze standardowej biblioteki Erlang za pomocą :calendar.universal_time()lub :calendar.local_time(). Istnieje wiele przydatnych funkcji do pracy z datetimetypem Erlanga w calendarmodule, ale są one nieco ograniczone i nie zapewniają niczego do analizowania lub formatowania dat, w czym pojawia się Timex.

bitwalker
źródło
1
Świetna odpowiedź, dziękuję obojgu i na pewno sprawdzę Timex!
Graham Conzett
17

NaiveDateTime

Jeśli nie zależy Ci na strefie czasowej i chcesz po prostu mieć czystą datę i godzinę, użyj NaiveDateTime:

NaiveDateTime.utc_now
# => ~N[2017-11-30 20:49:54.660724]

DateTime

Jeśli chcesz również szczegóły strefy czasowej, użyj DateTime, które również zwróci takie rzeczy, jak nazwa strefy czasowej, przesunięcie UTC, przesunięcie STD i skrót strefy czasowej:

DateTime.utc_now
# => %DateTime{calendar: Calendar.ISO, day: 30, hour: 20, microsecond: {667345, 6}, minute: 51, month: 11, second: 58, std_offset: 0, time_zone: "Etc/UTC", utc_offset: 0, year: 2017, zone_abbr: "UTC"}

Następnie możesz również wywołać to_date/1iz to_time/1tych modułów, aby uzyskać określone wartości daty i godziny ze struktur datetime.

Sheharyar
źródło
12

Myślę, że najlepszym rozwiązaniem jest użycie biblioteki timex Paula Schoenfeldera (znanej również jako BitWalker) dla Elixir. Biblioteka jest tutaj: https://github.com/bitwalker/timex i możesz pobrać pakiet z hex.pm https://hex.pm/packages/timex . Paul uprzejmie podał dobre wyjaśnienie, jak korzystać z biblioteki na stronie readme repozytorium github.

Możesz dzwonić do rodzimych bibliotek Erlang, ale myślę, że biblioteka Paula jest lepsza, gdy ma się do czynienia z Elixirem.

Onorio Catenacci
źródło
5
Dzięki za polecenie Onorio! Dla każdego, kto to czyta, jestem bardzo otwarty na wkład, abyśmy mogli sprawić, by Timex przeszedł do biblioteki dat / godzin w Elixirze, i być może któregoś dnia scalić go ze standardową biblioteką Elixir, jeśli będzie odpowiedni. Jeśli jesteś zainteresowany pomocą, wyślij mi wiadomość lub zanurkuj w narzędziu do śledzenia problemów na GitHub i wyślij kilka żądań ściągnięcia!
bitwalker
1
@bitwalker Tak, Erlang / Elixir ma wiele rzeczy do zrobienia dla biblioteki daty / czasu. I mam nadzieję, że Timex też da się połączyć w Elixir :)
Tony Han
11

To zależy, w jakim formacie chcesz to mieć.

Możesz użyć dowolnej funkcji ze standardowej biblioteki Erlang firmy Elixir. Tradycyjnie czas otrzymywałbyś dzięki now/0funkcji:

iex(1)> :erlang.now
{1487, 549978, 29683}

Oznacza to time_t1487,549,978,29683, czyli 19 minut i 38,29683 sekund po północy czasu UTC w poniedziałek 20 lutego 2017 roku.

Jednak od Erlang / OTP 18 ta funkcja jest przestarzała; jednym z powodów jest to, że Erlang gwarantuje, że wartość zwracana będzie rosła przy każdym wywołaniu. Jeśli wywołujesz go w ciasnej pętli na maszynie wystarczająco szybko, aby wywołać ją więcej niż raz na mikrosekundę, zwracany znacznik czasu wyprzedza czas rzeczywisty.

Zamiennik to API z większą precyzją i kontrolą . Podstawowym interfejsem tego nowego API jest os:system_time/0funkcja, która zwraca czas epoki w jednostce zdefiniowanej przez system:

iex(2)> :os.system_time
1487549978296838000

Możesz jednak poprosić o konkretną jednostkę za pomocą system_time/1:

iex(3)> :os.system_time(:millisecond)
1487549978296

Od wersji Elixir 1.2 te funkcje były również dostępne w Systemmodule natywnym :

iex(4)> System.system_time(:second)
1487549978

Aby uzyskać bardziej przyjazny, ale nadal natywny interfejs Elixir, użyj calendarmodułu, który da ci krotki:

iex(5)> :calendar.universal_time
{{2017, 2, 20}, {0, 19, 38}}

Od wersji 1.3 Elixir ma również własny zestaw modułów do manipulowania datami i godzinami: Datei DateTime. Możesz użyć jego funkcji, aby uzyskać aktualną datę lub godzinę w następujący sposób:

iex(6)> Date.utc_today
~D[2017-02-20]
iex(7)> DateTime.utc_now
#DateTime<2017-02-20 00:19:38.29683Z>
Mark Reed
źródło
8

Aby uzyskać liczbę milisekund (Unix Timestamp):

DateTime.utc_now() |> DateTime.to_unix(:millisecond)
Sam Houston
źródło
1
Niezły Sam, właśnie tego szukałem;)
Dennis
7

Możesz także użyć :os.timestamp\0, który zwraca {megaseconds, seconds, microseconds}z UTC. :os.timestamp |> :calendar.now_to_datetimeda ci teraz w standardowym {{YYYY, MM, DD}, {HH, MM, SS}}formacie erlang .

G Amini
źródło
3
Aby uzyskać to w sygnaturze czasowej POSIX / UNIX: michal.muskala.eu/2015/07/30/unix-timestamps-in-elixir.html
Henrik N
6

Jeśli potrzebujesz poradzić sobie z czasem letnim lub strefami czasowymi, stworzyłem do tego bibliotekę: Kalendarz .

Aby uzyskać aktualny czas, użyj na przykład Calendar.DateTime.now("America/Los_Angeles")aktualnego czasu w Los Angeles lub Calendar.DateTime.now_utcaktualnego czasu UTC.

Lau
źródło
2

Aby uzyskać uniksowy znacznik czasu

DateTime.to_unix(DateTime.utc_now)
radzserg
źródło
0

Cóż, Timex zwykle przychodzi na ratunek, jednak niektóre z poniższych trików mogą być pomocne:

{erl_date, erl_time} = :calendar.local_time()
# {{2020, 11, 19}, {0, 6, 36}}

{:ok, time} = Time.from_erl(erl_time)
# {:ok, ~T[00:06:36]}

{:ok, date} = Date.from_erl(erl_date)
# {:ok, ~D[2020-11-19]}

Calendar.strftime(time, "%c", preferred_datetime: "%H:%M:%S")
# "00:06:36"


Calendar.strftime(date, "%c", preferred_datetime: "%m-%d-%Y")
# "11-19-2020"
Michaił Chupryński
źródło