Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The new calendar types in Elixir 1.3

lau
September 02, 2016

The new calendar types in Elixir 1.3

Elixir 1.3 adds new built-in types for date and time.

Hear about the considerations behind them and how they can improve the quality of your data and software.

When should you use a NaiveDateTime instead of a DateTime? Find out the what best practices are for all the new types. Be it with Ecto, with Phoenix or in Elixir in general.

lau

September 02, 2016
Tweet

Other Decks in Technology

Transcript

  1. Calendar types in
    Elixir 1.3
    ElixirConf 2016

    View Slide

  2. Lau Taarnskov
    Software developer
    Open source contributor. Creator of
    Calendar for Elixir and tzdata
    Blog: creativedeletion.com
    Twitter: @laut
    Github: lau

    View Slide

  3. Lau Taarnskov - twitter: @LauT
    What is a type?

    View Slide

  4. Lau Taarnskov - twitter: @LauT
    Why have types?

    View Slide

  5. Lau Taarnskov - twitter: @LauT
    iex(1)> 5/2
    2.5

    View Slide

  6. Lau Taarnskov - twitter: @LauT
    iex(1)> 5/2
    2.5
    iex(2)> 5/"Orlando"
    ** (ArithmeticError) bad
    argument in arithmetic
    expression
    :erlang./(5, "Orlando")

    View Slide

  7. Lau Taarnskov - twitter: @LauT
    We want errors instead
    of non-sensical results

    View Slide

  8. Lau Taarnskov - twitter: @LauT
    Explicit data

    View Slide

  9. Lau Taarnskov - twitter: @LauT

    View Slide

  10. Lau Taarnskov - twitter: @LauT
    Mars Climate Orbiter
    Mission cost: $327.6 million
    Mission failure
    after a 286 day journey to Mars

    View Slide

  11. Lau Taarnskov - twitter: @LauT
    Newton-seconds? Oh,
    we used pound seconds.

    View Slide

  12. Lau Taarnskov - twitter: @LauT
    5, 6, 3, 9, 4, 5…

    View Slide

  13. Lau Taarnskov - twitter: @LauT
    {5, :lbs_s}, {6, :lbs_s},
    {3, :lbs_s}, {9, :lbs_s},
    {4, :lbs_s}, {5, :lbs_s}…

    View Slide

  14. Lau Taarnskov - twitter: @LauT
    %ThrusterData{amount: 5, unit: :lbs_s},
    %ThrusterData{amount: 6, unit: :lbs_s},
    %ThrusterData{amount: 3, unit: :lbs_s},

    View Slide

  15. Lau Taarnskov - twitter: @LauT
    def process_thruster_data(%{amount: amount, unit: :n_s}) do
    # ...
    end
    ** (FunctionClauseError) no function clause matching in
    ThrustProcessor.process_thruster_data/1
    thruster.ex:12:
    ThrustProcessor.process_thruster_data(%ThrusterData{amou
    nt: 3, unit: :lbs_s})
    thruster.ex:17: (file)
    (elixir) lib/code.ex:363: Code.require_file/2

    View Slide

  16. Lau Taarnskov - twitter: @LauT
    Different units of time
    and date

    View Slide

  17. Lau Taarnskov - twitter: @LauT
    2016
    2016 September
    2016 September 2nd
    2016 September 2nd at 14:01:03
    2016-09-02 at 14:01:03 in New York
    14:01
    14:01:03
    14:01:03.9472
    ….

    View Slide

  18. Lau Taarnskov - twitter: @LauT
    One type to
    rule them all?

    View Slide

  19. Lau Taarnskov - twitter: @LauT
    2016-09-02
    2016-09-02 00:00:00.000 UTC

    View Slide

  20. Lau Taarnskov - twitter: @LauT
    06:10
    2001-01-01 06:10:00.000 UTC

    View Slide

  21. Lau Taarnskov - twitter: @LauT
    2001-01-01 00:00:00.000
    2001-01-01 06:10:00.000 UTC

    View Slide

  22. Lau Taarnskov - twitter: @LauT
    6:10
    What year is that in?
    2001
    (!!!!!!!)

    View Slide

  23. Lau Taarnskov - twitter: @LauT
    2016-09-02
    At what hour and
    minute? 00:00
    (!!!)

    View Slide

  24. Lau Taarnskov - twitter: @LauT
    Year
    Year with month
    Year, month, day of month
    Hour
    Hour and minute
    Hour and minute and second

    View Slide

  25. Lau Taarnskov - twitter: @LauT
    The structs in the
    Calendar library

    View Slide

  26. Lau Taarnskov - twitter: @LauT
    Types in Calendar in 2014
    Calendar.Date
    Calendar.Time
    Calendar.NaiveDateTime
    Calendar.DateTime

    View Slide

  27. Lau Taarnskov - twitter: @LauT
    Date: year, month, day

    View Slide

  28. Lau Taarnskov - twitter: @LauT
    Time: hour, minute,
    second, microsecond

    View Slide

  29. Lau Taarnskov - twitter: @LauT
    NaiveDateTime: year,
    month, day, hour, minute,
    second, microsecond

    View Slide

  30. Lau Taarnskov - twitter: @LauT
    DateTime: year, month,
    day, hour, minute, second,
    microsecond, time zone,
    UTC offset, standard
    offset, zone abbreviation

    View Slide

  31. Lau Taarnskov - twitter: @LauT
    Local vs Naive

    View Slide

  32. Lau Taarnskov - twitter: @LauT
    JAVA 8
    Class LocalDate
    A date without a time-zone in the
    ISO-8601 calendar system, such
    as 2007-12-03.

    View Slide

  33. Lau Taarnskov - twitter: @LauT
    local |ˈlōk(ə)l|

    adjective
    belonging or relating to a
    particular area or
    neighborhood, typically
    exclusively so: researching local
    history | the local post office.

    View Slide

  34. Lau Taarnskov - twitter: @LauT

    View Slide

  35. Lau Taarnskov - twitter: @LauT
    ~N[1970-01-01 00:00:00] |> DateTime.to_unix
    ** (FunctionClauseError) no function clause
    matching in DateTime.to_unix/2
    (elixir) lib/calendar.ex:1078:
    DateTime.to_unix(~N[1970-01-01
    00:00:00], :seconds)

    View Slide

  36. Lau Taarnskov - twitter: @LauT
    The structs built into
    Elixir 1.3

    View Slide

  37. Lau Taarnskov - twitter: @LauT
    Types in Calendar in 2014 Types in Elixir 1.3 in 2016
    Calendar.Date Date
    Calendar.Time Time
    Calendar.NaiveDateTime NaiveDateTime
    Calendar.DateTime DateTime

    View Slide

  38. Lau Taarnskov - twitter: @LauT
    Sigils
    ~D[2016-09-02]
    ~T[14:15:00]
    ~N[2016-09-02 14:15:00]

    View Slide

  39. Lau Taarnskov - twitter: @LauT
    %DateTime{calendar:
    Calendar.ISO, day: 1, hour:
    0, microsecond: {0, 0}, …

    View Slide

  40. Lau Taarnskov - twitter: @LauT
    %DateTime{calendar:
    Calendar.ISO, day: 1, hour:
    0, microsecond: {0, 0}, …

    View Slide

  41. Lau Taarnskov - twitter: @LauT
    "2016-09-02 14:15:00.1234” |>
    NaiveDateTime.from_iso8601!
    ~N[2016-09-02 14:15:00.1234]
    "2016-09-02 14:15:00.1” |>
    NaiveDateTime.from_iso8601!
    ~N[2016-09-02 14:15:00.1]
    Significant fractional seconds

    View Slide

  42. Lau Taarnskov - twitter: @LauT
    "2016-09-02 14:15:00.1234” |>
    NaiveDateTime.from_iso8601! |> Map.get(:microsecond)
    {123400, 4}
    "2016-09-02 14:15:00.10” |>
    NaiveDateTime.from_iso8601! |> Map.get(:microsecond)
    {100000, 2}
    "2016-09-02 14:15:00” |> NaiveDateTime.from_iso8601!
    |> Map.get(:microsecond)
    {0, 0}
    Significant fractional seconds

    View Slide

  43. Lau Taarnskov - twitter: @LauT
    Time zones and more
    functionality with the
    Calendar library

    View Slide

  44. Lau Taarnskov - twitter: @LauT
    The Calendar library

    View Slide

  45. Lau Taarnskov - twitter: @LauT
    ~N[1970-01-01 00:00:00]
    |> Calendar.NaiveDateTime.to_date_time_utc
    |> DateTime.to_unix
    0

    View Slide

  46. Lau Taarnskov - twitter: @LauT
    DateTime.from_unix!(1472836167)
    %DateTime{calendar: Calendar.ISO, day: 2,
    hour: 17, microsecond: {0, 0}, minute: 9,
    month: 9, second: 27, std_offset: 0,
    time_zone: "Etc/UTC",
    utc_offset: 0, year: 2016, zone_abbr: "UTC"}

    View Slide

  47. Lau Taarnskov - twitter: @LauT
    DateTime.from_unix!(1472836167)
    |> Calendar.DateTime.shift_zone!("America/New_York")
    %DateTime{calendar: Calendar.ISO, day: 2, hour: 13,
    microsecond: {0, 0}, minute: 9, month: 9, second: 27,
    std_offset: 3600,
    time_zone: "America/New_York", utc_offset: -18000,
    year: 2016, zone_abbr: "EDT"}

    View Slide

  48. Lau Taarnskov - twitter: @LauT
    DateTime.from_unix!(1472836167)
    |> Calendar.DateTime.shift_zone(“America/New_York”)
    |> DateTime.to_iso8601
    "2016-09-02T13:09:27-04:00"

    View Slide

  49. Lau Taarnskov - twitter: @LauT
    DateTime.from_unix(1472836167)
    |> Calendar.DateTime.shift_zone!(“America/New_York”)
    |> Calendar.Strftime.strftime!("%Y %B %d, %H:%M:%S %Z")
    "2016 September 02, 13:09:27 EDT"

    View Slide

  50. Lau Taarnskov - twitter: @LauT
    ~D[2016-09-02]
    |> Calendar.Date.friday?
    true

    View Slide

  51. Lau Taarnskov - twitter: @LauT
    ~D[2016-09-02]
    |> Calendar.Date.before?
    (~D[2016-09-03])
    true

    View Slide

  52. Lau Taarnskov - twitter: @LauT
    ~D[2016-09-02]
    |>Calendar.Date.next_day!
    ~D[2016-09-03]

    View Slide

  53. Lau Taarnskov - twitter: @LauT
    Calendar.Date.today(“Amer
    ica/New_York")
    |> Calendar.Date.next_day!
    ~D[2016-09-03]

    View Slide

  54. Lau Taarnskov - twitter: @LauT
    ~D[2016-09-02]
    |> Calendar.Date.add!(7)
    |> Date.to_iso8601
    "2016-09-09"

    View Slide

  55. Lau Taarnskov - twitter: @LauT
    Getting the time zone
    of a user

    View Slide

  56. Lau Taarnskov - twitter: @LauT
    Persistence in Ecto

    View Slide

  57. Lau Taarnskov - twitter: @LauT
    The Calecto library

    View Slide

  58. Lau Taarnskov - twitter: @LauT
    You want to select a
    type that fits the data

    View Slide

  59. Lau Taarnskov - twitter: @LauT
    Thank you

    View Slide

  60. Lau Taarnskov - twitter: @LauT
    Questions

    View Slide