
org.robolectric.shadows.ShadowTime Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of framework Show documentation
Show all versions of framework Show documentation
An alternative Android testing framework.
The newest version!
package org.robolectric.shadows;
import android.os.Build;
import android.text.format.Time;
import android.util.TimeFormatException;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.Strftime;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import static android.os.Build.VERSION_CODES.KITKAT_WATCH;
import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
@Implements(value = Time.class)
public class ShadowTime {
@RealObject
private Time time;
@Implementation(maxSdk = KITKAT_WATCH)
public void setToNow() {
time.set(ShadowSystemClock.currentTimeMillis());
}
private static final long SECOND_IN_MILLIS = 1000;
private static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;
private static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
private static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
@Implementation(maxSdk = KITKAT_WATCH)
public void __constructor__() {
__constructor__(getCurrentTimezone());
}
@Implementation(maxSdk = KITKAT_WATCH)
public void __constructor__(String timezone) {
if (timezone == null) {
throw new NullPointerException("timezone is null!");
}
time.timezone = timezone;
time.year = 1970;
time.monthDay = 1;
time.isDst = -1;
}
@Implementation(maxSdk = KITKAT_WATCH)
public void __constructor__(Time other) {
set(other);
}
@Implementation(maxSdk = KITKAT_WATCH)
public void set(Time other) {
time.timezone = other.timezone;
time.second = other.second;
time.minute = other.minute;
time.hour = other.hour;
time.monthDay = other.monthDay;
time.month = other.month;
time.year = other.year;
time.weekDay = other.weekDay;
time.yearDay = other.yearDay;
time.isDst = other.isDst;
time.gmtoff = other.gmtoff;
}
@Implementation(maxSdk = KITKAT_WATCH)
public static boolean isEpoch(Time time) {
long millis = time.toMillis(true);
return getJulianDay(millis, 0) == Time.EPOCH_JULIAN_DAY;
}
@Implementation(maxSdk = KITKAT_WATCH)
public static int getJulianDay(long millis, long gmtoff) {
long offsetMillis = gmtoff * 1000;
long julianDay = (millis + offsetMillis) / DAY_IN_MILLIS;
return (int) julianDay + Time.EPOCH_JULIAN_DAY;
}
@Implementation(maxSdk = KITKAT_WATCH)
public long setJulianDay(int julianDay) {
// Don't bother with the GMT offset since we don't know the correct
// value for the given Julian day. Just get close and then adjust
// the day.
//long millis = (julianDay - EPOCH_JULIAN_DAY) * DateUtils.DAY_IN_MILLIS;
long millis = (julianDay - Time.EPOCH_JULIAN_DAY) * DAY_IN_MILLIS;
set(millis);
// Figure out how close we are to the requested Julian day.
// We can't be off by more than a day.
int approximateDay = getJulianDay(millis, time.gmtoff);
int diff = julianDay - approximateDay;
time.monthDay += diff;
// Set the time to 12am and re-normalize.
time.hour = 0;
time.minute = 0;
time.second = 0;
millis = time.normalize(true);
return millis;
}
@Implementation(maxSdk = KITKAT_WATCH)
public void set(long millis) {
Calendar c = getCalendar();
c.setTimeInMillis(millis);
set(
c.get(Calendar.SECOND),
c.get(Calendar.MINUTE),
c.get(Calendar.HOUR_OF_DAY),
c.get(Calendar.DAY_OF_MONTH),
c.get(Calendar.MONTH),
c.get(Calendar.YEAR)
);
}
@Implementation(maxSdk = KITKAT_WATCH)
public long toMillis(boolean ignoreDst) {
Calendar c = getCalendar();
return c.getTimeInMillis();
}
@Implementation(maxSdk = KITKAT_WATCH)
public void set(int second, int minute, int hour, int monthDay, int month, int year) {
time.second = second;
time.minute = minute;
time.hour = hour;
time.monthDay = monthDay;
time.month = month;
time.year = year;
time.weekDay = 0;
time.yearDay = 0;
time.isDst = -1;
time.gmtoff = 0;
}
@Implementation(maxSdk = KITKAT_WATCH)
public void set(int monthDay, int month, int year) {
set(0, 0, 0, monthDay, month, year);
}
@Implementation(maxSdk = KITKAT_WATCH)
public void clear(String timezone) {
if (timezone == null) {
throw new NullPointerException("timezone is null!");
}
time.timezone = timezone;
time.allDay = false;
time.second = 0;
time.minute = 0;
time.hour = 0;
time.monthDay = 0;
time.month = 0;
time.year = 0;
time.weekDay = 0;
time.yearDay = 0;
time.gmtoff = 0;
time.isDst = -1;
}
@Implementation(maxSdk = KITKAT_WATCH)
public static String getCurrentTimezone() {
return TimeZone.getDefault().getID();
}
@Implementation(maxSdk = KITKAT_WATCH)
public void switchTimezone(String timezone) {
long date = toMillis(true);
long gmtoff = TimeZone.getTimeZone(timezone).getOffset(date);
set(date + gmtoff);
time.timezone = timezone;
time.gmtoff = (gmtoff / 1000);
}
@Implementation(maxSdk = KITKAT_WATCH)
public static int compare(Time a, Time b) {
long ams = a.toMillis(false);
long bms = b.toMillis(false);
if (ams == bms) {
return 0;
} else if (ams < bms) {
return -1;
} else {
return 1;
}
}
@Implementation(maxSdk = KITKAT_WATCH)
public boolean before(Time other) {
return Time.compare(time, other) < 0;
}
@Implementation(maxSdk = KITKAT_WATCH)
public boolean after(Time other) {
return Time.compare(time, other) > 0;
}
@Implementation(maxSdk = KITKAT_WATCH)
public boolean parse(String timeString) {
TimeZone tz;
if (timeString.endsWith("Z")) {
timeString = timeString.substring(0, timeString.length() - 1);
tz = TimeZone.getTimeZone("UTC");
} else {
tz = TimeZone.getTimeZone(time.timezone);
}
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd'T'HHmmss", Locale.ENGLISH);
SimpleDateFormat dfShort = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
df.setTimeZone(tz);
dfShort.setTimeZone(tz);
time.timezone = tz.getID();
try {
set(df.parse(timeString).getTime());
} catch (ParseException e) {
try {
set(dfShort.parse(timeString).getTime());
} catch (ParseException e2) {
throwTimeFormatException(e2.getLocalizedMessage());
}
}
return "UTC".equals(tz.getID());
}
@Implementation(maxSdk = KITKAT_WATCH)
public String format2445() {
String value = format("%Y%m%dT%H%M%S");
if ( "UTC".equals(time.timezone)){
value += "Z";
}
return value;
}
@Implementation(maxSdk = KITKAT_WATCH)
public String format3339(boolean allDay) {
if (allDay) {
return format("%Y-%m-%d");
} else if ("UTC".equals(time.timezone)) {
return format("%Y-%m-%dT%H:%M:%S.000Z");
} else {
String base = format("%Y-%m-%dT%H:%M:%S.000");
String sign = (time.gmtoff < 0) ? "-" : "+";
int offset = (int) Math.abs(time.gmtoff);
int minutes = (offset % 3600) / 60;
int hours = offset / 3600;
return String.format("%s%s%02d:%02d", base, sign, hours, minutes);
}
}
@Implementation(maxSdk = KITKAT_WATCH)
public boolean parse3339(String rfc3339String) {
SimpleDateFormat formatter = new SimpleDateFormat();
// Special case Date without time first
if (rfc3339String.matches("\\d{4}-\\d{2}-\\d{2}")) {
final TimeZone tz = TimeZone.getTimeZone(time.timezone);
formatter.applyLocalizedPattern("yyyy-MM-dd");
// Make sure we inferFromValue the date in the context of the specified time zone
// instead of the system default time zone.
formatter.setTimeZone(tz);
Calendar calendar = Calendar.getInstance(tz, Locale.getDefault());
try {
calendar.setTime(formatter.parse(rfc3339String));
} catch (java.text.ParseException e) {
throwTimeFormatException(e.getLocalizedMessage());
}
time.second = time.minute = time.hour = 0;
time.monthDay = calendar.get(Calendar.DAY_OF_MONTH);
time.month = calendar.get(Calendar.MONTH);
time.year = calendar.get(Calendar.YEAR);
time.weekDay = calendar.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
time.yearDay = calendar.get(Calendar.DAY_OF_YEAR);
time.isDst = calendar.get(Calendar.DST_OFFSET) != 0 ? 1 : 0;
time.allDay = true;
return false;
}
// Store a string normalized for SimpleDateFormat;
String dateString = rfc3339String
// Look-ahead to remove the colon followed by minutes in timezone
.replaceFirst(":(?=\\d{2}$)", "")
// Look-behind to pad with minutes any timezone only defines hours
.replaceFirst("(?<=[+-]\\d{2})$", "00")
// If it ends with a Z, just replace it with no offset
.replaceFirst("(Z)$", "+0000");
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
formatter.applyLocalizedPattern("yyyy-MM-dd'T'HH:mm:ssZ");
long millisInUtc = time.toMillis(false);
try {
millisInUtc = formatter.parse(dateString).getTime();
} catch (java.text.ParseException e1) {
// Try again with fractional seconds.
formatter.applyLocalizedPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
formatter.setLenient(true);
try {
millisInUtc = formatter.parse(dateString).getTime();
} catch (java.text.ParseException e2) {
throwTimeFormatException(e2.getLocalizedMessage());
}
}
// Clear to UTC, then set time;
clear("UTC");
set(millisInUtc);
return true;
}
private void throwTimeFormatException(String optionalMessage) {
throw ReflectionHelpers.callConstructor(TimeFormatException.class, from(String.class, optionalMessage == null ? "fail" : optionalMessage));
}
@Implementation(maxSdk = KITKAT_WATCH)
public String format(String format) {
return Strftime.format(format, new Date(toMillis(false)), Locale.getDefault(), TimeZone.getTimeZone(time.timezone));
}
private Calendar getCalendar() {
Calendar c = Calendar.getInstance(TimeZone.getTimeZone(time.timezone));
c.set(time.year, time.month, time.monthDay, time.hour, time.minute, time.second);
c.set(Calendar.MILLISECOND, 0);
return c;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy