Fork me on GitHub
#beginners
<
2019-04-10
>
Ho0man05:04:47

Hi, How can I convert an instance of java.sql.Timestamp to a zoned date? โ€”- I am using clojure.java-time

seancorfield06:04:40

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=>     

seancorfield06:04:19

@ho0man I was missing the zone ID before. The above should work with whatever timezone you want to specify.

Ho0man06:04:42

@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

Lennart Buit06:04:00

there is also the ability to get the current zone id: (jt/zone-id)

seancorfield06:04:27

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=>  

seancorfield06:04:14

To be honest tho', if you're doing this in a database, I'd recommend keeping everything on UTC and sticking with instants.

Ho0man06:04:13

It is stored as UTC timestamp in the DB, may it still cause any problem?

Lennart Buit06:04:27

I read a blog the other day why this is not always enough, but I cannot find it anymore ๐Ÿ˜ข

Lennart Buit06:04:02

but most likely, storing just UTC, or UTC + Zone is enough. Only in particular cases it is not

seancorfield06:04:07

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!

Lennart Buit06:04:31

yeah sorry, I am just providing a particular counter example ^^!

seancorfield06:04:19

Oh, no, definitely worth mentioning! This stuff is nasty. I hate having to deal with timezones!

seancorfield06:04:09

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.

seancorfield06:04:12

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)!

Lennart Buit06:04:48

haha yeah, having the same timezone in most of europe is quite convenient

seancorfield06:04:24

I live in a country with four timezones, and not all parts of every state observe DST ๐Ÿ™‚

seancorfield06:04:32

(my state just voted to allow the legislature to petition the federal government to stop observing DST -- yay!)

Lennart Buit06:04:14

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

Lennart Buit06:04:54

or โ€” we have a different timezone than germany has, which is also a terrible idea. There are no winners in this timezone debate ๐Ÿ˜›

Lennart Buit06:04:30

this API is growing on me

seancorfield06:04:32

Avoid local date/times altogther.

seancorfield06:04:19

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=>        

๐Ÿ‘ 4
Lennart Buit06:04:02

doesnโ€™t that keep zone?

Lennart Buit06:04:17

(well not with instantโ€™s, but with zoned-date-times)

Lennart Buit06:04:26

ah yeah, sorry!

seancorfield06:04:33

Avoid zoned date times, stay in UTC everywhere. Seriously.

seancorfield06:04:07

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.

๐Ÿ‘ 4
seancorfield06:04:20

(we have a global 24x7 customer base)

Lennart Buit06:04:21

I agree, I just wasnโ€™t very awake just yet

orestis06:04:43

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.

seancorfield07:04:30

@orestis Yes, see the long thread from about half an hour ago ๐Ÿ™‚

orestis07:04:07

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.

Nazral07:04:04

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?

Nazral07:04:58

(I'm using compojure and I need the conf to be passed to functions handling the routes, that's why I resorted to this)

seancorfield07:04:25

Never put a def inside another function. Not idiomatic at all.

seancorfield07:04:03

With Ring/Compojure, you can use middleware to add configuration to the request hash map.

seancorfield07:04:27

In your -main, when you build the "application", wrap the handler in a middleware closure that includes your built configuration and assocs it into the request so that handlers can read it from that.

Nazral07:04:33

I don't think this applies to the websocket requests and event handling of sente

orestis08:04:49

If you really want global mutable state, then you should use an atom

orestis08:04:46

(def global-conf (atom {}))

(defn my-handler [...]
 (let [conf @global-conf]
  ...))

(defn -main [& args}
  (reset! global-conf (my-conf-build-function args)
  ...)

Nazral08:04:26

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

Jamie Rumbelow09:04:20

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?

Vikram10:04:34

Hi all, can anyone tell me how to start learning clojure openscad. Thanks

pithyless10:04:28

@jamie962 I would do the latter, but only because I never really reach for with-test.

pithyless10:04:54

But this raises an interesting question - when do people reach for with-test?

pithyless10:04:53

e.g. a random datapoint: GitHub search returns 1k code results for with-test, but 104k code results for deftest

Jamie Rumbelow08:04:47

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!

Gauthier Feuillen14:04:17

New to Clojure, looking for resources on how to use the REPL in the right way. Do you have any recommendations ?

hipster coder17:04:07

if you are coming from Vim, Spacemacs combines Vim with Emacs. So it helps you learn emacs in steps.

orestis19:04:00

Have you read the REPL guide on the CLojure website?

manutter5114:04:25

You can also get some hits on the search phrase โ€œrepl-driven developmentโ€

victorb16:04:43

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])

adam17:04:04

I am planning to use Compojure for a new project, which version of Java should I go with 8 or 11?

Alex Miller (Clojure team)18:04:39

Unless you have some reason to do otherwise Iโ€™d use openjdk Java 11

ghadi18:04:34

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

jaihindhreddy18:04:19

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?

ghadi18:04:31

.... I will try

ghadi18:04:25

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 .jars 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.

๐Ÿ‘ 8
๐Ÿ‘ 4
ghadi18:04:08

the open in OpenJDK is a reference to the fact that the source code is public under the GPL license

jaihindhreddy18:04:41

Got it. Thanks a lot Ghadi!

ghadi18:04:46

my pleasure

jaihindhreddy18:04:57

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!!

jaihindhreddy18:04:33

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...

Alex Miller (Clojure team)18:04:24

in general, that's rare.

๐Ÿ‘ 4
jaihindhreddy18:04:31

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

Alex Miller (Clojure team)18:04:50

Java breaks things less frequently than Clojure

Alex Miller (Clojure team)18:04:13

you can take Clojure 1.0 stuff and run it on Java 11 just fine

Alex Miller (Clojure team)18:04:55

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

Alex Miller (Clojure team)18:04:15

but because Java is GPL and openjdk exists, you can use the openjdk version for free

ghadi18:04:45

that being said, Oracle open sourced all of the previously closed tools during the Java 11 release

Alex Miller (Clojure team)18:04:46

and there are now multiple vendors helping to provide support and bug fixes for this and older releases

ghadi18:04:03

so you'd be paying oracle not for enhanced features, but enhanced support

๐Ÿ‘ 4
ghadi18:04:21

Amazon Corretto 8/11 is a distribution of Java 8/11 that has longevity and security patching, if you're into that

Alex Miller (Clojure team)18:04:09

(you should be into that :)

๐Ÿ™ƒ 4
jaihindhreddy18:04:28

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.

Alex Miller (Clojure team)18:04:00

well that one is more bending :)

โž• 4
jaihindhreddy18:04:05

Did Clojure break more stuff? I know a bunch of deprecations exist.

Alex Miller (Clojure team)18:04:20

but there have been a handful of other breaking things throughout the years, but mostly not major things

ghadi18:04:42

Clojure has a good track record in that dept

Alex Miller (Clojure team)18:04:01

we also don't make the same level of binary compatibility promises that Java does

Alex Miller (Clojure team)18:04:14

if you happen to AOT your code for example

ghadi18:04:21

I really want resultset-seq and bean to be removed from core... ยฏ\(ใƒ„)/ยฏ

โž• 4
Alex Miller (Clojure team)18:04:42

although we do try to be very careful in any changes that might break aot-compiled code

๐Ÿ‘ 4
Alex Miller (Clojure team)18:04:29

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)

jaihindhreddy18:04:13

All I can think of are, as you said, bendings ๐Ÿ™‚

jaihindhreddy18:04:55

Any non interop Clojure (pure Clojure, if you will) still compiles and runs fine.

Alex Miller (Clojure team)18:04:28

part of that is Clojure's intentional under-specification of the core api to allow us some room for growth :)

Alex Miller (Clojure team)18:04:49

so we can add arities or polymorphically handle a broader set of things

Alex Miller (Clojure team)18:04:57

and we've done a lot of that

jaihindhreddy18:04:15

I loved it when so many fns got transducer returning arities.

Alex Miller (Clojure team)18:04:37

yeah, transducers was purely additive from an api perspective

โž• 8
๐Ÿ’ฏ 8
jaihindhreddy18:04:59

It was awesome that all those extra arities weren't used up for weak reasons like syntactic sugar.

jaihindhreddy18:04:18

Which accommodated transducers beautifully.

Robert Nikander20:04:18

Is there a shorter way to say this: (fn [a b] (= (:id a) (:id b)))? It almost looks like (comp = :id) but not quite.

Frank Henard20:04:08

#(= (:id %1) (:id %2))?

๐Ÿ‘ 4
Alex Miller (Clojure team)20:04:17

You could map :id, then apply = for a variadic version

๐Ÿ‘ 8
Alex Miller (Clojure team)20:04:28

Anytime I write code that works with exactly 2 things, I view it with suspicion

Alex Miller (Clojure team)20:04:05

Writing it for N, or writing it for 1 and using the seq lib are usually better

Frank Henard20:04:31

this might be what Alex is proposing (->> some-seq (map :id) (apply =))

Alex Miller (Clojure team)20:04:36

(fn [& xs] (->> xs (map :id) (apply =)))

Robert Nikander20:04:51

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.

Lennart Buit20:04:44

you can write (fn [{id-a :id} {id-b :id}] (= id-a id-b)) if you really want to

Lennart Buit20:04:42

but I personally donโ€™t think it becomes much clearer

Alex Miller (Clojure team)21:04:14

you could probably generify this pattern to something like

(defn =-by [pred & xs]
  (->> xs (map pred) (apply =)))

Alex Miller (Clojure team)21:04:35

(=-by :id a b)

๐Ÿ‘ 4