forked from status-im/status-legacy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatetime.cljs
More file actions
130 lines (110 loc) · 4.44 KB
/
datetime.cljs
File metadata and controls
130 lines (110 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
(ns status-im.utils.datetime
(:require [cljs-time.core :as t :refer [date-time plus days hours before?]]
[cljs-time.coerce :refer [from-long to-long from-date]]
[cljs-time.format :refer [formatters
formatter
unparse]]
[status-im.i18n :refer [label label-pluralize]]
[goog.string :as gstring]
goog.string.format
goog.i18n.DateTimeFormat
[clojure.string :as s]
[goog.object :refer [get]]))
(defn now []
(t/now))
(def hour (* 1000 60 60))
(def day (* hour 24))
(def week (* 7 day))
(def units [{:name :t/datetime-second :limit 60 :in-second 1}
{:name :t/datetime-minute :limit 3600 :in-second 60}
{:name :t/datetime-hour :limit 86400 :in-second 3600}
{:name :t/datetime-day :limit nil :in-second 86400}])
(def time-zone-offset (hours (- (/ (.getTimezoneOffset (js/Date.)) 60))))
;; xx-YY locale, xx locale or en fallback
(defn- locale-symbols [locale-name]
(if-let [loc (get goog.i18n (str "DateTimeSymbols_" locale-name))]
loc
(let [name-first (s/replace (or locale-name "") #"-.*$" "")
loc (get goog.i18n (str "DateTimeSymbols_" name-first))]
(or loc goog.i18n.DateTimeSymbols_en))))
(def medium-date-time-format (.-MEDIUM_DATETIME goog.i18n.DateTimeFormat.Format))
(def medium-date-format (.-MEDIUM_DATE goog.i18n.DateTimeFormat.Format))
(def short-time-format (.-SHORT_TIME goog.i18n.DateTimeFormat.Format))
(defn mk-fmt [locale format]
(goog.i18n.DateTimeFormat. format (locale-symbols locale)))
(def date-time-fmt
(mk-fmt status-im.i18n/locale medium-date-time-format))
(def date-fmt
(mk-fmt status-im.i18n/locale medium-date-format))
(def time-fmt
(mk-fmt status-im.i18n/locale short-time-format))
(defn- to-str [ms old-fmt-fn yesterday-fmt-fn today-fmt-fn]
(let [date (from-long ms)
local (plus date time-zone-offset) ; this is wrong, it uses the current timezone offset, regardless of DST
today (t/today-at-midnight)
yesterday (plus today (days -1))]
(cond
(before? date yesterday) (old-fmt-fn local)
(before? date today) (yesterday-fmt-fn local)
:else (today-fmt-fn local))))
(defn to-short-str [ms]
(to-str ms
#(.format date-fmt %)
#(label :t/datetime-yesterday)
#(.format time-fmt %)))
(defn day-relative [ms]
(to-str ms
#(.format date-fmt %)
#(label :t/datetime-yesterday)
#(label :t/datetime-today)))
(defn timestamp->mini-date [ms]
(unparse (formatter "dd MMM") (-> ms
from-long
(plus time-zone-offset))))
(defn timestamp->time [ms]
(.format time-fmt (-> ms
from-long
(plus time-zone-offset))))
(defn timestamp->date-key [ms]
(keyword (unparse (formatter "YYYYMMDD") (-> ms
from-long
(plus time-zone-offset)))))
(defn timestamp->long-date [ms]
(keyword (unparse (formatter "MMM DD YYYY HH:mm:ss")
(-> ms
from-long
(plus time-zone-offset)))))
(defn format-time-ago [diff unit]
(let [name (label-pluralize diff (:name unit))]
(label :t/datetime-ago-format {:ago (label :t/datetime-ago)
:number diff
:time-intervals name})))
(defn time-ago [time]
(let [diff (t/in-seconds (t/interval time (t/now)))]
(if (< diff 60)
(label :t/active-online)
(let [unit (first (drop-while #(and (>= diff (:limit %))
(:limit %))
units))]
(-> (/ diff (:in-second unit))
Math/floor
int
(format-time-ago unit))))))
(defn to-date [ms]
(from-long ms))
(defn timestamp []
(inst-ms (js/Date.)))
(defn format-date [format date]
(let [local (plus (from-date date) time-zone-offset)]
(unparse (formatter format) local)))
(defn get-ordinal-date [date]
(let [local (plus (from-date date) time-zone-offset)
day (js/parseInt (unparse (formatter "d") local))
s {0 "th"
1 "st"
2 "nd"
3 "rd"}
m (mod day 100)]
(str day (or (s (mod (- m 20) 10))
(s m)
(s 0)))))