Bug 1253338 - Add DateUtil.getTimezoneOffsetInMinutes*. r=ahunt

I initially wrote the "ForGivenDate" variant for testing purposes - so I could
verify the daylight savings time APIs worked the way I expected them to.
However, I ended up using it in my next patch and leaving in the generic "for
current time" variant because it seems useful.

MozReview-Commit-ID: 4hNGD4uDuOj

--HG--
extra : rebase_source : 56cd92c7ef95aa5ca54daa27d93f56a053f7b4df
This commit is contained in:
Michael Comella 2016-05-09 11:41:02 -07:00
parent 197654cbbc
commit 932d3f86b6
2 changed files with 66 additions and 0 deletions

View File

@ -10,9 +10,11 @@ import android.support.annotation.NonNull;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
/**
* Utilities to help with manipulating Java's dates and calendars.
@ -29,4 +31,25 @@ public class DateUtil {
df.setTimeZone(TimeZone.getTimeZone("GMT"));
return df.format(date);
}
/**
* Returns the timezone offset for the current date in minutes. See
* {@link #getTimezoneOffsetInMinutesForGivenDate(Calendar)} for more details.
*/
public static int getTimezoneOffsetInMinutes(@NonNull final TimeZone timezone) {
return getTimezoneOffsetInMinutesForGivenDate(Calendar.getInstance(timezone));
}
/**
* Returns the time zone offset for the given date in minutes. The date makes a difference due to daylight
* savings time in some regions. We return minutes because we can accurately represent time zones that are
* offset by non-integer hour values, e.g. parts of New Zealand at UTC+12:45.
*
* @param calendar A calendar with the appropriate time zone & date already set.
*/
public static int getTimezoneOffsetInMinutesForGivenDate(@NonNull final Calendar calendar) {
// via Date.getTimezoneOffset deprecated docs (note: it had incorrect order of operations).
// Also, we cast to int because we should never overflow here - the max should be GMT+14 = 840.
return (int) TimeUnit.MILLISECONDS.toMinutes(calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET));
}
}

View File

@ -43,4 +43,47 @@ public class TestDateUtil {
final String actualDate = DateUtil.getDateInHTTPFormat(calendar.getTime());
assertEquals("Returned date is expected", expectedDate, actualDate);
}
@Test
public void testGetTimezoneOffsetInMinutes() {
assertEquals("GMT has no offset", 0, DateUtil.getTimezoneOffsetInMinutes(TimeZone.getTimeZone("GMT")));
// We use custom timezones because they don't have daylight savings time.
assertEquals("Offset for GMT-8 is correct",
-480, DateUtil.getTimezoneOffsetInMinutes(TimeZone.getTimeZone("GMT-8")));
assertEquals("Offset for GMT+12:45 is correct",
765, DateUtil.getTimezoneOffsetInMinutes(TimeZone.getTimeZone("GMT+12:45")));
// We use a non-custom timezone without DST.
assertEquals("Offset for KST is correct",
540, DateUtil.getTimezoneOffsetInMinutes(TimeZone.getTimeZone("Asia/Seoul")));
}
@Test
public void testGetTimezoneOffsetInMinutesForGivenDateNoDaylightSavingsTime() {
final TimeZone kst = TimeZone.getTimeZone("Asia/Seoul");
final Calendar[] calendars =
new Calendar[] { getCalendarForMonth(Calendar.DECEMBER), getCalendarForMonth(Calendar.AUGUST) };
for (final Calendar cal : calendars) {
cal.setTimeZone(kst);
assertEquals("Offset for KST does not change with daylight savings time",
540, DateUtil.getTimezoneOffsetInMinutesForGivenDate(cal));
}
}
@Test
public void testGetTimezoneOffsetInMinutesForGivenDateDaylightSavingsTime() {
final TimeZone pacificTimeZone = TimeZone.getTimeZone("America/Los_Angeles");
final Calendar pstCalendar = getCalendarForMonth(Calendar.DECEMBER);
final Calendar pdtCalendar = getCalendarForMonth(Calendar.AUGUST);
pstCalendar.setTimeZone(pacificTimeZone);
pdtCalendar.setTimeZone(pacificTimeZone);
assertEquals("Offset for PST is correct", -480, DateUtil.getTimezoneOffsetInMinutesForGivenDate(pstCalendar));
assertEquals("Offset for PDT is correct", -420, DateUtil.getTimezoneOffsetInMinutesForGivenDate(pdtCalendar));
}
private Calendar getCalendarForMonth(final int month) {
return new GregorianCalendar(2000, month, 1);
}
}