c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

Elixirの日時用helper

きっと何人目だ感あふれる、日付時刻用にhelper moduleだよ。
Erlang{{year, month, date}, {hour, minute, second}}形式のtupleを日時に使う事が多いっぽいから、其れとの相互変換も仕込んでるよ。
RubyActiveSupport Timeみたいな1.years.beforeみたいのも、できるっぽいから、やってみたいよね。macroだよなあ。

# license: Public Domain

defmodule DateHelper do
  defrecord DateTime,
    year: nil,
    month: nil,
    date: nil,
    hour: nil,
    minute: nil,
    second: nil

  def fromTuple {{year, month, date}, {hour, minute, second}} do
    DateTime.new year: year, month: month, date: date, hour: hour, minute: minute, second: second
  end

  def toTuple DateTime[year: year, month: month, date: date, hour: hour, minute: minute, second: second] do
    {{year, month, date}, {hour, minute, second}}
  end

  # cf. Erlang Questions - formatting timestamps http://erlang.2086793.n4.nabble.com/formatting-timestamps-td3594191.html
  def fromTimestamp now do
    fromTuple :calendar.now_to_universal_time(now)
  end

  # cf. How to convert datetime() to timestamp() in erlang - Stack Overflow http://stackoverflow.com/questions/12527908/how-to-convert-datetime-to-timestamp-in-erlang
  def toTimestamp datetime do
    zero = :calendar.datetime_to_gregorian_seconds {{1970, 1, 1}, {0, 0, 0}}
    seconds = :calendar.datetime_to_gregorian_seconds(toTuple datetime) - zero
    {seconds div 1000000, seconds rem 1000000, 0}
  end

  def now do
    fromTimestamp :erlang.now
  end

  def fromDictList dict do
    DateTime.new year: dict[:year], month: dict[:month], date: dict[:date], hour: dict[:hour], minute: dict[:minute], second: dict[:second]
  end

  def toDictList DateTime[year: year, month: month, date: date, hour: hour, minute: minute, second: second] do
    [year: year, month: month, date: date, hour: hour, minute: minute, second: second]
  end

  def fromDateTimeString str do
    regex = %r{^(?<year>\d+)-(?<month>\d+)-(?<date>\d+) (?<hour>\d+):(?<minute>\d+):(?<second>\d+)}g
    captures = Regex.captures regex, str
    captures = Enum.map captures,
      fn {key, value} ->
        {key, elem(String.to_integer(value), 0)}
      end
    fromDictList captures
  end

  def toDateString DateTime[year: year, month: month, date: date] do
    "#{year}-#{pad month}-#{pad date}"
  end

  def toTimeString DateTime[hour: hour, minute: minute, second: second] do
    "#{pad hour}:#{pad minute}:#{pad second}"
  end

  def toDatetimeString datetime do
    "#{toDateString datetime} #{toTimeString datetime}"
  end

  defp pad num do
    pad num, 2
  end
  defp pad num, digits do
    List.flatten :io_lib.format("~#{digits}..0w", [num])
  end
end