package st.gravel.support.jvm;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class TimeExtensions {
private static final BigInteger ONE_MILLION = BigInteger.valueOf(1000000);
private static final long nanoOffset = calculateNanoOffset();
public static long nanosecondClock() {
return System.nanoTime() + nanoOffset;
}
public static long clockPrecisionNS() {
long sample = System.nanoTime();
long prec = Long.MAX_VALUE;
for (int samples = 0; samples < 10;) {
long diff = System.nanoTime() - sample;
if (diff > 0) {
prec = Math.min(diff, prec);
samples++;
}
}
System.out.println(prec);
return prec;
}
public static TimeZone defaultTimeZone() {
return TimeZone.getDefault();
}
public static TimeZone getTimeZoneNamed_(String name) {
return TimeZone.getTimeZone(name);
}
public static TimeZone getTimeZoneForOffsetMS_(int ms) {
String[] availableIDs = TimeZone.getAvailableIDs(ms);
if (availableIDs.length == 0)
throw new RuntimeException("No timezone for offset: " + ms);
return getTimeZoneNamed_(availableIDs[0]);
}
public static Calendar newCalendar_timeZone_(long millis, TimeZone timeZone) {
Calendar calendar = Calendar.getInstance(timeZone);
calendar.setTimeInMillis(millis);
return calendar;
}
public static Calendar newCalendarFromString_(String str) throws ParseException {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS");
cal.setTime(sdf.parse(str));
return cal;
}
public static int year(Calendar cal) {
return cal.get(Calendar.YEAR);
}
public static int monthIndex(Calendar cal) {
return cal.get(Calendar.MONTH)+1;
}
public static int dayOfMonth(Calendar cal) {
return cal.get(Calendar.DAY_OF_MONTH);
}
public static int dayOfYear(Calendar cal) {
return cal.get(Calendar.DAY_OF_YEAR);
}
public static int hour(Calendar cal) {
return cal.get(Calendar.HOUR_OF_DAY);
}
public static int minute(Calendar cal) {
return cal.get(Calendar.MINUTE);
}
public static int second(Calendar cal) {
return cal.get(Calendar.SECOND);
}
public static boolean isLeapYear(Calendar cal) {
return new GregorianCalendar().isLeapYear(year(cal));
}
private static long calculateNanoOffset() {
long currentTimeMillis = System.currentTimeMillis();
long nanoTime = System.nanoTime();
return (currentTimeMillis * 1000000) - nanoTime;
}
public static Object waitForNanoseconds(final Object receiver,
Object nanosecondsObject) {
long timeout;
int nanos;
if (nanosecondsObject instanceof BigInteger) {
final BigInteger nanoseconds = (BigInteger) nanosecondsObject;
timeout = nanoseconds.divide(ONE_MILLION).longValue();
nanos = nanoseconds.remainder(ONE_MILLION).intValue();
} else if (nanosecondsObject instanceof Integer) {
final int nanoseconds = (Integer) nanosecondsObject;
timeout = nanoseconds / 1000000;
nanos = nanoseconds % 1000000;
} else {
throw new RuntimeException("Unknown parameter type");
}
try {
synchronized (receiver) {
receiver.wait(timeout, nanos);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return receiver;
}
}