Skip to content

Instantly share code, notes, and snippets.

@electrum
Created March 24, 2010 23:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save electrum/342985 to your computer and use it in GitHub Desktop.
Save electrum/342985 to your computer and use it in GitHub Desktop.
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.TimeZone;
public class FastDateFormatter
{
private static final byte[][] DATES = new byte[24837][]; // days in [1970, 2038)
private static final byte[] DIGITS = toUtf8("0123456789");
private static final long MS_PER_DAY = 24L * 60L * 60L * 1000L;
private static final long MS_PER_HOUR = 60L * 60L * 1000L;
private static final long MS_PER_MINUTE = 60L * 1000L;
static {
for (int i = 0; i < DATES.length; i++) {
long t = i * MS_PER_DAY;
DATES[i] = toUtf8(formatDateSlow(t).substring(0, 10));
assert formatDateSlow(t).substring(11).equals("00:00:00.000");
}
}
@SuppressWarnings({"NumericCastThatLosesPrecision"})
public static byte[] formatDate(long t)
{
long save = t;
// days from epoch start
long days = t / MS_PER_DAY;
// fallback if outside pre-computed range
if ((t < 0) || (days >= DATES.length)) {
return toUtf8(formatDateSlow(t));
}
// remove days
t %= MS_PER_DAY;
// extract time
int hour = (int) (t / MS_PER_HOUR);
t %= MS_PER_HOUR;
int min = (int) (t / MS_PER_MINUTE);
t %= MS_PER_MINUTE;
int sec = (int) (t / 1000L);
int msec = (int) (t % 1000L);
assert (hour < 24) && (min < 60) && (sec < 60) && (msec < 1000);
// format date and time (YYYY-MM-DD hh:mm:ss.SSS)
byte[] b = new byte[23];
System.arraycopy(DATES[((int) days)], 0, b, 0, 10);
b[10] = (byte) ' ';
b[11] = DIGITS[hour / 10];
b[12] = DIGITS[hour % 10];
b[13] = (byte) ':';
b[14] = DIGITS[min / 10];
b[15] = DIGITS[min % 10];
b[16] = (byte) ':';
b[17] = DIGITS[sec / 10];
b[18] = DIGITS[sec % 10];
b[19] = (byte) '.';
b[20] = DIGITS[msec / 100];
b[21] = DIGITS[(msec % 100) / 10];
b[22] = DIGITS[msec % 10];
assert Arrays.equals(b, toUtf8(formatDateSlow(save)));
return b;
}
private static String formatDateSlow(long t)
{
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
return format.format(new Date(t));
}
private static byte[] toUtf8(String s)
{
return s.getBytes(Charset.forName("UTF-8"));
}
public static void main(String[] args)
{
System.out.println(new String(formatDate(1269465111345L), Charset.forName("UTF-8")));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment