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.openecomp.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;
42 import javax.xml.datatype.DatatypeConfigurationException;
43 import javax.xml.datatype.DatatypeFactory;
44 import javax.xml.datatype.XMLGregorianCalendar;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
50 * This class is a general purpose helper class to augment standard Java time support.
54 public final class Time {
57 * Logger to log operations
59 private static final Logger LOG = LoggerFactory.getLogger(Time.class);
62 * A formatter to be used to format values
64 private static SimpleDateFormat dateformatter = null;
67 * The UTC timezone (for UTC or GMT time)
69 @SuppressWarnings("nls")
70 private static final TimeZone utcTZ = TimeZone.getTimeZone("UTC");
73 * The cached reference to the datatype factory
75 private static DatatypeFactory xmlDatatypeFactory = null;
78 * Private default constructor prevents instantiation
85 * Increments a date by the indicated months, days, hours, minutes, and seconds, and returns the updated date.
88 * The date to be manipulated
90 * The number of months to be added to the date
92 * The number of days to be added to the date
94 * The number of hours to be added to the date
96 * The number of minutes to be added to the date
98 * The number of seconds to be added to the date
99 * @return The updated date.
101 public static Date addTime(final Date date, final int months, final int days, final int hours, final int minutes,
103 Calendar cal = Calendar.getInstance();
105 cal.add(Calendar.MONTH, months);
106 cal.add(Calendar.DATE, days);
107 cal.add(Calendar.HOUR_OF_DAY, hours);
108 cal.add(Calendar.MINUTE, minutes);
109 cal.add(Calendar.SECOND, seconds);
110 return cal.getTime();
114 * Clears the time components of a calendar to zero, leaving the date components unchanged.
117 * the calendar to be updated
118 * @return The updated calendar object
120 public static Calendar dateOnly(final Calendar cal) {
121 cal.set(Calendar.HOUR_OF_DAY, 0);
122 cal.set(Calendar.MINUTE, 0);
123 cal.set(Calendar.SECOND, 0);
124 cal.set(Calendar.MILLISECOND, 0);
129 * This method returns the local time that corresponds to the end of the current day
131 * @return The time that corresponds to the end of the current day, expressed as local time
133 public static Date endOfDayLocal() {
134 return endOfDayLocal(new Date());
138 * This method returns the last moment of the day for the supplied local time. This is defined as the millisecond
139 * before midnight of the current date represented by the local time.
142 * The local time for which the last moment of the day is desired.
143 * @return The millisecond prior to midnight, local time.
145 public static Date endOfDayLocal(final Date localTime) {
147 GregorianCalendar calendar = new GregorianCalendar();
148 calendar.setTime(localTime);
149 calendar.set(Calendar.HOUR, 11);
150 calendar.set(Calendar.AM_PM, Calendar.PM);
151 calendar.set(Calendar.MINUTE, 59);
152 calendar.set(Calendar.SECOND, 59);
153 calendar.set(Calendar.MILLISECOND, 999);
156 return calendar.getTime();
160 * The end of the current day and in the current time zone expressed as a UTC time.
162 * @return The UTC time that corresponds to the end of the current day
164 public static Date endOfDayUTC() {
165 return endOfDayUTC(new Date());
169 * Returns the UTC time that corresponds to the end of the day for the local time specified, using the current
170 * (default) time zone.
173 * The local time for which we are requesting the UTC time that corresponds to the end of the day
174 * @return The UTC time that corresponds to the end of the local day specified by the local time.
176 public static Date endOfDayUTC(final Date localTime) {
177 return endOfDayUTC(localTime, TimeZone.getDefault());
181 * Returns the time expressed in UTC time of the end of the day specified in local time and within the local time
185 * The local time for which we will compute the end of the local day, and then convert to UTC time.
186 * @param localTimeZone
187 * The time zone that the local time is within.
188 * @return The UTC date that corresponds to the end of the day local time and in the local time zone.
190 public static Date endOfDayUTC(final Date localTime, final TimeZone localTimeZone) {
191 Date endOfDay = endOfDayLocal(localTime);
192 return utcDate(endOfDay, localTimeZone);
196 * returns current Date in 'UTC' Timezone
198 * @return The current date, expressed in the UTC timezone.
200 @SuppressWarnings("nls")
201 public static Date getCurrentUTCDate() {
203 // This code incorrectly changes the default timezone for the entire JVM in order to compute the UTC
204 // date for the current time.
206 GregorianCalendar calendar = new GregorianCalendar();
207 calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
208 calendar.setTimeInMillis(utcTime());
209 return calendar.getTime();
213 * This method loads and caches the reference to the XML data type factory object.
215 * @return The XML Data Type Factory object
217 public static DatatypeFactory getDatatypeFactory() {
218 if (xmlDatatypeFactory == null) {
220 xmlDatatypeFactory = DatatypeFactory.newInstance();
221 } catch (DatatypeConfigurationException e) {
222 e.printStackTrace(System.err);
225 return xmlDatatypeFactory;
229 * Gives the date-time String based on given Locale and Timezone
232 * The date to be formatted
234 * The locale that we want to format the value for
236 * The time zone that the date is within
237 * @return The formatted value
239 public static String getDateByLocaleAndTimeZone(final Date date, final Locale locale, final TimeZone timezone) {
240 String strDate = null;
241 DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale);
242 df.setTimeZone(timezone);
244 strDate = df.format(date);
250 * Returns singleton UTC date formatter.
254 @SuppressWarnings("nls")
255 private static SimpleDateFormat getDateFormatter() {
256 if (dateformatter == null) {
257 dateformatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
258 dateformatter.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
260 return dateformatter;
264 * This method returns the local time that corresponds to a given UTC time in the current time zone.
267 * The UTC time for which we desire the equivalent local time in the current time zone.
268 * @return The local time that is equivalent to the given UTC time for the current time zone
270 public static long localTime(final long utcTime) {
271 return localTime(utcTime, TimeZone.getDefault());
275 * This method can be used to get the local time that corresponds to a specific UTC time.
277 * This method has a problem since the offset can only be determined by having a local time. So, we take the UTC
278 * time and add the raw offset to it to come up with an approximation of the local time. This gives us a local time
279 * that we can use to determine what the offset should be, which is what we actually add to the UTC time to get the
284 * The UTC time for which we want to obtain the equivalent local time
286 * The time zone that we want the local time to be within
287 * @return The local time for the specified time zone and the given UTC time
289 public static long localTime(final long utcTime, final TimeZone localTZ) {
290 int offset = localTZ.getOffset(utcTime + localTZ.getRawOffset());
291 long result = utcTime + offset;
297 * Sets the date components of a calendar to the specified values, leaving the time components unchanged.
300 * The calendar to be updated
304 * The month to be set
307 * @return The updated calendar object
309 public static Calendar setDate(final Calendar cal, final int year, final int month, final int day) {
310 cal.set(Calendar.YEAR, year);
311 cal.set(Calendar.MONTH, month);
312 cal.set(Calendar.DAY_OF_MONTH, day);
317 * Returns the start of the day expressed in local time for the current local time.
319 * @return The start of the day
321 public static Date startOfDayLocal() {
322 return startOfDayLocal(new Date());
326 * This method returns the date that corresponds to the start of the day local time. The date returned represents
327 * midnight of the previous day represented in local time. If the UTC time is desired, use the methods
328 * {@link #startOfDayUTC(Date, TimeZone)}, {@link #startOfDayUTC(Date)}, or {@link #startOfDayUTC()}
331 * The local date that we wish to compute the start of day for.
332 * @return The date that corresponds to the start of the local day
334 public static Date startOfDayLocal(final Date localTime) {
335 GregorianCalendar calendar = new GregorianCalendar();
336 calendar.setTime(localTime);
337 calendar.set(Calendar.HOUR, 0);
338 calendar.set(Calendar.AM_PM, Calendar.AM);
339 calendar.set(Calendar.MINUTE, 0);
340 calendar.set(Calendar.SECOND, 0);
341 calendar.set(Calendar.MILLISECOND, 0);
343 return calendar.getTime();
347 * This method returns the UTC date that corresponds to the start of the local day based on the current time and the
348 * default time zone (the time zone we are running in).
350 * @return The start of the local day expressed as a UTC time.
352 public static Date startOfDayUTC() {
353 return startOfDayUTC(new Date());
357 * This method returns the UTC date that corresponds to the start of the local day specified in the current time
361 * The local time to be used to compute the start of the day
362 * @return The start of the local day expressed as a UTC time.
364 public static Date startOfDayUTC(final Date localTime) {
365 return startOfDayUTC(localTime, TimeZone.getDefault());
369 * This method returns the UTC date that corresponds to the start of the local day specified in the local timezone.
372 * The local time to be used to compute start of day
373 * @param localTimeZone
374 * The time zone that the local time was recorded within
375 * @return The corresponding UTC date
377 public static Date startOfDayUTC(final Date localTime, final TimeZone localTimeZone) {
378 Date startOfDay = startOfDayLocal(localTime);
379 return utcDate(startOfDay, localTimeZone);
383 * This method creates and returns an XML timestamp expressed as the current UTC value for the system. The caller
384 * does not specify the time value or time zone using this method. This ensures that the timestamp value is always
385 * expressed as UTC time.
387 * @return The XMLGregorianCalendar that can be used to record the timestamp
390 public static XMLGregorianCalendar timestamp() {
391 getDatatypeFactory();
392 XMLGregorianCalendar ts = xmlDatatypeFactory.newXMLGregorianCalendar();
393 GregorianCalendar utc = new GregorianCalendar();
394 utc.setTime(utcDate());
396 ts.setYear(utc.get(Calendar.YEAR));
397 // Calendar Months are from 0-11 need to +1
398 ts.setMonth(utc.get(Calendar.MONTH) + 1);
399 ts.setDay(utc.get(Calendar.DAY_OF_MONTH));
400 ts.setHour(utc.get(Calendar.HOUR_OF_DAY));
401 ts.setMinute(utc.get(Calendar.MINUTE));
402 ts.setSecond(utc.get(Calendar.SECOND));
403 ts.setMillisecond(utc.get(Calendar.MILLISECOND));
408 * Converts XMLGregorianCalendar to java.util.Date in Java
411 * the calendar object to be converted
412 * @return The equivalent Date object
414 public static Date toDate(final XMLGregorianCalendar calendar) {
415 if (calendar == null) {
418 return calendar.toGregorianCalendar().getTime();
422 * Converts java Date to XMLGregorianCalendar.
425 * The date to convert
426 * @return The XMLGregorianCalendar for the specified date
428 @SuppressWarnings("nls")
429 public static XMLGregorianCalendar toXMLCalendar(final Date date) {
430 GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
433 XMLGregorianCalendar xmlCal = null;
435 xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(cal);
436 } catch (DatatypeConfigurationException e) {
437 LOG.error("toXMLCalendar", e);
443 * Truncates the provided date so that only the date, hours, and minutes portions are significant. This method
444 * returns the date with the seconds and milliseconds forced to zero.
447 * The date to truncate
448 * @return The date with only the year, month, day, hours, and minutes significant.
450 public static Date truncDate(final Date date) {
451 Calendar cal = Calendar.getInstance();
453 cal.set(Calendar.SECOND, 0);
454 cal.set(Calendar.MILLISECOND, 0);
455 return cal.getTime();
459 * The UTC date that corresponds to the current date in the local time zone.
461 * @return The UTC date for now in the current time zone.
463 public static Date utcDate() {
468 * The UTC date for the specified date in the current (default) time zone.
471 * The local date for which the UTC date is desired.
472 * @return The UTC date that corresponds to the date in the current time zone.
474 public static Date utcDate(final Date date) {
475 TimeZone tz = TimeZone.getDefault();
476 return utcDate(date, tz);
480 * Returns the UTC date for the specified date in the specified time zone.
483 * The date for which the UTC date is desired in the specified zone
485 * The time zone that corresponds to the date to be converted to UTC
486 * @return The UTC date that corresponds to the local date in the local time zone.
488 public static Date utcDate(final Date date, final TimeZone tz) {
489 return new Date(utcTime(date.getTime(), tz));
493 * Format incoming date as string in GMT or UTC.
496 * The date to be formatted
497 * @return The date formatted for UTC timezone
499 public static String utcFormat(final Date dt) {
500 String strDate = null;
501 DateFormat df = getDateFormatter();
503 strDate = df.format(dt);
509 * Parse previously formated Date object back to a Date object.
512 * The representation of a UTC date as a string
513 * @return The date object containing the parsed representation, or null if the representation cannot be parsed
515 @SuppressWarnings("nls")
516 public static Date utcParse(final String dateStr) {
520 return utcParse(dateStr, adtl);
524 * Parse previously formated Date object back to a Date object.
527 * The representation of a UTC date as a string
528 * @param adtlFormatStrings
529 * A list of strings that represent additional date format representations to try and parse.
530 * @return The date object containing the parsed representation, or null if the representation cannot be parsed
532 @SuppressWarnings("nls")
533 public static Date utcParse(final String dateStr, String... adtlFormatStrings) {
534 if (dateStr != null) {
535 // Build the list of formatters starting with the default defined in the class
536 List<DateFormat> formats = new ArrayList<>();
537 formats.add(getDateFormatter());
539 if (adtlFormatStrings != null) {
540 for (String s : adtlFormatStrings) {
541 formats.add(new SimpleDateFormat(s));
545 // Return the first matching date formatter's result
546 for (DateFormat df : formats) {
547 df.setTimeZone(utcTZ);
549 return df.parse(dateStr);
550 } catch (ParseException e) {
551 LOG.debug(String.format("IGNORE - Date string [%s] does not fit pattern [%s]", dateStr,
560 * This method returns the current time for the UTC timezone
562 * @return The time in the UTC time zone that corresponds to the current local time.
564 public static long utcTime() {
565 return new Date().getTime();
569 * Get the UTC time that corresponds to the given time in the default time zone (current time zone for the system).
572 * The time in the current time zone for which the UTC time is desired.
573 * @return The UTC time
575 public static long utcTime(final long localTime) {
576 TimeZone tz = TimeZone.getDefault();
577 return utcTime(localTime, tz);
581 * Get the UTC time that corresponds to the given time in the specified timezone.
583 * Note that the java <code>getOffset()</code> method works a little counter-intuitive. It returns the offset that
584 * would be added to the current UTC time to get the LOCAL time represented by the local time zone. That means to
585 * get the UTC time, we need to SUBTRACT this offset from the local time.
589 * The time in the specified time zone for which the UTC time is desired.
591 * The time zone which the local time is in.
592 * @return The UTC time for the specified local time in the specified local time zone.
594 public static long utcTime(final long localTime, final TimeZone localTZ) {
595 int offset = localTZ.getOffset(localTime);
596 return localTime - offset;
601 * Creates a timestamp value from a time
604 * The UTC time to convert to a timestamp
605 * @return The timestamp
607 public static Timestamp utcTimestamp(final long utcTime) {
608 TimeZone tz = TimeZone.getDefault();
609 return new Timestamp(utcTime(utcTime, tz));