/* * This program is part of the OpenLMIS logistics management information * system platform software. * * Copyright © 2015 ThoughtWorks, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. This program is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. You should * have received a copy of the GNU Affero General Public License along with * this program. If not, see http://www.gnu.org/licenses. For additional * information contact info@OpenLMIS.org */ package org.openlmis.core.utils; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.openlmis.core.exceptions.LMISException; import org.openlmis.core.model.Period; import org.openlmis.core.model.StockCard; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; public final class DateUtil { public static final String DEFAULT_DATE_FORMAT = "dd MMM yyyy"; public static final String DATE_FORMAT_ONLY_MONTH_AND_YEAR = "MMM yyyy"; public static final String DATE_FORMAT_ONLY_MONTH_AND_YEAR_SHORT = "MM/yy"; public static final String SIMPLE_DATE_FORMAT = "dd/MM/yyyy"; public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; public static final String TIME_FORMAT = "HH:mm"; public static final String DATE_FORMAT_ONLY_DAY_AND_MONTH = "dd MMM"; public static final String TIME_FORMAT_WITHOUT_SECOND = "dd MMM yyyy HH:mm"; public static final String DB_DATE_FORMAT = "yyyy-MM-dd"; public static final String DATE_DIGIT_FORMAT_ONLY_MONTH_AND_YEAR = "MMyyyy"; public static final String ISO_BASIC_DATE_TIME_FORMAT = "yyyyMMdd'T'HHmmss.SSSZ"; public static final int DAY_PERIOD_END = 20; public static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat(DEFAULT_DATE_FORMAT); public static final SimpleDateFormat DATE_TIME_FORMATTER = new SimpleDateFormat(DATE_TIME_FORMAT); public static final SimpleDateFormat DATE_FORMAT_NOT_DISPLAY_YEAR = new SimpleDateFormat(DATE_FORMAT_ONLY_DAY_AND_MONTH); public static final SimpleDateFormat DATE_FORMAT_NOT_DISPLAY_DAY = new SimpleDateFormat(DATE_FORMAT_ONLY_MONTH_AND_YEAR); public static final SimpleDateFormat DATE_FORMAT_MONTH_AND_YEAR_SHORT = new SimpleDateFormat(DATE_FORMAT_ONLY_MONTH_AND_YEAR_SHORT); private static Locale locale = Locale.getDefault(); public static final long MILLISECONDS_MINUTE = 60000; public static final long MILLISECONDS_HOUR = 3600000; public static final long MILLISECONDS_DAY = 86400000; public static final Calendar CALENDAR_NOW = Calendar.getInstance(); private DateUtil() { } public static Date truncateTimeStampInDate(Date date) { String formattedDateStr = formatDate(date, SIMPLE_DATE_FORMAT); return parseString(formattedDateStr, SIMPLE_DATE_FORMAT); } public static Date addDayOfMonth(Date date, int difference) { Calendar calendar = calendarDate(date); calendar.add(Calendar.DAY_OF_MONTH, difference); return calendar.getTime(); } public static Date minusDayOfMonth(Date date, int difference) { return addDayOfMonth(date, -difference); } public static String formatDate(Date date) { return DATE_FORMATTER.format(date); } public static String formatDateTime(Date date) { return DATE_TIME_FORMATTER.format(date); } public static String formatDateWithoutYear(Date date) { return DATE_FORMAT_NOT_DISPLAY_YEAR.format(date); } public static String formatDateWithoutDay(Date date) { return DATE_FORMAT_NOT_DISPLAY_DAY.format(date); } public static String formatDateWithShortMonthAndYear(Date date) { return DATE_FORMAT_MONTH_AND_YEAR_SHORT.format(date); } public static String formatDate(Date date, String format) { return new SimpleDateFormat(format, locale).format(date); } public static Date parseString(String string, String format) { try { return new SimpleDateFormat(format, locale).parse(string); } catch (ParseException e) { new LMISException(e).reportToFabric(); return null; } } public static Date today() { return Calendar.getInstance().getTime(); } public static String convertDate(String date, String currentFormat, String expectFormat) throws ParseException { return formatDate(parseString(date, currentFormat), expectFormat); } public static String formatDateFromIntToString(int year, int monthOfYear, int dayOfMonth) { return new StringBuilder().append(dayOfMonth).append("/").append(monthOfYear + 1).append("/").append(year).toString(); } public static Date dateMinusMonth(Date current, int months) { return new DateTime(current).minusMonths(months).toDate(); } public static void sortByDate(List<String> expiryDates) { Collections.sort(expiryDates, new Comparator<String>() { @Override public int compare(String lhs, String rhs) { return parseString(lhs, SIMPLE_DATE_FORMAT).compareTo(parseString(rhs, SIMPLE_DATE_FORMAT)); } }); } public static Period generateRnRFormPeriodBy(Date generateDate) { DateTime dateTime = new DateTime(generateDate); Period period = new Period(dateTime); if (isInSubmitDates(dateTime.getDayOfMonth())) { return period.previous(); } return period; } public static Date generatePreviousMonthDateBy(Date date) { return dateMinusMonth(date, 1); } public static int calculateDateMonthOffset(Date earlierDate, Date laterDate) { Calendar startCalendar = new GregorianCalendar(); startCalendar.setTime(earlierDate); Calendar endCalendar = new GregorianCalendar(); endCalendar.setTime(laterDate); int diffYear = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR); return diffYear * 12 + endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH); } private static Calendar calendarDate(Date date) { CALENDAR_NOW.setTime(date); return CALENDAR_NOW; } public static DateTime cutTimeStamp(DateTime dateTime) { DateTimeFormatter format = DateTimeFormat.forPattern(DB_DATE_FORMAT); String formatDate = format.print(dateTime); return format.parseDateTime(formatDate); } private static boolean isInSubmitDates(int day) { return day >= DAY_PERIOD_END + 1 && day <= DAY_PERIOD_END + 5; } public static long calculateTimeIntervalFromNow(long lastSyncedTimestamp) { return new Date().getTime() - lastSyncedTimestamp; } public static String formatExpiryDateString(List<String> expiryDates) { if (expiryDates == null) { return StringUtils.EMPTY; } sortByDate(expiryDates); return StringUtils.join(expiryDates, StockCard.DIVIDER); } public static String uniqueExpiryDates(List<String> expiryDates, String existingDates) { return formatExpiryDateString(addExpiryDates(expiryDates, existingDates)); } public static List<String> addExpiryDates(List<String> expiryDates, String date) { if (StringUtils.isEmpty(date)) { return expiryDates; } if (expiryDates == null || expiryDates.isEmpty()) { expiryDates = new ArrayList<>(); } String[] existingExpiryDates = date.split(StockCard.DIVIDER); for (String expiryDate : existingExpiryDates) { if (!expiryDates.contains(expiryDate)) { expiryDates.add(expiryDate); } } return expiryDates; } public static String getMonthAbbrByDate(Date date) { CALENDAR_NOW.setTime(date); return new SimpleDateFormat("MMM", locale).format(CALENDAR_NOW.getTime()); } public static int calculateMonthOffset(DateTime biggerTime, DateTime smallerTime) { return biggerTime.getYear() * 12 + biggerTime.getMonthOfYear() - (smallerTime.getYear() * 12 + smallerTime.getMonthOfYear()); } public static Date getActualMaximumDate(Date date) { CALENDAR_NOW.setTime(date); CALENDAR_NOW.set(Calendar.DAY_OF_MONTH, CALENDAR_NOW.getActualMaximum(Calendar.DAY_OF_MONTH)); return CALENDAR_NOW.getTime(); } }