Sorc96

Sorc96

Datetime input and time zone

I have been searching for a way to deal with datetime values coming from forms. The datetime-local input does not care about time zones, so the information is lost and casting to Ecto’s :utc_datetime assumes the value already is in UTC.

I think the front end should add the time zone instead of this being handled anywhere else (like a custom Ecto.Type), since it is the only place that knows the actual time zone of the user, but I have not been able to find a solution.

Is there a way to map the value of an input before the params get sent to the server? Should I just give up on datetime-local and use some kind of a custom input component? Is there an existing component for this? Or is there a completely different approach to this that I have not considered?

It has been driving me crazy for the last two days that I cannot get a basic form to work properly because of this, so any ideas will be very much welcome.

Most Liked

joshamb

joshamb

Whilst I don’t have an answer for you on how to embed the timezone in the form, I have an alternative idea (which you might already be aware of!)

In you app.js, you have the following:

let liveSocket = new LiveSocket("/live", Socket, {
  longPollFallbackMs: 2500,
  params: {_csrf_token: csrfToken}
})

You can add to the params the browser timezone, so

let liveSocket = new LiveSocket("/live", Socket, {
  longPollFallbackMs: 2500,
  params: {
    _csrf_token: csrfToken,
    timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
  }
})

Then in the LiveView, you can do this

Phoenix.LiveView.get_connect_params(socket)

This would then output

%{
  ...
  "timezone" => "XXX"
}

And then, using that, you could potentially jam it into your changeset…

def changeset(struct, params, timezone) do
  struct
  |> cast(params, [:date_time])
  |> update_change(:date_time, fn date_time -> 
    date_time && DateTime.new!(DateTime.to_date(date_time), DateTime.to_time(date_time), timezone)
  end)
end
garrison

garrison

The information is not lost so much as it was never gained. The datetime-local inputs explicitly don’t validate the user’s local timezone. It’s literally just a timezone-free datetime input, I have no idea what they were thinking naming it that. Elixir’s NaiveDateTime is a much less confusing name.

Anyway, why not just have a “select timezone” dropdown? That’s the solution recommended in the Mozilla docs. For extra usability you can set the default to the user’s local timezone (a reply above showed how to retrieve it).

Pass the timezone in as a virtual field and then perform the conversion in the changeset.

Where Next?

Popular in Questions Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: The documentation above suggests that while ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New

Other popular topics Top

AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39523 209
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52774 488
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement