e6c95db82b6c4ed13b8c01c61d9715f1a57bb602
[aaf/authz.git] / misc / env / src / main / java / org / onap / aaf / misc / env / util / Chrono.java
1 /**\r
2  * ============LICENSE_START====================================================\r
3  * org.onap.aaf\r
4  * ===========================================================================\r
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.\r
6  * ===========================================================================\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  * \r
11  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * \r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  * ============LICENSE_END====================================================\r
19  *\r
20  */\r
21 \r
22 package org.onap.aaf.misc.env.util;\r
23 \r
24 import java.security.SecureRandom;\r
25 import java.text.DateFormat;\r
26 import java.text.SimpleDateFormat;\r
27 import java.util.Date;\r
28 import java.util.GregorianCalendar;\r
29 import java.util.TimeZone;\r
30 import java.util.UUID;\r
31 import java.util.logging.Formatter;\r
32 import java.util.logging.LogRecord;\r
33 \r
34 import javax.xml.datatype.DatatypeConfigurationException;\r
35 import javax.xml.datatype.DatatypeFactory;\r
36 import javax.xml.datatype.XMLGregorianCalendar;\r
37 \r
38 public class Chrono {\r
39     private static final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;\r
40 \r
41     public final static DateFormat dateFmt;\r
42     public final static DateFormat dateOnlyFmt;\r
43     public final static DateFormat niceDateFmt;\r
44     public final static DateFormat utcFmt;\r
45     public final static DateFormat niceUTCDateFmt;\r
46     public final static DateFormat iso8601Fmt;\r
47     public final static DateFormat batchFmt;\r
48     // Give general access to XML DataType Factory, since it's pretty common\r
49     public static final DatatypeFactory xmlDatatypeFactory;\r
50     \r
51     static {\r
52         try {\r
53             xmlDatatypeFactory = DatatypeFactory.newInstance();\r
54         } catch (DatatypeConfigurationException e) {\r
55             throw new RuntimeException(e);\r
56         }\r
57         dateOnlyFmt = new SimpleDateFormat("yyyy-MM-dd");\r
58         niceDateFmt = new SimpleDateFormat("yyyy/MM/dd HH:mm zzz");\r
59         dateFmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");\r
60         utcFmt =  new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");\r
61         utcFmt.setTimeZone(TimeZone.getTimeZone("UTC"));\r
62         niceUTCDateFmt = new SimpleDateFormat("yyyy/MM/dd HH:mm zzz");\r
63         niceUTCDateFmt.setTimeZone(TimeZone.getTimeZone("UTC"));\r
64         iso8601Fmt =  new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");\r
65         batchFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss+SSSS");\r
66     }\r
67     \r
68 \r
69     public static class Formatter8601 extends Formatter {\r
70 \r
71         @Override\r
72         public String format(LogRecord r) {\r
73             StringBuilder sb = new StringBuilder();\r
74             sb.append(dateFmt.format(new Date(r.getMillis())));\r
75             sb.append(' ');\r
76             sb.append(r.getThreadID());\r
77             sb.append(' ');\r
78             sb.append(r.getLevel());\r
79             sb.append(": ");\r
80             sb.append(r.getMessage());\r
81             sb.append('\n');\r
82             return sb.toString();\r
83         }\r
84         \r
85     }\r
86     \r
87     /**\r
88      * timeStamp\r
89      * \r
90      * Convenience method to setup an XML dateTime (XMLGregorianCalendar) with "now" \r
91      * @return\r
92      */\r
93     public static XMLGregorianCalendar timeStamp() {\r
94         return xmlDatatypeFactory.newXMLGregorianCalendar(new GregorianCalendar());\r
95     }\r
96 \r
97     /**\r
98      * timestamp\r
99      * \r
100      * Convenience method to setup an XML dateTime (XMLGregorianCalendar) with passed in Date \r
101      * @param date\r
102      * @return\r
103      */\r
104     public static XMLGregorianCalendar timeStamp(Date date) {\r
105         GregorianCalendar gc = new GregorianCalendar();\r
106         gc.setTime(date);\r
107         return xmlDatatypeFactory.newXMLGregorianCalendar(gc);\r
108     }\r
109 \r
110     public static XMLGregorianCalendar timeStamp(GregorianCalendar gc) {\r
111         return xmlDatatypeFactory.newXMLGregorianCalendar(gc);\r
112     }\r
113 \r
114     public static String utcStamp() {\r
115         return utcFmt.format(new Date());\r
116     }\r
117 \r
118     public static String utcStamp(Date date) {\r
119         if (date==null)return "";\r
120         return utcFmt.format(date);\r
121     }\r
122 \r
123     public static String utcStamp(GregorianCalendar gc) {\r
124         if (gc==null)return "";\r
125         return utcFmt.format(gc.getTime());\r
126     }\r
127 \r
128     public static String utcStamp(XMLGregorianCalendar xgc) {\r
129         if (xgc==null)return "";\r
130         return utcFmt.format(xgc.toGregorianCalendar().getTime());\r
131     }\r
132     \r
133     public static String niceUTCStamp() {\r
134         return niceUTCDateFmt.format(new Date());\r
135     }\r
136 \r
137     public static String niceUTCStamp(Date date) {\r
138         if (date==null)return "";\r
139         return niceUTCDateFmt.format(date);\r
140     }\r
141 \r
142     public static String niceUTCStamp(GregorianCalendar gc) {\r
143         if (gc==null)return "";\r
144         return niceUTCDateFmt.format(gc.getTime());\r
145     }\r
146 \r
147     public static String niceUTCStamp(XMLGregorianCalendar xgc) {\r
148         if (xgc==null)return "";\r
149         return niceUTCDateFmt.format(xgc.toGregorianCalendar().getTime());\r
150     }\r
151 \r
152     public static String dateStamp() {\r
153         return dateFmt.format(new Date());\r
154     }\r
155 \r
156     public static String dateStamp(GregorianCalendar gc) {\r
157         if (gc == null)return "";\r
158         return dateFmt.format(gc.getTime());\r
159     }\r
160 \r
161     public static String dateStamp(Date date) {\r
162         if (date == null)return "";\r
163         return dateFmt.format(date);\r
164     }\r
165 \r
166     public static String dateStamp(XMLGregorianCalendar xgc) {\r
167         if (xgc==null)return "";\r
168         return dateFmt.format(xgc.toGregorianCalendar().getTime());\r
169     }\r
170 \r
171     /**\r
172      * JAXB compatible dataTime Stamp\r
173      * \r
174      * Java 6 does not format Timezone with -05:00 format, and JAXB XML breaks without it.\r
175      * \r
176      * @return\r
177      */\r
178     public static String dateTime() {\r
179         return dateTime(new GregorianCalendar());\r
180     }\r
181 \r
182     /**\r
183      * JAXB compatible dataTime Stamp\r
184      * \r
185      * Java 6 does not format Timezone with -05:00 format, and JAXB XML breaks without it.\r
186      * \r
187      * @return\r
188      */\r
189     public static String dateTime(Date date) {\r
190         GregorianCalendar gc = new GregorianCalendar();\r
191         gc.setTime(date);\r
192         return dateTime(gc);\r
193     }\r
194 \r
195     /**\r
196      * JAXB compatible dataTime Stamp\r
197      * \r
198      * Java 6 does not format Timezone with -05:00 format, and JAXB XML breaks without it.\r
199      * \r
200      * @return\r
201      */\r
202     public static String dateTime(GregorianCalendar gc) {\r
203         if (gc == null)return "";\r
204         TimeZone tz = gc.getTimeZone();\r
205         int tz1 = (tz.getRawOffset()+tz.getDSTSavings())/0x8CA0;\r
206         int tz1abs = Math.abs(tz1);\r
207         return String.format("%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d:%02d", \r
208                 gc.get(GregorianCalendar.YEAR),\r
209                 gc.get(GregorianCalendar.MONTH)+1,\r
210                 gc.get(GregorianCalendar.DAY_OF_MONTH),\r
211                 gc.get(GregorianCalendar.HOUR),\r
212                 gc.get(GregorianCalendar.MINUTE),\r
213                 gc.get(GregorianCalendar.SECOND),\r
214                 gc.get(GregorianCalendar.MILLISECOND),\r
215                 tz1==tz1abs?'+':'-',\r
216                 tz1abs/100,\r
217                 ((tz1abs-(tz1abs/100)*100)*6)/10 // Get the "10s", then convert to mins (without losing int place)\r
218                 );\r
219     }\r
220 \r
221     /**\r
222      * JAXB compatible dataTime Stamp\r
223      * \r
224      * Java 6 does not format Timezone with -05:00 format, and JAXB XML breaks without it.\r
225      * \r
226      * @return\r
227      */\r
228     public static String dateTime(XMLGregorianCalendar xgc) {\r
229         return xgc==null?"":dateTime(xgc.toGregorianCalendar());\r
230     }\r
231 \r
232     public static String dateOnlyStamp() {\r
233         return dateOnlyFmt.format(new Date());\r
234     }\r
235 \r
236     public static String dateOnlyStamp(GregorianCalendar gc) {\r
237         return gc == null?"":dateOnlyFmt.format(gc.getTime());\r
238     }\r
239 \r
240     public static String dateOnlyStamp(Date date) {\r
241         return date == null?"":dateOnlyFmt.format(date);\r
242     }\r
243 \r
244     public static String dateOnlyStamp(XMLGregorianCalendar xgc) {\r
245         return xgc==null?"":dateOnlyFmt.format(xgc.toGregorianCalendar().getTime());\r
246     }\r
247 \r
248     public static String niceDateStamp() {\r
249         return niceDateFmt.format(new Date());\r
250     }\r
251 \r
252     public static String niceDateStamp(Date date) {\r
253         return date==null?"":niceDateFmt.format(date);\r
254     }\r
255 \r
256     public static String niceDateStamp(GregorianCalendar gc) {\r
257         return gc==null?"":niceDateFmt.format(gc.getTime());\r
258     }\r
259 \r
260     public static String niceDateStamp(XMLGregorianCalendar xgc) {\r
261         return xgc==null?"":niceDateFmt.format(xgc.toGregorianCalendar().getTime());\r
262     }\r
263 \r
264 \r
265     //////////////////////  HELPFUL Strings\r
266     public static final String BAD_DIR_CHARS_REGEX = "[/:\\;.]";\r
267     public static final String SPLIT_DIR_REGEX = "/";\r
268 \r
269     public static long firstMomentOfDay(long utc) {\r
270         GregorianCalendar begin = new GregorianCalendar();\r
271         begin.setTimeInMillis(utc);\r
272         return firstMomentOfDay(begin).getTimeInMillis();\r
273     }    \r
274     \r
275     public static long lastMomentOfDay(long utc) {\r
276         GregorianCalendar end = new GregorianCalendar();\r
277         end.setTimeInMillis(utc);\r
278         return lastMomentOfDay(end).getTimeInMillis();\r
279     }\r
280 \r
281     public static GregorianCalendar firstMomentOfDay(GregorianCalendar begin) {\r
282         if (begin==null)begin = new GregorianCalendar();\r
283         begin.set(GregorianCalendar.HOUR, 0);\r
284         begin.set(GregorianCalendar.AM_PM, GregorianCalendar.AM);\r
285         begin.set(GregorianCalendar.MINUTE, 0);\r
286         begin.set(GregorianCalendar.SECOND, 0);\r
287         begin.set(GregorianCalendar.MILLISECOND, 0);\r
288         return begin;\r
289     }    \r
290 \r
291     public static GregorianCalendar lastMomentOfDay(GregorianCalendar end) {\r
292         if (end==null)end = new GregorianCalendar();\r
293         end.set(GregorianCalendar.HOUR, 11);\r
294         end.set(GregorianCalendar.MINUTE, 59);\r
295         end.set(GregorianCalendar.SECOND, 59);\r
296         end.set(GregorianCalendar.MILLISECOND, 999);\r
297         end.set(GregorianCalendar.AM_PM, GregorianCalendar.PM);\r
298         return end;\r
299     }\r
300 \r
301     // UUID needs to be converted from UUID Epoch\r
302     public static final Date uuidToDate(UUID id) {\r
303         return new Date((id.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH)/10000);\r
304     }\r
305 \r
306     public static final long uuidToUnix(UUID id) {\r
307         return (id.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH)/10000;\r
308     }\r
309 \r
310     public static float millisFromNanos(long start, long end) {\r
311         return (end - start) / 1000000f;\r
312     }\r
313 \r
314 \r
315     private static long sequence = new SecureRandom().nextInt();\r
316     private static synchronized long sequence() {\r
317         return ++sequence;\r
318     }\r
319     \r
320     public static final UUID dateToUUID(Date origTime) {\r
321         return dateToUUID(origTime.getTime());\r
322     }\r
323     \r
324     public static final UUID dateToUUID(long origTime) {\r
325     /*\r
326      * From Cassandra : http://wiki.apache.org/cassandra/FAQ\r
327       Magic number obtained from #cassandra's thobbs, who\r
328       claims to have stolen it from a Python library.\r
329     */\r
330         long time = origTime * 10000 + NUM_100NS_INTERVALS_SINCE_UUID_EPOCH;\r
331         long timeLow = time &       0xffffffffL;\r
332         long timeMid = time &   0xffff00000000L;\r
333         long timeHi = time & 0xfff000000000000L;\r
334         long upperLong = (timeLow << 32) | (timeMid >> 16) | (1 << 12) | (timeHi >> 48) ;\r
335         return new java.util.UUID(upperLong, (0xC000000000000000L | sequence()));\r
336     }\r
337 \r
338 }\r