Timex seems to work only in my Windows environment, is there something wrong with my syntax?

I am trying to get the local date and converting it to a ‘YYYY-MM’ format, and develop on both a windows and mac system. On the windows machine, the line of code I ended up with was:

Timex.format!(Timex.to_datetime(Timex.local), “{YYYY}-{0M}”)

and this produced the exact results I needed. However, when I pulled down on the Mac, ran my mix deps.get and ecto migration, trying to create a new date causes an “invalid_date” error, like this:

(ArgumentError) invalid_date
(timex) lib/format/datetime/formatter.ex:44: Timex.Format.DateTime.Formatter.lformat!/4

What am I missing? Any help appreciated!

Can you please share a full example of how you construct the date and try to format it on both machines and what versions of elixir, Erlang and Timex are installed on those machines respectively?

1 Like

Hey there! Both machines have: Elixir 1.4, Timex 3.0, and Erlang 20.2.

This is how the date is created/formated:

  def seed_starting_categories(user) do
    Repo.insert(
      Ecto.build_assoc(user, :categories, %Category{
          id: Ecto.UUID.generate(),
          name: "My First Category",
          date: Timex.format!(Timex.to_datetime(Timex.local), "{YYYY}-{0M}")
        })
    )
  end

Can you IO.inspect the result of Timex.local in both environments?

Timex.local/0 is documented to maybe return a Timex.AmbiguousDateTime.t() or an :error-tuple, which both are not understood by Timex.to_datetime, which itself will return an :error-tuple then and Timex.format! blows up.

@wakka_wakka have you made any progress? I’d like to learn more about this, and especially the reasons of this failure.

I tried to replicate something of that, on my Windows I can run the Timex.format!(Timex.to_datetime(Timex.local), "{YYYY}-{0M}") snippet, and got 2018-03 as result. Timex.local returned #DateTime<2018-03-08 17:46:57.333000-03:00 -03 America/Sao_Paulo>.

Then I switched to WSL (Ubuntu 16), I ran the same snippets on a clean lock file and got:

Timex.format!(Timex.to_datetime(Timex.local), "{YYYY}-{0M}")
** (ArgumentError) invalid_date
    (timex) lib/format/datetime/formatter.ex:44: Timex.Format.DateTime.Formatter.lformat!/4

Then I just used Timex.local and got:

{:error, {:unknown_timezone, "/etc/localtime"}}

Maybe some missing configuration about *nix timezones? That affects both OSX and Ubuntu (afaik)

Specs (both envs):

Elixir 1.6.2
Erlang 20.2
Timex 3.2.1

There was a bug report in Septembre '17 which was fixed then.

Releases since that fix are 3.1.25, 3.2.0 and 3.2.1.

Also it works for me (created something to test now to confirm or unconfirm the behaviour)… Versions as @joaoevangelista.

Also I’ll throw tzdata 0.5.16 into the mix (according to mix.lock). My system is an arch linux with 4.15.5 Kernel and tzdata 2018c timezone database. My local timezome is Europe/Berlin.

So it seems not to be a generic linux thing.

@joaoevangelista please file a bug at github.com/bitwalker/timex and provide as much info as you can, I am sure @bitwalker is eager to help.

@wakka_wakka please try to update Elixir and Timex first. If the problem persists with current versions, please join the ticket created by @joaoevangelistaor create your own if he hasn’t created one until then.

fwiw that works on my mac…

I searched about timezone issues in other softwares and seems you can rely on environment variables, my Windows’ Powershell gets the correct one, on WSL it didn’t find the variable that threads mentioned, I’ll try to set it up and run again the snippet

Gotcha!

TL;DR

Set TZ environment variable to the name of default timezone for example mine would be: export TZ='America/Sao_Paulo'

  • Is this a bug on Timex? I don’t think so
  • Maybe include some notes on it? Definitively.

After seeing the comment about the OSX that works, and having my Windows working too, I thought on look about where does a system stores its timezone, because when we set up Ubuntu, for example, it asks us where are we to set the time and formats.

I searched for issues regarding timezones on Unix and stubbed upon some posts and this R one where I saw the usage of the TZ env var. I went to Powershell and used the command to fetch the information, aka: [System.TimezoneInfo]::Local and returned the correct one, then I went to WSL and searched for TZ and there was nothing, I tried to set it to /usr/share/zoneinfo/Brazil/East and returned the error {:error, {:unknown_timezone, "/usr/share/zoneinfo/Brazil/East"}}.

So it tried using the ‘America/Sao_Paulo’ string on the TZ env var and worked as it does on Windows, returning #DateTime<2018-03-08 18:58:46.054746-03:00 -03 America/Sao_Paulo>

I have no TZ set:

$ env | grep TZ
$ echo $?
1

Instead, I have a file /etc/localtime which is simlinked to /usr/share/zoneinfo/Europe/Berlin. This file seems to be binary.

So Timex should be getting information from the file localtime links to or TZ

Aside from replacing the “smart quotes” in the above command, it
works on my Mac (10.12.6) with Elixir 1.6.2 and Timex 3.2.1.

What versions are you running?