2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Copyright (C) 2017 Amdocs
8 * =============================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 * ============LICENSE_END=========================================================
27 package org.onap.appc.util;
29 import java.sql.Timestamp;
30 import java.text.DateFormat;
31 import java.text.ParseException;
32 import java.text.SimpleDateFormat;
33 import java.util.ArrayList;
34 import java.util.Calendar;
35 import java.util.Date;
36 import java.util.GregorianCalendar;
37 import java.util.List;
38 import java.util.Locale;
39 import java.util.SimpleTimeZone;
40 import java.util.TimeZone;
41 import javax.xml.datatype.DatatypeConfigurationException;
42 import javax.xml.datatype.DatatypeFactory;
43 import javax.xml.datatype.XMLGregorianCalendar;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
48 * This class is a general purpose helper class to augment standard Java time support.
52 public final class Time {
55 * Logger to log operations
57 private static final Logger LOG = LoggerFactory.getLogger(Time.class);
60 * A formatter to be used to format values
62 private static SimpleDateFormat dateformatter = null;
65 * The UTC timezone (for UTC or GMT time)
67 @SuppressWarnings("nls")
68 private static final TimeZone utcTZ = TimeZone.getTimeZone("UTC");
71 * The cached reference to the datatype factory
73 private static DatatypeFactory xmlDatatypeFactory = null;
76 * Private default constructor prevents instantiation
83 * Increments a date by the indicated months, days, hours, minutes, and seconds, and returns the
86 * @param date The date to be manipulated
87 * @param months The number of months to be added to the date
88 * @param days The number of days to be added to the date
89 * @param hours The number of hours to be added to the date
90 * @param minutes The number of minutes to be added to the date
91 * @param seconds The number of seconds to be added to the date
92 * @return The updated date.
94 public static Date addTime(final Date date, final int months, final int days, final int hours,
95 final int minutes, final int seconds) {
96 Calendar cal = Calendar.getInstance();
98 cal.add(Calendar.MONTH, months);
99 cal.add(Calendar.DATE, days);
100 cal.add(Calendar.HOUR_OF_DAY, hours);
101 cal.add(Calendar.MINUTE, minutes);
102 cal.add(Calendar.SECOND, seconds);
103 return cal.getTime();
107 * Clears the time components of a calendar to zero, leaving the date components unchanged.
109 * @param cal the calendar to be updated
110 * @return The updated calendar object
112 public static Calendar dateOnly(final Calendar cal) {
113 cal.set(Calendar.HOUR_OF_DAY, 0);
114 cal.set(Calendar.MINUTE, 0);
115 cal.set(Calendar.SECOND, 0);
116 cal.set(Calendar.MILLISECOND, 0);
121 * This method returns the local time that corresponds to the end of the current day
123 * @return The time that corresponds to the end of the current day, expressed as local time
125 public static Date endOfDayLocal() {
126 return endOfDayLocal(new Date());
130 * This method returns the last moment of the day for the supplied local time. This is defined
131 * as the millisecond before midnight of the current date represented by the local time.
133 * @param localTime The local time for which the last moment of the day is desired.
134 * @return The millisecond prior to midnight, local time.
136 public static Date endOfDayLocal(final Date localTime) {
138 GregorianCalendar calendar = new GregorianCalendar();
139 calendar.setTime(localTime);
140 calendar.set(Calendar.HOUR, 11);
141 calendar.set(Calendar.AM_PM, Calendar.PM);
142 calendar.set(Calendar.MINUTE, 59);
143 calendar.set(Calendar.SECOND, 59);
144 calendar.set(Calendar.MILLISECOND, 999);
147 return calendar.getTime();
151 * The end of the current day and in the current time zone expressed as a UTC time.
153 * @return The UTC time that corresponds to the end of the current day
155 public static Date endOfDayUTC() {
156 return endOfDayUTC(new Date());
160 * Returns the UTC time that corresponds to the end of the day for the local time specified,
161 * using the current (default) time zone.
163 * @param localTime The local time for which we are requesting the UTC time that corresponds to
165 * @return The UTC time that corresponds to the end of the local day specified by the local
168 public static Date endOfDayUTC(final Date localTime) {
169 return endOfDayUTC(localTime, TimeZone.getDefault());
173 * Returns the time expressed in UTC time of the end of the day specified in local time and
174 * within the local time zone.
176 * @param localTime The local time for which we will compute the end of the local day, and then
177 * convert to UTC time.
178 * @param localTimeZone The time zone that the local time is within.
179 * @return The UTC date that corresponds to the end of the day local time and in the local time
182 public static Date endOfDayUTC(final Date localTime, final TimeZone localTimeZone) {
183 Date endOfDay = endOfDayLocal(localTime);
184 return utcDate(endOfDay, localTimeZone);
188 * returns current Date in 'UTC' Timezone
190 * @return The current date, expressed in the UTC timezone.
192 @SuppressWarnings("nls")
193 public static Date getCurrentUTCDate() {
195 // This code incorrectly changes the default timezone for the entire JVM in order to compute
197 // date for the current time.
199 GregorianCalendar calendar = new GregorianCalendar();
200 calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
201 calendar.setTimeInMillis(utcTime());
202 return calendar.getTime();
206 * This method loads and caches the reference to the XML data type factory object.
208 * @return The XML Data Type Factory object
210 public static DatatypeFactory getDatatypeFactory() {
211 if (xmlDatatypeFactory == null) {
213 xmlDatatypeFactory = DatatypeFactory.newInstance();
214 } catch (DatatypeConfigurationException e) {
215 e.printStackTrace(System.err);
218 return xmlDatatypeFactory;
222 * Gives the date-time String based on given Locale and Timezone
224 * @param date The date to be formatted
225 * @param locale The locale that we want to format the value for
226 * @param timezone The time zone that the date is within
227 * @return The formatted value
229 public static String getDateByLocaleAndTimeZone(final Date date, final Locale locale,
230 final TimeZone timezone) {
231 String strDate = null;
233 DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale);
234 df.setTimeZone(timezone);
236 strDate = df.format(date);
242 * Returns singleton UTC date formatter.
246 @SuppressWarnings("nls")
247 private static SimpleDateFormat getDateFormatter() {
248 if (dateformatter == null) {
249 dateformatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
250 dateformatter.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
252 return dateformatter;
256 * This method returns the local time that corresponds to a given UTC time in the current time
259 * @param utcTime The UTC time for which we desire the equivalent local time in the current time
261 * @return The local time that is equivalent to the given UTC time for the current time zone
263 public static long localTime(final long utcTime) {
264 return localTime(utcTime, TimeZone.getDefault());
268 * This method can be used to get the local time that corresponds to a specific UTC time.
270 * This method has a problem since the offset can only be determined by having a local time. So,
271 * we take the UTC time and add the raw offset to it to come up with an approximation of the
272 * local time. This gives us a local time that we can use to determine what the offset should
273 * be, which is what we actually add to the UTC time to get the local time.
276 * @param utcTime The UTC time for which we want to obtain the equivalent local time
277 * @param localTZ The time zone that we want the local time to be within
278 * @return The local time for the specified time zone and the given UTC time
280 public static long localTime(final long utcTime, final TimeZone localTZ) {
281 int offset = localTZ.getOffset(utcTime + localTZ.getRawOffset());
282 long result = utcTime + offset;
288 * Sets the date components of a calendar to the specified values, leaving the time components
291 * @param cal The calendar to be updated
292 * @param year The year to be set
293 * @param month The month to be set
294 * @param day The day to be set
295 * @return The updated calendar object
297 public static Calendar setDate(final Calendar cal, final int year, final int month,
299 cal.set(Calendar.YEAR, year);
300 cal.set(Calendar.MONTH, month);
301 cal.set(Calendar.DAY_OF_MONTH, day);
306 * Returns the start of the day expressed in local time for the current local time.
308 * @return The start of the day
310 public static Date startOfDayLocal() {
311 return startOfDayLocal(new Date());
315 * This method returns the date that corresponds to the start of the day local time. The date
316 * returned represents midnight of the previous day represented in local time. If the UTC time
317 * is desired, use the methods {@link #startOfDayUTC(Date, TimeZone)},
318 * {@link #startOfDayUTC(Date)}, or {@link #startOfDayUTC()}
320 * @param localTime The local date that we wish to compute the start of day for.
321 * @return The date that corresponds to the start of the local day
323 public static Date startOfDayLocal(final Date localTime) {
324 GregorianCalendar calendar = new GregorianCalendar();
325 calendar.setTime(localTime);
326 calendar.set(Calendar.HOUR, 0);
327 calendar.set(Calendar.AM_PM, Calendar.AM);
328 calendar.set(Calendar.MINUTE, 0);
329 calendar.set(Calendar.SECOND, 0);
330 calendar.set(Calendar.MILLISECOND, 0);
332 return calendar.getTime();
336 * This method returns the UTC date that corresponds to the start of the local day based on the
337 * current time and the default time zone (the time zone we are running in).
339 * @return The start of the local day expressed as a UTC time.
341 public static Date startOfDayUTC() {
342 return startOfDayUTC(new Date());
346 * This method returns the UTC date that corresponds to the start of the local day specified in
347 * the current time zone.
349 * @param localTime The local time to be used to compute the start of the day
350 * @return The start of the local day expressed as a UTC time.
352 public static Date startOfDayUTC(final Date localTime) {
353 return startOfDayUTC(localTime, TimeZone.getDefault());
357 * This method returns the UTC date that corresponds to the start of the local day specified in
358 * the local timezone.
360 * @param localTime The local time to be used to compute start of day
361 * @param localTimeZone The time zone that the local time was recorded within
362 * @return The corresponding UTC date
364 public static Date startOfDayUTC(final Date localTime, final TimeZone localTimeZone) {
365 Date startOfDay = startOfDayLocal(localTime);
366 return utcDate(startOfDay, localTimeZone);
370 * This method creates and returns an XML timestamp expressed as the current UTC value for the
371 * system. The caller does not specify the time value or time zone using this method. This
372 * ensures that the timestamp value is always expressed as UTC time.
374 * @return The XMLGregorianCalendar that can be used to record the timestamp
377 public static XMLGregorianCalendar timestamp() {
378 getDatatypeFactory();
379 XMLGregorianCalendar ts = xmlDatatypeFactory.newXMLGregorianCalendar();
380 GregorianCalendar utc = new GregorianCalendar();
381 utc.setTime(utcDate());
383 ts.setYear(utc.get(Calendar.YEAR));
384 // Calendar Months are from 0-11 need to +1
385 ts.setMonth(utc.get(Calendar.MONTH) + 1);
386 ts.setDay(utc.get(Calendar.DAY_OF_MONTH));
387 ts.setHour(utc.get(Calendar.HOUR_OF_DAY));
388 ts.setMinute(utc.get(Calendar.MINUTE));
389 ts.setSecond(utc.get(Calendar.SECOND));
390 ts.setMillisecond(utc.get(Calendar.MILLISECOND));
395 * Converts XMLGregorianCalendar to java.util.Date in Java
397 * @param calendar the calendar object to be converted
398 * @return The equivalent Date object
400 public static Date toDate(final XMLGregorianCalendar calendar) {
401 if (calendar == null) {
404 return calendar.toGregorianCalendar().getTime();
408 * Converts java Date to XMLGregorianCalendar.
410 * @param date The date to convert
411 * @return The XMLGregorianCalendar for the specified date
413 @SuppressWarnings("nls")
414 public static XMLGregorianCalendar toXMLCalendar(final Date date) {
415 GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
418 XMLGregorianCalendar xmlCal = null;
420 xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
421 } catch (DatatypeConfigurationException e) {
422 LOG.error("toXMLCalendar", e);
428 * Truncates the provided date so that only the date, hours, and minutes portions are
429 * significant. This method returns the date with the seconds and milliseconds forced to zero.
431 * @param date The date to truncate
432 * @return The date with only the year, month, day, hours, and minutes significant.
434 public static Date truncDate(final Date date) {
435 Calendar cal = Calendar.getInstance();
437 cal.set(Calendar.SECOND, 0);
438 cal.set(Calendar.MILLISECOND, 0);
439 return cal.getTime();
443 * The UTC date that corresponds to the current date in the local time zone.
445 * @return The UTC date for now in the current time zone.
447 public static Date utcDate() {
452 * The UTC date for the specified date in the current (default) time zone.
454 * @param date The local date for which the UTC date is desired.
455 * @return The UTC date that corresponds to the date in the current time zone.
457 public static Date utcDate(final Date date) {
458 TimeZone tz = TimeZone.getDefault();
459 return utcDate(date, tz);
463 * Returns the UTC date for the specified date in the specified time zone.
465 * @param date The date for which the UTC date is desired in the specified zone
466 * @param tz The time zone that corresponds to the date to be converted to UTC
467 * @return The UTC date that corresponds to the local date in the local time zone.
469 public static Date utcDate(final Date date, final TimeZone tz) {
470 return new Date(utcTime(date.getTime(), tz));
474 * Format incoming date as string in GMT or UTC.
476 * @param dt The date to be formatted
477 * @return The date formatted for UTC timezone
479 public static String utcFormat(final Date dt) {
480 String strDate = null;
481 DateFormat df = getDateFormatter();
483 strDate = df.format(dt);
489 * Parse previously formated Date object back to a Date object.
491 * @param dateStr The representation of a UTC date as a string
492 * @return The date object containing the parsed representation, or null if the representation
495 @SuppressWarnings("nls")
496 public static Date utcParse(final String dateStr) {
497 String[] adtl = {"yyyy-MM-dd"};
498 return utcParse(dateStr, adtl);
502 * Parse previously formated Date object back to a Date object.
504 * @param dateStr The representation of a UTC date as a string
505 * @param adtlFormatStrings A list of strings that represent additional date format
506 * representations to try and parse.
507 * @return The date object containing the parsed representation, or null if the representation
510 @SuppressWarnings("nls")
511 public static Date utcParse(final String dateStr, String... adtlFormatStrings) {
512 if (dateStr != null) {
513 // Build the list of formatters starting with the default defined in the class
514 List<DateFormat> formats = new ArrayList<>();
515 formats.add(getDateFormatter());
517 if (adtlFormatStrings != null) {
518 for (String s : adtlFormatStrings) {
519 formats.add(new SimpleDateFormat(s));
523 // Return the first matching date formatter's result
524 for (DateFormat df : formats) {
525 df.setTimeZone(utcTZ);
527 return df.parse(dateStr);
528 } catch (ParseException e) {
529 LOG.debug(String.format("IGNORE - Date string [%s] does not fit pattern [%s]",
530 dateStr, df.toString()));
538 * This method returns the current time for the UTC timezone
540 * @return The time in the UTC time zone that corresponds to the current local time.
542 public static long utcTime() {
543 return new Date().getTime();
547 * Get the UTC time that corresponds to the given time in the default time zone (current time
548 * zone for the system).
550 * @param localTime The time in the current time zone for which the UTC time is desired.
551 * @return The UTC time
553 public static long utcTime(final long localTime) {
554 TimeZone tz = TimeZone.getDefault();
555 return utcTime(localTime, tz);
559 * Get the UTC time that corresponds to the given time in the specified timezone.
561 * Note that the java <code>getOffset()</code> method works a little counter-intuitive. It
562 * returns the offset that would be added to the current UTC time to get the LOCAL time
563 * represented by the local time zone. That means to get the UTC time, we need to SUBTRACT this
564 * offset from the local time.
567 * @param localTime The time in the specified time zone for which the UTC time is desired.
568 * @param localTZ The time zone which the local time is in.
569 * @return The UTC time for the specified local time in the specified local time zone.
571 public static long utcTime(final long localTime, final TimeZone localTZ) {
572 int offset = localTZ.getOffset(localTime);
573 return localTime - offset;
578 * Creates a timestamp value from a time
580 * @param utcTime The UTC time to convert to a timestamp
581 * @return The timestamp
583 public static Timestamp utcTimestamp(final long utcTime) {
584 TimeZone tz = TimeZone.getDefault();
585 return new Timestamp(utcTime(utcTime, tz));
588 public static String dateToStringConverterMillis(Date date) {
589 SimpleDateFormat customDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
591 return customDate.format(date);
596 public static Date stringToDateConverterMillis(String dateString) throws ParseException {
597 SimpleDateFormat customDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
598 return customDate.parse(dateString);