Fork me on GitHub
#clojure-uk
<
2019-11-28
>
maleghast11:11:54

Morning All 🙂

maleghast11:11:57

Is that Gaelic?

mccraigmccraig12:11:41

it's a deep-south drawl written with a scandinavian alphabet 😬

dominicm12:11:35

Mccraigianlic

parrot 8
otfrom13:11:00

Madainn mhath

David13:11:05

Gaeilge na hAlba? Nó mílitrigh gaeilge éirinn?

otfrom15:11:11

I'm pretty sure you are making fun of my spelling now. 🙂

otfrom15:11:47

yes, to Scottish Gaelic

otfrom13:11:12

gonna sign up for the Gaelic duolingo course 🙂

otfrom13:11:24

I think it comes out on St Andrew's Day

Conor13:11:35

The weirdest thing about Scots Gaelic is that the fadas are the wrong way around

danielneal14:11:03

what is a fada?

Conor14:11:06

A diacritic mark indicating you should lengthen a vowel sound

maleghast15:11:04

Just bringing it all back to Clojure for a moment... If one is using Java8 Date / Time instead of legacy or Joda, and one were to define a date, thus:

(jt/local-date 2013 2)

maleghast15:11:29

Does anyone know how to get the last day of the month from the resulting date object..?

maleghast15:11:59

I tried:

(jt/as test-date :last-of-month)

maleghast15:11:06

but that's clearly not right...

maleghast15:11:31

(jt/as test-date :day-of-month)

maleghast15:11:21

because when you set year and month you default to first day of the month, but I would have thought I could extract the last day of the month from the object...

Ben Hammond15:11:09

(java-time/minus (java-time/local-date 2013 3) (java-time/days 1))

Ben Hammond15:11:16

would that be cheating?

maleghast15:11:47

@ben.hammond - no, that would not be cheating, I just had not thought of it!

👍 8
maleghast15:11:13

Plus it's a bit long-winded, I was hoping for some syntactic sugar, but overall, this will get the job done, so thanks 🙂

Ben Hammond15:11:44

there's a

public LocalDate withDayOfMonth(int dayOfMonth)

maleghast15:11:56

Of course it won't work for December, at least not as easily as I will have to take one day off the 1st of the January of the following year

Ben Hammond15:11:58

in java.time.LocalDate I note

maleghast15:11:42

Right, but I want the date object to return to me, programatically, the last day of the month in question. I know I could create the date with the last day, but I am looping over numbers and don't have a data structure of my own to manage the business rule(s) around the lengths of months, i.e. January has 31 days, but February has 28 except if the year is cleanly divisible by 4 in which case it has 29 days, etc.

dharrigan15:11:31

Don't forget about the 100 year and 400 year rule for leap years 🙂

maleghast15:11:36

So your solution above is great apart from the last trip around the loop as I can't create (java-time/local-date 2013 13)

maleghast15:11:58

@dharrigan..? Please enlighten me, I am afraid I know not of what you speak

dominicm15:11:24

Haha. Time.

paulspencerwilliams15:11:44

Thing to remember is everything we know about time is probably wrong.

maleghast15:11:50

@dharrigan - Thx, I had no clue about that 100 / 400 year rule - that's fascinating

maleghast15:11:50

@paulspencerwilliams - Thanks for that... I think 😉

paulspencerwilliams15:11:46

Honestly, they can be a mare. A few systems ago we had a problem because an Indonesian island changed their boundaries switching it into another timezone, and until Java recognised it, all commodity trades there were an hour out.

rickmoynihan15:11:52

The Timezone database is literally full of absurdities and quirks like this: https://blog.jonudell.net/2009/10/23/a-literary-appreciation-of-the-olsonzoneinfotz-database/

dharrigan15:11:39

btw, this works too

dharrigan15:11:23

(import [java.time LocalDate])
(import [java.time.temporal TemporalAdjusters])
(def now (LocalDate/now))
(.with now (TemporalAdjusters/lastDayOfMonth))

dharrigan15:11:50

(.with (LocalDate/now) (TemporalAdjusters/lastDayOfMonth))

dominicm15:11:42

user=> (tick.core/last-day-of-month (tick.alpha.api/new-date 2019 12))
#time/date "2019-12-31"

Ben Hammond15:11:15

(-> (java-time/local-date 2013 12)
  (java-time/plus (java-time/months 1))
  (java-time/minus (java-time/days 1)))

maleghast15:11:01

(defn get-last-day-of-month
  "Function to get valid last day of month from year and month"
  [year month]
  (let [year-modified (if (= 12 month) (+ 1 year) year)
        month-modified (if (= 12 month) 1 (+ 1 month))]
    (jt/as (jt/minus (jt/local-date year-modified month-modified) (jt/days 1)) :day-of-month)))

Ben Hammond15:11:47

(java-time/adjust (java-time/local-date 2013 12) :last-day-of-month)

dharrigan15:11:52

Why not use the built-in API that java gives you?

maleghast15:11:38

@dharrigan - Because I am using it via the Clojure wrapper and I don't want to do interop

Ben Hammond15:11:26

(sort (keys (merge java-time.adjuster/base-adjusters java-time.adjuster/extra-adjusters)))
=>
(:day-of-week-in-month
 :first-day-of-month
 :first-day-of-next-month
 :first-day-of-next-year
 :first-day-of-year
 :first-in-month
 :last-day-of-month
 :last-day-of-year
 :last-in-month
 :next-day-of-week
 :next-or-same-day-of-week
 :previous-day-of-week
 :previous-or-same-day-of-week)

maleghast15:11:27

but @ben.hammond has found the thing I was looking for, so even though I enjoyed my function ^^ I can make it a LOT nicer now...

Ben Hammond15:11:01

I've started to really like java-time since I was shown https://github.com/henryw374/time-literals

Ben Hammond15:11:36

it doesn't (often) make me do things that I don't want to do

maleghast16:11:52

Man, that is pretty neat!

seancorfield17:11:46

I gather the other nice Java Time wrapper is https://github.com/henryw374/cljc.java-time which also works in cljs.

dominicm17:11:14

and tick adds an idiomatic wrapper over cljc.java-time 🙂 (co-authored by henryw)

seancorfield17:11:29

Haven't looked at tick yet. It's on my list 🙂

seancorfield17:11:35

(my very long list!)

maleghast18:11:52

Tick is actually pretty great

maleghast18:11:08

@seancorfield - if you are using clojure.java-time at work, maybe you can help me with something else... I need to get a UNIX timestamp out of a java-time/local-time, but I am struggling to find the docs... Is this something I can do..?

seancorfield18:11:24

Funny you should mention that -- I was just working on some code yesterday that includes a ->unix-time function... let me look that up...

seancorfield18:11:21

Do you mean local-date-time? You need a date as well as a time to get to Unix time...

seancorfield18:11:51

Pretty sure you need to get to an Instant or OffsetDateTime first, and then call .toEpochSecond

maleghast18:11:26

hold on, I will try that...

seancorfield18:11:59

user=> (jt/local-date-time)
#object[java.time.LocalDateTime 0x9353d68 "2019-11-28T10:26:30.324"]
user=> (.toEpochSecond *1 java.time.ZoneOffset/UTC)
1574936790
user=> 
^ @maleghast

maleghast18:11:52

That is super-sweet - shame there's no syntactic sugar to do it without interop, but still, very nice!

maleghast18:11:36

I mean if you could do this:

(jt/as (jt/local-date-time) :unixtimestamp)

maleghast18:11:42

that would be amazing, right?

seancorfield18:11:51

(-> (jt/instant) (jt/to-millis-from-epoch) (quot 1000))
Like that?

seancorfield18:11:17

(again, you need to go from a local date/time to an instant or offset date time for it to work)

seancorfield18:11:22

user=> (-> (jt/offset-date-time) (jt/to-millis-from-epoch) (quot 1000))
1574965982