[Phoenix LiveView] 현지 시간대로 날짜/시간 형식 지정
시간대 및 로케일을 가져오는 중
브라우저 쪽
초기 렌더링 직후에 클라이언트-서버 연결이 설정될 때 LiveView 프로세스에서 수신할 수 있도록 브라우저에서 현지 시간대 및 로케일에 대한 정보를 가져와 라이브 소켓 매개변수에 포함하려고 합니다.
다음은 몇 가지 편리한 기능입니다.
/assets/js/app.js
에서 라이브 소켓 매개변수에 키-값 쌍을 간단히 추가할 수 있습니다. 그러면 클라이언트가 LiveView에 연결될 때 액세스할 수 있습니다.-let liveSocket = new LiveSocket('/live', Socket, { params: { _csrf_token: csrfToken } });
+let liveSocket = new LiveSocket('/live', Socket, {
+ params: {
+ _csrf_token: csrfToken,
+ locale: Intl.NumberFormat().resolvedOptions().locale,
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
+ timezone_offset: -(new Date().getTimezoneOffset() / 60),
+ },
+});
[info] CONNECTED TO Phoenix.LiveView.Socket in 112µs
Transport: :websocket
Serializer: Phoenix.Socket.V2.JSONSerializer
Parameters: %{"_csrf_token" => "Ay8cCDsHZCFYBicSKTMHfi5EIjowK3sJHWHrqqVH4hcboKI8a1v_wB4g",
"_mounts" => "0",
"_track_static" => %{"0" => "http://localhost:4000/css/app.css",
"1" => "http://localhost:4000/js/app.js"},
"locale" => "en-US",
"timezone" => "America/New_York",
"timezone_offset" => "-5",
"vsn" => "2.0.0"}
서버측(라이브뷰)
이제 소켓 매개변수에서 시간대와 로케일을 가져오려고 합니다. 한 가지 중요한 것은 소켓 매개변수가 only remain available during mount 이라는 것입니다. 또한 초기 렌더링 시점에는 브라우저에서 파생된 정보를 사용할 수 없기 때문에 기본값을 제공해야 합니다.
defmodule MnishiguchiWeb.TimezoneLive do
use MnishiguchiWeb, :live_view
@default_locale "en"
@default_timezone "UTC"
@default_timezone_offset 0
@impl true
def mount(_params, _session, socket) do
socket =
socket
|> assign_locale()
|> assign_timezone()
|> assign_timezone_offset()
{:ok, socket}
end
defp assign_locale(socket) do
locale = get_connect_params(socket)["locale"] || @default_locale
assign(socket, locale: locale)
end
defp assign_timezone(socket) do
timezone = get_connect_params(socket)["timezone"] || @default_timezone
assign(socket, timezone: timezone)
end
defp assign_timezone_offset(socket) do
timezone_offset = get_connect_params(socket)["timezone_offset"] || @default_timezone_offset
assign(socket, timezone_offset: timezone_offset)
end
...
날짜/시간 형식화
시간대와 로케일이 LiveView 프로세스에 저장되면 datetime 값을 사용자에게 친숙한 형식으로 변환하려고 합니다. 이를 위해 두 개의 편리한 라이브러리가 있습니다.
Timex -
:tzdata
패키지Cldr - Unicode Consortium’s Common Locale Data Repository (CLDR)을 위한 Elixir 라이브러리
다음 라이브러리를
mix.exs
에 추가합니다. defp deps do
[
...
+ {:timex, "~> 3.6"},
+ {:ex_cldr_dates_times, "~> 2.0"},
...
]
end
그런 다음
mix deps.get
를 실행합니다.Cldr library documentation 에 따르면 다음과 같이 모듈을 생성하기만 하면 됩니다.
defmodule Mnishiguchi.Cldr do
@default_locale "en"
@default_timezone "UTC"
@default_format :long
use Cldr,
locales: ["en", "ja"],
default_locale: @default_locale,
providers: [Cldr.Number, Cldr.Calendar, Cldr.DateTime]
@doc """
Formats datatime based on specified options.
## Examples
iex> format_time(~U[2021-03-02 22:05:28Z], locale: "ja", timezone: "Asia/Tokyo")
"2021年3月3日 7:05:28 JST"
iex> format_time(~U[2021-03-02 22:05:28Z], locale: "ja", timezone: "America/New_York")
"2021年3月2日 17:05:28 EST"
iex> format_time(~U[2021-03-02 22:05:28Z], locale: "en-US", timezone: "America/New_York")
"March 2, 2021 at 5:05:28 PM EST"
# Fallback to ISO8601 string.
iex> format_time(~U[2021-03-02 22:05:28Z], timezone: "Hello")
"2021-03-02T22:05:28+00:00"
"""
@spec format_time(DateTime.t(), nil | list | map) :: binary
def format_time(datetime, options \\ []) do
locale = options[:locale] || @default_locale
timezone = options[:timezone] || @default_timezone
format = options[:format] || @default_format
cldr_options = [locale: locale, format: format]
with time_in_tz <- Timex.Timezone.convert(datetime, timezone),
{:ok, formatted_time} <- __MODULE__.DateTime.to_string(time_in_tz, cldr_options) do
formatted_time
else
{:error, _reason} ->
Timex.format!(datetime, "{ISO:Extended}")
end
end
그러면 어디에서나
format_time
기능을 수행할 수 있습니다.로딩 아이콘 추가
이것은 기술적으로 선택 사항이지만 초기 렌더링 당시 브라우저의 정보를 모르기 때문에 기본값으로 대체해야 합니다. 따라서 사용자는 연결이 설정되는 즉시 기본 형식에서 로컬 형식으로 변경되는 시간 형식의 이상한 효과를 보게 됩니다.
This guy uses a different approach 이 문제에 대해 설명하지만 LiveView가 연결될 때까지 콘텐츠를 숨기기로 선택했습니다. 멋진 로딩 아이콘을 표시하여 UI가 여전히 자연스럽게 보일 것이라고 믿습니다. Single Element CSS Spinners 라이브러리가 편리하다는 것을 알았습니다.
<%= unless connected?(@socket) do %>
<div style="min-height:90vh">
<div class="loader">Loading...</div>
</div>
<% else %>
<!-- contents -->
<% end %>
자원
Managing browser timezones to display dates with Phoenix Live View by Alex-Min
Single Element CSS Spinners by lukehaas
Reference
이 문제에 관하여([Phoenix LiveView] 현지 시간대로 날짜/시간 형식 지정), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/mnishiguchi/phoenix-liveview-formatting-date-time-with-local-time-zone-49c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)