This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-10
Channels
- # announcements (4)
- # beginners (116)
- # boot (4)
- # calva (63)
- # cider (8)
- # clara (20)
- # cljdoc (10)
- # cljsrn (69)
- # clojure (115)
- # clojure-austin (1)
- # clojure-dev (4)
- # clojure-finland (1)
- # clojure-italy (3)
- # clojure-nl (6)
- # clojure-russia (10)
- # clojure-uk (84)
- # clojurescript (28)
- # cursive (14)
- # data-science (1)
- # datascript (1)
- # datomic (11)
- # duct (3)
- # emacs (13)
- # figwheel-main (11)
- # fulcro (4)
- # graphql (6)
- # jackdaw (2)
- # jobs (23)
- # jobs-rus (1)
- # kaocha (11)
- # lein-figwheel (13)
- # leiningen (55)
- # luminus (14)
- # lumo (22)
- # off-topic (121)
- # pathom (19)
- # re-frame (6)
- # reagent (3)
- # reitit (22)
- # remote-jobs (10)
- # ring-swagger (1)
- # shadow-cljs (67)
- # slack-help (5)
- # spacemacs (1)
- # sql (18)
- # vim (28)
- # yada (2)
Hi, How can I convert an instance of java.sql.Timestamp
to a zoned date?
โ-
I am using clojure.java-time
user=> (java.sql.Timestamp/from (jt/instant))
#inst "2019-04-10T06:16:24.131160000-00:00"
user=> (-> *1 (jt/zoned-date-time "UTC"))
#object[java.time.ZonedDateTime 0x1805383 "2019-04-10T06:16:24.131160Z[UTC]"]
user=>
@ho0man I was missing the zone ID before. The above should work with whatever timezone you want to specify.
@seancorfield thanks a lot.
I have another question though ... now that I have the ZonesDateTime ... how can I extract the date (is using jt/local-date
correct to extract just the date)
I am trying to select all records related to some event that occurred today
there is also the ability to get the current zone id: (jt/zone-id)
Just call local-date
on it...
user=> (java.sql.Timestamp/from (jt/instant))
#inst "2019-04-10T06:22:53.533774000-00:00"
user=> (type *1)
java.sql.Timestamp
user=> (-> *2 (jt/zoned-date-time "America/New_York"))
#object[java.time.ZonedDateTime 0x106cd9c8 "2019-04-10T02:22:53.533774-04:00[America/New_York]"]
user=> (-> *1 (jt/local-date))
#object[java.time.LocalDate 0x77ce88c4 "2019-04-10"]
user=>
To be honest tho', if you're doing this in a database, I'd recommend keeping everything on UTC and sticking with instants.
I read a blog the other day why this is not always enough, but I cannot find it anymore ๐ข
Ah there we go: https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/
Thanks a lot, @UDF11HLKC
but most likely, storing just UTC, or UTC + Zone is enough. Only in particular cases it is not
Yeah, if you need to store local event times because you need to operate on and display local event times, then using zoned or offset makes sense. That's not been the case for any app I've ever worked on, except for rare cases of location-specific events (but even that can be handled by UTC and zone in most cases). Timezones are hard is the bottom line here!
yeah sorry, I am just providing a particular counter example ^^!
Oh, no, definitely worth mentioning! This stuff is nasty. I hate having to deal with timezones!
We're lucky that for the most part we only care about relative actions: when was someone last online relative to you, when did they like you, when did you purchase your 30 day membership etc.
We don't need to care about someone in France attending an event in London that starts on a certain date at a certain local time ๐ I have enough of that trying to deal with calling my mother every Monday at 5pm her time (I'm in California)!
haha yeah, having the same timezone in most of europe is quite convenient
I live in a country with four timezones, and not all parts of every state observe DST ๐
(my state just voted to allow the legislature to petition the federal government to stop observing DST -- yay!)
yeah the EU is going to drop DST, but its up to its members to choose what tz to keep. The netherlands however, already is in an ill fitting timezone, so keeping DST all year is a terrible idea that probably will happen
or โ we have a different timezone than germany has, which is also a terrible idea. There are no winners in this timezone debate ๐
this API is growing on me
Avoid local date/times altogther.
Truncate a timestamp to a date, via an instant
user=> (java.sql.Timestamp/from (jt/instant))
#inst "2019-04-10T06:28:37.100373000-00:00"
user=> (-> *1 (jt/instant) (jt/truncate-to :days))
#object[java.time.Instant 0x37fef327 "2019-04-10T00:00:00Z"]
user=>
doesnโt that keep zone?
(well not with instantโs, but with zoned-date-times)
ah yeah, sorry!
Avoid zoned date times, stay in UTC everywhere. Seriously.
We have all our servers set to UTC and our database set to UTC. We do everything in UTC on the server, and only convert to local date/time for display. It's the only sane option.
(we have a global 24x7 customer base)
I agree, I just wasnโt very awake just yet
Unless you want to store โlocalโ dates โ i.e., this event will start when the clocks show 5:00pm at that specific city. Then a local date is more appropriate, I believe. I fuzzily remember reading about how in some cases UTC is not the best choice, and I think this use case is one of them.
@orestis Yes, see the long thread from about half an hour ago ๐
Haha ๐ I recall someone mentioning that if you really want to deal with relative events, look into the iCal format RFC and just do that.
I imagine doing
(def global-conf {})
;; code that uses global-conf
(def -main [& args]
(def global-conf (my-conf-builder-function args))
;; calling code
)
is not the clojure way?(I'm using compojure and I need the conf to be passed to functions handling the routes, that's why I resorted to this)
Never put a def
inside another function. Not idiomatic at all.
With Ring/Compojure, you can use middleware to add configuration to the req
uest hash map.
In your -main
, when you build the "application", wrap the handler in a middleware closure that includes your built configuration and assoc
s it into the req
uest so that handlers can read it from that.
(def global-conf (atom {}))
(defn my-handler [...]
(let [conf @global-conf]
...))
(defn -main [& args}
(reset! global-conf (my-conf-build-function args)
...)
I'm trying to avoid atoms because it's only modified at startup (config file with default values vs command line options) but I think I found how to do it by digging into sente's source
Hi all! Q q about testing conventions. Iโve got a utils
namespace with some smaller funcs I find handy. Should I use with-test
to test them? Or should I use deftest
in a tests.utils
namespace? Which is more common / idiomatic?
@jamie962 I would do the latter, but only because I never really reach for with-test
.
e.g. a random datapoint: GitHub search returns 1k code results for with-test
, but 104k code results for deftest
Thatโs interesting โ I guess the standard is to separate out tests from implementation. But for pure functions (with no tricky mocking or whatever) I see no reason why they couldnโt be coupled. Tests, when well written, are excellent documentation!
New to Clojure, looking for resources on how to use the REPL in the right way. Do you have any recommendations ?
if you are coming from Vim, Spacemacs combines Vim with Emacs. So it helps you learn emacs in steps.
You might want to check this out: https://www.youtube.com/watch?v=Qx0-pViyIDU
You can also get some hits on the search phrase โrepl-driven developmentโ
@manutter51 Thanks !
@feuillen.gauthier thereโs a great guide at https://clojure.org/guides/repl/introduction
https://purelyfunctional.tv/courses/repl-driven-development-in-clojure/ by @ericnormand is very nice too (although require a subscription to see the full series [and I haven't actually watched the full one, just bunch of snippets])
I am planning to use Compojure for a new project, which version of Java should I go with 8 or 11?
Unless you have some reason to do otherwise Iโd use openjdk Java 11
if you get WARNING: Reflective Access
stuff in your log, I'd talk to the maintainers of the projects to make sure they're not doing anything naughty
Newb question: Can someone please succinctly explain the difference b/w the following: Java, JVM, JDK, JRE. And/or point me to resources I should study to learn more. Also, what's open in openjdk?
Java is the programming language, and informally the associated runtime. This term probably depends on context
JVM is the runtime. It runs your application from .class
files and .jar
s full of them. It manages memory, loads code, optimizes the code dynamically into machine code. Clojure compiles to .class
files and dynamically loads it into the JVM.
The JDK is the "Java Development Kit". It includes the java language compiler, the JVM, and a ton of tooling.
The JRE is the "java runtime environment" -- just the JVM typically. You'd distribute your application to end users with the JRE if it's pre-compiled, otherwise you'd tell users to install the JDK.
the open in OpenJDK is a reference to the fact that the source code is public under the GPL license
Got it. Thanks a lot Ghadi!
I just remembered your talk is in my watch later. Java made somewhat simple if I remember correctly. I'll go watch it. Thanks for the talk too!!
So when I hear about Java being very stable, the JVM promises to run any old dusty JAR (artifact) but the java language may break and not allow dusty code to create the artifact...
And if so, Clojure's promise of compatibility only reaches Clojure's constructs. If I user some Java thing with interop, and Java decides to break it, I may be broken
Java breaks things less frequently than Clojure
you can take Clojure 1.0 stuff and run it on Java 11 just fine
the key thing as of Java 11 is that if you want to use the Oracle version for commercial use, you must purchase a license from Oracle, which was not previously true
but because Java is GPL and openjdk exists, you can use the openjdk version for free
that being said, Oracle open sourced all of the previously closed tools during the Java 11 release
and there are now multiple vendors helping to provide support and bug fixes for this and older releases
Amazon Corretto 8/11 is a distribution of Java 8/11 that has longevity and security patching, if you're into that
I'm aware of only two things that may be considered as Clojure breaking something. Numerics at around 1.3, and core async buffer semantics (subtly because if a buffer isn't full it must accept any number of things) when transducers were introduced.
Did Clojure break more stuff? I know a bunch of deprecations exist.
but there have been a handful of other breaking things throughout the years, but mostly not major things
we also don't make the same level of binary compatibility promises that Java does
if you happen to AOT your code for example
although we do try to be very careful in any changes that might break aot-compiled code
and I think in general, those kind of breaks have also been rare (I can't actually think of one off the top of my head)
All I can think of are, as you said, bendings ๐
Any non interop Clojure (pure Clojure, if you will) still compiles and runs fine.
part of that is Clojure's intentional under-specification of the core api to allow us some room for growth :)
so we can add arities or polymorphically handle a broader set of things
and we've done a lot of that
I loved it when so many fns got transducer returning arities.
yeah, transducers was purely additive from an api perspective
It was awesome that all those extra arities weren't used up for weak reasons like syntactic sugar.
Which accommodated transducers beautifully.
Is there a shorter way to say this: (fn [a b] (= (:id a) (:id b)))
? It almost looks like (comp = :id)
but not quite.
Anytime I write code that works with exactly 2 things, I view it with suspicion
Writing it for N, or writing it for 1 and using the seq lib are usually better
this might be what Alex is proposing (->> some-seq (map :id) (apply =))
(fn [& xs] (->> xs (map :id) (apply =)))
in fn form, but yep
In some situations I like that, but in my current code I feel like want to say "compare these two things by ID", and if I write the map+apply it makes the code harder to read.
you can write (fn [{id-a :id} {id-b :id}] (= id-a id-b))
if you really want to
but I personally donโt think it becomes much clearer
you could probably generify this pattern to something like
(defn =-by [pred & xs]
(->> xs (map pred) (apply =)))