Attn: clj-time users - possible breaking change being considered!

79 views
Skip to first unread message

Sean Corfield

unread,
Feb 5, 2012, 7:31:45 PM2/5/12
to clo...@googlegroups.com
Avi Flax recently pointed out that (formatter "fmtstr") creates a
formatter in UTC whereas the underlying Joda Time library uses the
default timezone when you do DateTimeFormat.forPattern():

https://github.com/seancorfield/clj-time/issues/8

Given that a two-argument version exists to specify a timezone, so you
can say (formatter "fmtstr" utc) - utc coming from clj-time.core -
he's right that this is probably odd / undesirable... and there's no
easy / obvious way to create a formatter with the default timezone,
without dropping down to the underlying Java.

I'm considering changing (formatter "fmtstr") to mean just
(DateTimeFormat/forPattern "fmtstr") and bumping the version to 0.4.0
since this is potentially a breaking change but I wanted to get a
sense of whether anyone cares / has a strong opinion?
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Avi Flax

unread,
Feb 5, 2012, 8:23:12 PM2/5/12
to Clojure
On Feb 5, 7:31 pm, Sean Corfield <seancorfi...@gmail.com> wrote:
> and there's no
> easy / obvious way to create a formatter with the default timezone,
> without dropping down to the underlying Java.

Not that I want to weaken my own case, but isn’t there?

What about: (formatter "fmtstr" (default-time-zone)) ?

That said, I still support/request the described change.

Thanks!
Avi

Sean Corfield

unread,
Feb 6, 2012, 2:09:17 PM2/6/12
to clo...@googlegroups.com
On Sun, Feb 5, 2012 at 5:23 PM, Avi Flax <avi...@gmail.com> wrote:
> What about: (formatter "fmtstr" (default-time-zone)) ?

Ah yes, but if that's the normal desired behavior that's an ugly
default compared to (formatter "fmtstr")...

Also worth noting is that Avi pointed out that (now),
(today-at-midnight), (epoch) etc all use UTC instead of the default
time zone so this is a broader philosophical point of whether clj-time
should continue to use UTC as its default or your default time zone. I
tend to have all my servers set to UTC and do everything in UTC (and
then convert for input / output into the local user's timezone) so I'm
perfectly happy with clj-time as it stands. This is more about whether
the majority of users would prefer the current UTC behavior or whether
it would be more convenient to use the (local) default time zone?

Currently folks would need (to-time-zone (now) (default-time-zone))
and similar calls. If the behavior was changed, folks who wanted UTC
would need (to-time-zone (now) utc) - although for many of these calls
I'd probably add an optional timezone argument to support (now utc).
Hmm, that might be worthwhile anyway to allow (now
(default-time-zone))...

Cedric Greevey

unread,
Feb 6, 2012, 2:17:08 PM2/6/12
to clo...@googlegroups.com
On Mon, Feb 6, 2012 at 2:09 PM, Sean Corfield <seanco...@gmail.com> wrote:
> Also worth noting is that Avi pointed out that (now),
> (today-at-midnight), (epoch) etc all use UTC instead of the default
> time zone so this is a broader philosophical point of whether clj-time
> should continue to use UTC as its default or your default time zone. I
> tend to have all my servers set to UTC and do everything in UTC (and
> then convert for input / output into the local user's timezone) so I'm
> perfectly happy with clj-time as it stands. This is more about whether
> the majority of users would prefer the current UTC behavior or whether
> it would be more convenient to use the (local) default time zone?

Maybe there should be a *switch* for that ...

Sean Corfield

unread,
Feb 6, 2012, 2:21:28 PM2/6/12
to clo...@googlegroups.com
On Mon, Feb 6, 2012 at 11:17 AM, Cedric Greevey <cgre...@gmail.com> wrote:
> Maybe there should be a *switch* for that ...

A good suggestion as a possible compromise to allow both defaults.

Right now, my default position is to not change anything unless enough
folks indicate a desire for default time zone per Avi's suggestion.

Caspar Hasenclever

unread,
Feb 6, 2012, 3:43:56 PM2/6/12
to Clojure
As Avi points out on the github issue discussion, this change would
best be done throughout, i.e. wherever a DateTime instance is created,
otherwise one would end up with surprising behaviour (default of UTC
in
date-time, default of JVM default time zone in formatter).

That being said, I would argue for keeping UTC as the time zone when
creating
DateTime instances (including via formatter), unless another time zone
is explicitly
requested.

Although I appreciate the argument for following Joda time in using
the JVM default
time zone, I think clj-time would benefit from imposing a bit of
purity in this case.
Using the JVM defaults for such settings always allows some
unpredictability to leak
into your code (default file encoding, anyone?).

In other words, the value of (date-time 1970 1 1) should not, in my
opinion, depend
on whether it is run on my machine or yours.

clj-time.core makes it's use of UTC clear in the documentation,
although a heads-up
regarding the departure from Joda time's behaviour in this regard
would probably help
prevent users tripping over the same issue Avi had.

On the other hand, I sympathize with Avi that it can be somewhat
inconvenient to specify
times in non-UTC. from-time-zone and to-time-zone are not the most
succinct way
of dealing with this, in my opinion. I admit I quickly ended up
writing a helper function
to produce DateTime instances for explicitly named time zones. Ideally
I would like to be able
to pass the time zone to date-time et al. The way date-time uses
multiple arities currently
precludes this, but my preferred way would be to say, e.g.

(date-time :utc 1970 1 1 10 30)
=> #<DateTime 1970-01-01T10:30:00.000Z>

or:
(date-time :europe-barcelona 1970 1 1 10 30)
=> #<DateTime 1970-01-01T10:30:00.000+01:00>

or indeed:
(date-time (default-time-zone) 1970 1 1 10 30)
=> #<DateTime 1970-01-01T10:30:00.000+01:00> ; YMMV

and to have UTC as a fallback when no time zone is specified:
(date-time 1970 1 1 10 30)
=> #<DateTime 1970-01-01T10:30:00.000Z>

I personally think it is helpful to make the time zone explicit by
either passing it or accecpting the constant default of UTC. Dealing
with dates and time zones is a lot like dealing with bytes and
encodings.
While cultural, operating system or run time defaults may lull you
into treating
the time zone/encoding as somehow supplementary and non-essential,
you don't really know the value unless you define both aspects of the
data
(and you will get bitten sooner or later).

Ok, I'll stop before I go completely OT.

Regards,

Caspar

Sean Corfield

unread,
Feb 6, 2012, 6:52:25 PM2/6/12
to clo...@googlegroups.com
Good feedback Casper, thanx!

Cedric Greevey

unread,
Feb 6, 2012, 8:31:39 PM2/6/12
to clo...@googlegroups.com
On Mon, Feb 6, 2012 at 3:43 PM, Caspar Hasenclever
<caspar.ha...@googlemail.com> wrote:
> In other words, the value of (date-time 1970 1 1) should not, in my
> opinion, depend
> on whether it is run on my machine or yours.

This is an important, valid point.

Probably I should amend my earlier suggestion from a switch that uses
either UTC or the OS timezone setting to, instead, that there should
be a *default-time-zone* Var that is, by default, UTC, but which you
can set!, alter-var-root!, or dynamically bind to something else
before/when calling into the lib if you want some other default in the
no-timezone-argument versions of the functions in the lib.

Reply all
Reply to author
Forward
0 new messages