Reputation: 999
I have a time string "2017-08-30 09:01:48"
. Is there a way to round the time to the nearest hour and return the hour?
So if the time were "2017-08-30 09:01:48"
it would return 9
If the time were "2017-08-30 09:51:48"
it would return 10
I looked at the library clj-time
but I couldn't see anything in there that would help me
Any help would be much appreciated?
Upvotes: 3
Views: 915
Reputation: 4358
If you don't want to depend on another library, don't forget, that we have new date/time API in Java 8. Although it doesn't support rounding to the nearest hour (minute, whatever), that's quite easy to implement like madstap in his solution.
Here's the code:
(import 'java.time.LocalDateTime)
(import 'java.time.format.DateTimeFormatter)
(def date-format (DateTimeFormatter/ofPattern "yyyy-MM-dd HH:mm:ss"))
(defn- round-to-nearest-hour [date-time-string]
(let [date-time (LocalDateTime/parse date-time-string date-format)]
(if (>= 30 (.getMinute date-time))
date-time
(.plusHours date-time 1))))
(.getHour (round-to-nearest-hour "2017-08-30 09:01:48")) ;=> 9
(.getHour (round-to-nearest-hour "2017-08-30 09:31:48")) ;=> 10
Upvotes: 4
Reputation: 1372
clj-time
is a thin wrapper for Joda Time library. You can easily use the methods of the underlying Java objects to perform common date manipulations.
For rounding the hour, you can access the hour as a DateTime.Property
and use its API to round to nearest hour as follows:
(require '[clj-time.format :as tf])
(-> (tf/parse "2017-08-30 09:01:48")
.hourOfDay
.roundHalfCeilingCopy
.getHourOfDay)
There are several rounding methods (roundCeilingCopy
, roundHalfFloorCopy
, etc.) to choose from, depending on your exact case.
Note also, that you don't need to specify a formatter, as your date string is already in the ISO8601 format.
Upvotes: 6
Reputation: 1552
This is pretty simple to do with the clj-time library.
(ns foo.hours
(:require
[clj-time.core :as time]
[clj-time.format :as timef]))
(defn parse [s]
(timef/parse (timef/formatter "yyyy-MM-dd HH:mm:ss") s))
(defn round-hour [time]
(let [m (time/minute time)
h (time/hour time)
rounded-h (if (<= 30 m) (inc h) h)]
(if (= 24 rounded-h) 0 rounded-h)))
(comment
(def f (comp round-hour parse))
(f "2017-08-30 09:20:48") ;=> 9
(f "2017-08-30 09:33:48") ;=> 10
(f "2017-08-30 23:39:48") ;=> 0
)
Upvotes: 2