1 package org.influxdb.impl;
2
3 import java.text.SimpleDateFormat;
4 import java.util.EnumSet;
5 import java.util.TimeZone;
6 import java.util.concurrent.TimeUnit;
7
8 /**
9  * Utils for time related methods.
10  *
11  * @author stefan.majer [at] gmail.com
12  */

13 public enum TimeUtil {
14   INSTANCE;
15
16     private static final ThreadLocal<SimpleDateFormat> FORMATTER_MILLIS = new ThreadLocal<SimpleDateFormat>() {
17         @Override
18         protected SimpleDateFormat initialValue() {
19             SimpleDateFormat dateDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
20             dateDF.setTimeZone(TimeZone.getTimeZone("UTC"));
21             return dateDF;
22         }
23     };
24
25     private static final ThreadLocal<SimpleDateFormat> FORMATTER_SECONDS = new ThreadLocal<SimpleDateFormat>() {
26         @Override
27         protected SimpleDateFormat initialValue() {
28             SimpleDateFormat dateDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
29             dateDF.setTimeZone(TimeZone.getTimeZone("UTC"));
30             return dateDF;
31         }
32     };
33
34   private static final EnumSet<TimeUnit> ALLOWED_TIMEUNITS = EnumSet.of(
35       TimeUnit.HOURS,
36       TimeUnit.MINUTES,
37       TimeUnit.SECONDS,
38       TimeUnit.MILLISECONDS,
39       TimeUnit.MICROSECONDS,
40       TimeUnit.NANOSECONDS);
41
42     public static final int TIME_IN_SECOND_LENGTH = 20;
43
44   /**
45    * Convert from a TimeUnit to a influxDB timeunit String.
46    *
47    * @param t the TimeUnit
48    * @return the String representation.
49    */

50   public static String toTimePrecision(final TimeUnit t) {
51     switch (t) {
52     case HOURS:
53       return "h";
54     case MINUTES:
55       return "m";
56     case SECONDS:
57       return "s";
58     case MILLISECONDS:
59       return "ms";
60     case MICROSECONDS:
61       return "u";
62     case NANOSECONDS:
63       return "n";
64     default:
65       throw new IllegalArgumentException("time precision must be one of:" + ALLOWED_TIMEUNITS);
66     }
67   }
68
69     /**
70      * convert a unix epoch time to timestamp used by influxdb.
71      * this can then be used in query expressions against influxdb's time column like so:
72      * influxDB.query(new Query("SELECT * FROM some_measurement WHERE time &gt;= '"
73      *                          + toInfluxDBTimeFormat(timeStart) + "'", some_database))
74      * influxdb time format example: 2016-10-31T06:52:20.020Z
75      *
76      * @param time timestamp to use, in unix epoch time
77      * @return influxdb compatible date-tome string
78      */

79     public static String toInfluxDBTimeFormat(final long time) {
80         return FORMATTER_MILLIS.get().format(time);
81     }
82
83     /**
84      * convert an influxdb timestamp used by influxdb to unix epoch time.
85      * influxdb time format example: 2016-10-31T06:52:20.020Z or 2016-10-31T06:52:20Z
86      *
87      * @param time timestamp to use, in influxdb datetime format
88      * @return time in unix epoch time
89      */

90     public static long fromInfluxDBTimeFormat(final String time) {
91         try {
92             if (time.length() == TIME_IN_SECOND_LENGTH) {
93                 return FORMATTER_SECONDS.get().parse(time).getTime();
94             }
95             return FORMATTER_MILLIS.get().parse(time).getTime();
96         } catch (Exception e) {
97             throw new RuntimeException("unexpected date format", e);
98         }
99     }
100
101 }
102