elixir-lang / elixir

Elixir is a dynamic, functional language for building scalable and maintainable applications
https://elixir-lang.org/
Apache License 2.0
24.28k stars 3.34k forks source link

Rename NaiveDateTime to LocalDateTime #4679

Closed josevalim closed 8 years ago

josevalim commented 8 years ago

While implementing NaiveDateTime.from_iso8601/1 I have realized that the discussion between discarding the timezone information or computing the offset or discarding the offset is tricky because NaiveDateTime is not well defined.

Given the work on JodaTime and Java8, it may be more reasonable to call it LocalDateTime. With such, it is expected that the offset will be discarded because we are storing the local datetime information. It may also fit better the standard library if we decide to include OffsetDateTime in the future.

The last question is: if we migrate NaiveDateTime to LocalDateTime, should we also rename Date and Time to LocalDate and LocalTime? That may be required given that LocalTime will also discard any attached timezone information.

/cc @lau @bitwalker

josevalim commented 8 years ago

It may also be worth considering renaming DateTime to ZonedDateTime. Altogether:

Date -> LocalDate
Time -> LocalTime
NaiveDateTime -> LocalDateTime
DateTime -> ZonedDateTime
danhper commented 8 years ago

DateTime -> ZonedDateTime

I think adding the Local prefix for structures without a timezone is a good idea, but I think DateTime would be less verbose and easy enough to understand.

It is probably the module which will be the most used, so I would rather not make the name too long.

josevalim commented 8 years ago

Here is another reason why I believe we should at least convert NaiveDateTime to LocalDateTime:

  @doc """
  Converts a DateTime into a NaiveDateTime.

  Because NaiveDateTime does not hold timezone information,
  any timezone related data will be lost during the conversion.

  ## Examples

      iex> dt = %DateTime{year: 2000, month: 2, day: 29,
      ...>                hour: 23, minute: 0, second: 7, microsecond: 0,
      ...>                utc_offset: 3600, std_offset: 3600, time_zone: "Europe/Warsaw"}
      iex> DateTime.to_naive(dt)
      ~N[2000-02-29 23:00:07]

  """
  def to_naive(%DateTime{year: year, month: month, day: day, calendar: calendar,
                         hour: hour, minute: minute, second: second, microsecond: microsecond}) do
    %NaiveDateTime{year: year, month: month, day: day, calendar: calendar,
                   hour: hour, minute: minute, second: second, microsecond: microsecond}
  end

to_local makes much more sense as a conversion and as an understanding of why the timezone information is not carried over.

lexmag commented 8 years ago

To me NaiveDateTime seems more suitable name for that kind of data: I expect that it just doesn't provide timezone, I'm responsible for applying that meaning on application level and it can simply be not the same as my "local" timezone. Looking at LocalDateTime I'm wondering to which timezone it's local, this name makes me think that this data structure may provide some timezone information, and having to_local function increases confusion (in contrast, to_naive – I instantly see that timezone will be dropped). :bowtie:

lau commented 8 years ago

Here is a definition of local:

local |ˈlōk(ə)l| adjective belonging or relating to a particular area or neighborhood, typically exclusively so: researching local history | the local post office.

A good example of a "local" datetime is if for instance you get a datetime belonging to a particula area. Let us say "America/Montevideo". We have a struct that can do that, which is called DateTime 😄 But of course we can also use DateTime to represent UTC. UTC is not local.

Here are some antonyms for the word local: "broad, unrestricted". Which of the datetime structs is the most broad and unrestricted of the structs we have today? I would say NaiveDateTime. It could be a "local" datetime - that is a date belonging to a certain area. Or it could be UTC. It is unrestricted - not restricted by DST for instance. So NaiveDateTime is less local than DateTime. It does not belong to any locality, it is void of locality.

The thing about NaiveDateTime, what makes it different is that is does not have any information about locality nor UTC offset. This does not mean that it cannot represent a "local" datetime - it just means that it does not "know" about locality. That is why it is naive. It can represent either UTC or a "local" datetime, but in a naive way, where we don't know if it is UTC or local. And if it is local we don't know which locality it is.

Adding "local" says nothing meaningful about the difference between the two. The same goes for Date and Time. There is nothing particular local about them. Again they are kind of more "unrestricted" or "broad" than they are local. The date 2016-05-24 does not belong exclusively to a certain place.

The word naive is also used by Python for datetimes without UTC offset information. (But please let us not copy everything about how Python handles time).

I don't think we have to cargo cult other projects only because they are old and big like Java. Old and big projects brought us "brilliant" ideas like saving only 2 digits of the year. We can think for ourselves. Elixir has Phoenix with CRDTs for presence. As far as I know it was not copied from Java. Elixir has automatic up to date timezone information. Java does not. At the same time it makes sense to study what other people have done. And understand the reasons why. But we don't have to just copy everyone else.

josevalim commented 8 years ago

I don't think we have to cargo cult other projects only because they are old and big like Java. Old and big projects brought us "brilliant" ideas like saving only 2 digits of the year. We can think for ourselves.

That goes without saying. The reason I brought the local API is because it personally made more sense to me. It is important to bring such discussions without being accused of cargo-culting one API or another (specially given the Java API is quite new). :)

josevalim commented 8 years ago

Adding "local" says nothing meaningful about the difference between the two. The same goes for Date and Time. There is nothing particular local about them. Again they are kind of more "unrestricted" or "broad" than they are local. The date 2016-05-24 does not belong exclusively to a certain place.

This is a very good argument. Let's keep things as is. :heart:

lau commented 8 years ago

I sincerely apologize. I didn't consider the choice of words (ironic in a way isn't it 😉 ) sufficiently before posting that and writing about cargo culting. It might seem like a small thing to some, but I am glad you pointed it out, because we should discuss these things in a proper manner.

josevalim commented 8 years ago

Thank you @lau! :heart: