package com.bc.util.time; import com.bc.util.string.StringUtils; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; public class TimeUtils { public static final String ISO8601_YMDHMS_PATTERN = "yyyy-MM-dd HH:mm:ss"; public static final Date INVALID_DATE = new Date(0); public static boolean isSameDay(Date date_1, Date date_2) { if (date_1 == null || date_2 == null) { return false; } final Calendar cal_1 = GregorianCalendar.getInstance(); cal_1.setTime(date_1); final Calendar cal_2 = GregorianCalendar.getInstance(); cal_2.setTime(date_2); //noinspection RedundantIfStatement if (cal_1.get(Calendar.YEAR) == cal_2.get(Calendar.YEAR) && cal_1.get(Calendar.MONTH) == cal_2.get(Calendar.MONTH) && cal_1.get(Calendar.DAY_OF_MONTH) == cal_2.get(Calendar.DAY_OF_MONTH)) { return true; } return false; } public static boolean isSameSecond(Date date_1, Date date_2) { if (date_1 == null || date_2 == null) { return false; } final Calendar cal_1 = GregorianCalendar.getInstance(); cal_1.setTime(date_1); final Calendar cal_2 = GregorianCalendar.getInstance(); cal_2.setTime(date_2); //noinspection RedundantIfStatement if (cal_1.get(Calendar.YEAR) == cal_2.get(Calendar.YEAR) && cal_1.get(Calendar.MONTH) == cal_2.get(Calendar.MONTH) && cal_1.get(Calendar.DAY_OF_MONTH) == cal_2.get(Calendar.DAY_OF_MONTH) && cal_1.get(Calendar.HOUR_OF_DAY) == cal_2.get(Calendar.HOUR_OF_DAY) && cal_1.get(Calendar.MINUTE) == cal_2.get(Calendar.MINUTE) && cal_1.get(Calendar.SECOND) == cal_2.get(Calendar.SECOND)) { return true; } return false; } /** * Parses the given text value as UTC date value. The method recognizes the format the ISO 8601 date/time format * <code>YYYY-MM-DD [hh:mm:ss.S]</code>. * * @param dateString the text to be parsed, must not be null or empty * @return a date object, never null * @throws java.text.ParseException o invalid pattern format */ public static Date parseISO8601Date(String dateString) throws ParseException { return parseDateByPattern(dateString, ISO8601_PATTERNS); } public static Date parseISO8601Date(String dateString, boolean isUTC) throws ParseException { return parseDateByPattern(dateString, ISO8601_PATTERNS, isUTC); } public static Date parseISO8601StartDate(String dateString) throws ParseException { final Date date = parseDateByPattern(dateString, ISO8601_PATTERNS, false); final Calendar cal = GregorianCalendar.getInstance(); cal.setTime(date); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); } public static Date parseISO8601EndDate(String dateString) throws ParseException { final Date date = parseDateByPattern(dateString, ISO8601_PATTERNS, false); final Calendar cal = GregorianCalendar.getInstance(); cal.setTime(date); cal.set(Calendar.HOUR_OF_DAY, 23); cal.set(Calendar.MINUTE, 59); cal.set(Calendar.SECOND, 59); cal.set(Calendar.MILLISECOND, 0); return cal.getTime(); } public static boolean isValidISO8601String(String dateString) { boolean result = true; try { parseISO8601Date(dateString); } catch (ParseException e) { result = false; } catch (IllegalArgumentException e) { result = false; } return result; } /** * Formats the given UTC date value using the ISO 8601 format <code>YYYY-MM-DD [hh:mm:ss.S]</code>. * * @param date the date to be formatted, must not be null * @return a text string, never null */ public static String formatISO8601Date(Date date) { return formatISO8601Date(date, true); } public static String formatISO8601Date(Date date, boolean isUtc) { if (date == null) { throw new IllegalArgumentException("argument date is null"); } Calendar calendar; if (isUtc) { calendar = createUTCCalendar(); } else { calendar = GregorianCalendar.getInstance(); calendar.clear(); } calendar.setTime(date); final String pattern = getPattern(calendar); final DateFormat format = new SimpleDateFormat(pattern); format.setTimeZone(calendar.getTimeZone()); return format.format(date); } public static String getPattern(final Calendar calendar) { final String pattern; if (calendar.get(Calendar.MILLISECOND) != 0) { pattern = ISO8601_YMDHMSM_PATTERN; } else if (calendar.get(Calendar.SECOND) != 0) { pattern = ISO8601_YMDHMS_PATTERN; } else if (calendar.get(Calendar.HOUR_OF_DAY) != 0 || calendar.get(Calendar.MINUTE) != 0) { pattern = ISO8601_YMDHM_PATTERN; } else { pattern = ISO8601_YMD_PATTERN; } return pattern; } public static Calendar createUTCCalendar() { final Calendar instance = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ENGLISH); instance.clear(); return instance; } /** * Parses the given text value as ftp logfile date value. The method recognizes the format used by ftp logfiles * <code>dd/MMM/yyyy [:hh:mm:ss.S]</code>. * * @param dateString the text to be parsed, must not be null or empty * @return a date object, never null * @throws ParseException */ public static Date parseFtpLogDate(String dateString) throws ParseException { final String[] patterns = { LOG_YMDHMS_PATTERN, LOG_YMDHM_PATTERN, LOG_YMD_PATTERN }; return parseDateByPattern(dateString, patterns); } public static Date parseHdfEosDateString(String hdfEosDate) throws ParseException { final String[] patterns = { HDFEOS_YMDHMSM_PATTERN, HDFEOS_YMD_PATTERN }; return parseDateByPattern(hdfEosDate, patterns, false); } public static Date parseProductDate(String dateString) throws ParseException { final String[] patterns = { PRODUCT_PATTERN }; return parseDateByPattern(dateString, patterns, true); } /////////////////////////////////////////////////////////////////////////// /////// END OF PUBLIC /////////////////////////////////////////////////////////////////////////// private static final String ISO8601_YMDHMSM_PATTERN = "yyyy-MM-dd HH:mm:ss.S"; private static final String ISO8601_YMDHM_PATTERN = "yyyy-MM-dd HH:mm"; private static final String ISO8601_YMD_PATTERN = "yyyy-MM-dd"; private static final String[] ISO8601_PATTERNS = new String[]{ ISO8601_YMDHMSM_PATTERN, ISO8601_YMDHMS_PATTERN, ISO8601_YMDHM_PATTERN, ISO8601_YMD_PATTERN }; private static final String LOG_YMDHMS_PATTERN = "dd/MMM/yyyy:HH:mm:ss"; private static final String LOG_YMDHM_PATTERN = "dd/MMM/yyyy:HH:mm"; private static final String LOG_YMD_PATTERN = "dd/MMM/yyyy"; private static final String HDFEOS_YMDHMSM_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.S"; private static final String HDFEOS_YMD_PATTERN = "yyyy-MM-dd"; private static final String PRODUCT_PATTERN = "dd-MMM-yyyy HH:mm:ss"; private static final int YEAR_2K_THRESHOLD = 100; private static final int YEAR_2K = 2000; private static Date parseDateByPattern(String dateString, final String[] patterns) throws ParseException { return parseDateByPattern(dateString, patterns, true); } private static Date parseDateByPattern(String dateString, final String[] patterns, boolean isUTC) throws ParseException { if (StringUtils.isEmpty(dateString)) { throw new IllegalArgumentException("argument dateString is null"); } final Calendar calendar; if (isUTC) { calendar = createUTCCalendar(); } else { calendar = GregorianCalendar.getInstance(); } Date result = null; ParseException lastError = null; for (int i = 0; i < patterns.length; i++) { final SimpleDateFormat format = new SimpleDateFormat(patterns[i], Locale.ENGLISH); format.setTimeZone(calendar.getTimeZone()); try { result = format.parse(dateString); break; } catch (ParseException e) { lastError = e; } } if (result == null) { throw lastError; } calendar.clear(); calendar.setTime(result); if (calendar.get(Calendar.YEAR) < YEAR_2K_THRESHOLD) { calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) + YEAR_2K); } result = calendar.getTime(); return result; } }