/* * Copyright (c) 2015 EMC Corporation * All Rights Reserved */ package util; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import javax.xml.bind.DatatypeConverter; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import com.emc.storageos.db.client.model.uimodels.ExecutionWindowLengthType; /** * Utilities for working with dates/calendars. Intended mostly for working with Execution Windows. * * @author Chris Dail */ public class TimeUtils { public static final long MILLIS_IN_SECOND = 1000; public static final long SECONDS_IN_HOUR = 3600; public static final long SECONDS_IN_DAY = 3600 * 24; public static final long SECONDS_IN_MIN = 60; public static final int INVALID_LARGE_DAY_OF_MONTH = 32; public static Long getEndDate(DateTime start, int lengthInMillis) { DateTime end = start.plusMillis(lengthInMillis); return end.getMillis() / 1000; } public static Calendar unixToCal(Long unixTimestamp) { Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); cal.setTimeInMillis(unixTimestamp * 1000); return cal; } public static Long dateToUnix(Date d) { Long result = null; if (d != null) { result = d.getTime() / 1000; } return result; } public static Calendar toCal(Date date) { Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); cal.setTime(date); return cal; } public static String toIso(Date date) { return DatatypeConverter.printDateTime(toCal(date)); } public static Date fromIso(String s) { return DatatypeConverter.parseDateTime(s).getTime(); } public static Duration toDuration(long millis) { long seconds = millis / MILLIS_IN_SECOND; if (seconds % SECONDS_IN_DAY == 0) { return new Duration(seconds / SECONDS_IN_DAY, ExecutionWindowLengthType.DAYS); } else if (seconds % SECONDS_IN_HOUR == 0) { return new Duration(seconds / SECONDS_IN_HOUR, ExecutionWindowLengthType.HOURS); } return new Duration((int) seconds / SECONDS_IN_MIN, ExecutionWindowLengthType.MINUTES); } public static long toMillis(long duration, String unit) { ExecutionWindowLengthType lengthType = ExecutionWindowLengthType.valueOf(unit); if (ExecutionWindowLengthType.DAYS.equals(lengthType)) { return duration * SECONDS_IN_DAY * MILLIS_IN_SECOND; } else if (ExecutionWindowLengthType.HOURS.equals(lengthType)) { return duration * SECONDS_IN_HOUR * MILLIS_IN_SECOND; } return duration * SECONDS_IN_MIN * MILLIS_IN_SECOND; } public static TimeZone getTimeZoneForOffset(int offsetInMinutes) { int rawOffset = (offsetInMinutes * 60 * 1000) * -1; String[] timeZoneIds = TimeZone.getAvailableIDs(rawOffset); if (timeZoneIds != null && timeZoneIds.length > 0) { String timeZoneId = timeZoneIds[0]; return TimeZone.getTimeZone(timeZoneId); } return null; } public static int getLocalHourOfDay(int hourOfDayInUTC, int offsetInMinutes) { DateTime utcDate = new DateTime(DateTimeZone.UTC); utcDate = utcDate.withHourOfDay(hourOfDayInUTC); DateTime localDate = utcDate.withZone(getLocalTimeZone(offsetInMinutes)); return localDate.getHourOfDay(); } public static int getLocalDayOfWeek(int dayOfWeekInUTC, int hourOfDayInUTC, int offsetInMinutes) { DateTime utcDate = new DateTime(DateTimeZone.UTC); utcDate = utcDate.withDayOfWeek(dayOfWeekInUTC).withHourOfDay(hourOfDayInUTC); DateTime localDate = utcDate.withZone(getLocalTimeZone(offsetInMinutes)); return localDate.getDayOfWeek(); } public static int getLocalDayOfMonth(int dayOfMonthInUTC, int hourOfDayInUTC, int offsetInMinutes) { DateTime utcDate = new DateTime(DateTimeZone.UTC); if (dayOfMonthInUTC >= utcDate.dayOfMonth().getMaximumValue()) { utcDate = utcDate.withDayOfMonth(utcDate.dayOfMonth().getMaximumValue()).withHourOfDay(hourOfDayInUTC); } else { utcDate = utcDate.withDayOfMonth(dayOfMonthInUTC).withHourOfDay(hourOfDayInUTC); } DateTime localDate = utcDate.withZone(getLocalTimeZone(offsetInMinutes)); return localDate.getDayOfMonth(); } public static DateTimeZone getLocalTimeZone(int offsetInMinutes) { return DateTimeZone.forOffsetMillis((offsetInMinutes * 60 * 1000) * -1); } public static int getUTCHourOfDay(int hourOfDayInLocal, int offsetInMinutes) { DateTime localDate = new DateTime(getLocalTimeZone(offsetInMinutes)); localDate = localDate.withHourOfDay(hourOfDayInLocal); DateTime utcDate = localDate.withZone(DateTimeZone.UTC); return utcDate.getHourOfDay(); } public static int getUTCDayOfWeek(int dayOfWeekInLocal, int hourOfDayInLocal, int offsetInMinutes) { DateTime localDate = new DateTime(getLocalTimeZone(offsetInMinutes)); localDate = localDate.withDayOfWeek(dayOfWeekInLocal).withHourOfDay(hourOfDayInLocal); DateTime utcDate = localDate.withZone(DateTimeZone.UTC); return utcDate.getDayOfWeek(); } public static Integer getUTCDayOfMonth(int dayOfMonthInLocal, int hourOfDayInLocal, int offsetInMinutes) { DateTime localDate = new DateTime(getLocalTimeZone(offsetInMinutes)); localDate = localDate.withDayOfMonth(dayOfMonthInLocal).withHourOfDay(hourOfDayInLocal); DateTime utcDate = localDate.withZone(DateTimeZone.UTC); if (isInPreviousMonth(utcDate, localDate)) { return INVALID_LARGE_DAY_OF_MONTH; } return utcDate.getDayOfMonth(); } public static boolean isUTCInPreviousMonth(Integer dayOfMonthInLocal, int hourOfDayInLocal, int offsetInMinutes) { if (dayOfMonthInLocal == 1) { DateTime localDate = new DateTime(getLocalTimeZone(offsetInMinutes)); localDate = localDate.withDayOfMonth(dayOfMonthInLocal).withHourOfDay(hourOfDayInLocal); DateTime utcDate = localDate.withZone(DateTimeZone.UTC); return isInPreviousMonth(utcDate, localDate); } return false; } private static boolean isInPreviousMonth(DateTime value, DateTime current) { return value.getMonthOfYear() < current.getMonthOfYear() && value.getYear() <= current.getYear(); } public static Calendar getCalendar(int hourOfDay, int offset) { Calendar cal = Calendar.getInstance(getTimeZoneForOffset(offset)); cal.set(Calendar.HOUR_OF_DAY, hourOfDay); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0); cal.setTimeZone(TimeZone.getTimeZone("UTC")); return cal; } public static class Duration { public ExecutionWindowLengthType unit; public long duration; public Duration(long duration, ExecutionWindowLengthType unit) { this.unit = unit; this.duration = duration; } } }