Преобразовать эпоху в удобочитаемую строку даты, как я могу сделать мой код короче? - PullRequest
1 голос
/ 10 апреля 2020

Я конвертирую timestamp, то есть эпоху Unix (в секундах), в читабельный формат. trunc предназначен для преобразования экспоненциального числа в int. Как я могу сделать мой код короче?

  def format_timestamp(timestamp) do
    timestamp
        |> trunc
        |> DateTime.from_unix!(:second)
        |> (fn t -> 
            date = [t.year, t.month, t.day]
            |> Enum.map(&to_string/1)
            |> Enum.map(&String.pad_leading(&1, 2, "0"))
            |> Enum.join("-")

            timing = [t.hour, t.minute, t.second]
            |> Enum.map(&to_string/1)
            |> Enum.map(&String.pad_leading(&1, 2, "0"))
            |> Enum.join(":")

            ~s(#{date}T#{timing}.#{t.time_zone |> String.replace("Etc/UTC", "000Z")})
        end).()
  end

Редактировать: ввод в эпоху в секундах (целое число). Желаемый результат - строка в следующем формате: 2020-04-09T09:26:12.000Z с ведущими нулями для месяца, дня, часа, минут и секунд.

Ответы [ 3 ]

1 голос
/ 10 апреля 2020

Вы не упомянули, что ваш вход и желаемый выход. Если UT C в порядке, самый простой способ - использовать DateTime.to_string/1:

1586490833
|> DateTime.from_unix!()
|> DateTime.to_string

Выход:

"2020-04-10 03:53:53Z"

Ваш алгоритм возвращает "2020-04-10 03:53:53 UTC". Чтобы получить это, вы можете заменить Z, используя String.replace/4:

1586490833
|> DateTime.from_unix!()
|> DateTime.to_string
|> String.replace("Z", " UTC")

Или вы можете создать свою собственную строку, используя свойство zone_abbr из DateTime:

{:ok, dt} = DateTime.from_unix(1586490833)
"#{DateTime.to_date(dt)} #{DateTime.to_time(dt} #{dt.zone_abbr}"
0 голосов
/ 10 апреля 2020

Для полного контроля я бы go создал бы собственный форматер для какой строки ISO-8601, которая получается из DateTime.to_iso8601!/1.

@date_delim ?-
@time_delim ?:
@zone_suffix " UTC"

# 20200410T040640Z
def format_timestamp(<<
  y1, y2, y3, y4, m1, m2, d1, d2, ?T,
  h1, h2, i1, i2, s1, s2, ?Z
>>), do: <<
  y1, y2, y3, y4, @date_delim, m1, m2, @date_delim, d1, d2, ?\s,
  h1, h2, @time_delim, i1, i2, @time_delim, s1, s2, @zone_suffix >>

def format_timestamp(timestamp) when is_integer(timestamp) do
  timestamp
  |> DateTime.from_unix!()
  |> DateTime.to_iso8601(:basic)
  |> format_timestamp()
end

Для всего остального последний ответ, предоставленный Адамом Миллерчипом с использованием dt.zone_abbr, будет наилучшим.

0 голосов
/ 10 апреля 2020

Это может помочь

def format_timestamp(timestamp) do
  "#{
    timestamp
    |> DateTime.from_unix!()
    |> DateTime.to_naive()
    |> NaiveDateTime.to_string()
  } UTC"
end
...