Is there any fast way to create DateTime instance and set minutes\seconds\millis to 0? At this moment I am using the following code:
private DateTime createDateTime(java.util.Date date, org.joda.time.Chronology chronology) {
DateTime dateTime = new DateTime(date, chronology);
dateTime = dateTime.withMinuteOfHour(0);
dateTime = dateTime.withSecondOfMinute(0);
dateTime = dateTime.withMillisOfSecond(0);
return dateTime;
}
But when it invokes about 200.000 times, dateTime.with***(0); takes a lot of time. Probably there is more correct solution?
So the short answer to your question is: YES (deprecated).
Joda-Time is an API created by joda.org which offers better classes and having efficient methods to handle date and time than classes from java. util package like Calendar, Gregorian Calendar, Date, etc. This API is included in Java 8.0 with the java.
Adjusting Time ZoneUse the DateTimeZone class in Joda-Time to adjust to a desired time zone. Joda-Time uses immutable objects. So rather than change the time zone ("mutate"), we instantiate a new DateTime object based on the old but with the desired difference (some other time zone). Use proper time zone names.
Joda-Time provides a comprehensive formatting system. There are two layers: High level - pre-packaged constant formatters. Mid level - pattern-based, like SimpleDateFormat.
Maybe like this?
// Truncate minutes/seconds/milliseconds from the date's timestamp
long truncatedTimestamp = date.getTime() - date.getTime() % 3600000;
DateTime dateTime = new DateTime(truncatedTimestamp, chronology);
Why is this faster?
DateTime
constructorDateTime
constructor and 3 more normalisations (expensive), every time you set some date part to 0
Hence, you probably can't beat modulo. As others pointed out, this might lead to incorrect results in very remote corner-cases where hours don't count 60 seconds (e.g. due to leap seconds), although I fail to see how, as the unix timestamp can always be truncated to zero, to get the beginning of a calendar hour (examples welcome).
Just tried the code below - it looks like method 1 (yours) takes about 320ms on my pc, vs method 2 (mine) 390ms, vs method 3 (Lukas's) 15ms, vs method 4 (MutableDateTime) 310ms... Now the modulo might (?) lead to incorrect results.
public class Test {
private static int NUM_RUN;
public static void main(String[] args) {
Date date = new Date();
List<Runnable> list = new ArrayList<>();
list.add(method3Withs(date));
list.add(method1With(date));
list.add(methodModulo(date));
list.add(methodMutable(date));
NUM_RUN = 100_000;
for (Runnable r : list) {
long start = System.nanoTime();
r.run();
long end = System.nanoTime();
System.out.println((end - start) / 1000000);
}
NUM_RUN = 10_000_000;
for (Runnable r : list) {
long start = System.nanoTime();
r.run();
long end = System.nanoTime();
System.out.println((end - start) / 1000000);
}
}
private static Runnable method3Withs(final Date date) {
return new Runnable() {
@Override
public void run() {
DateTime d2 = null;
for (int i = 0; i < NUM_RUN; i++) {
d2 = new DateTime(date);
d2 = d2.withMinuteOfHour(0);
d2 = d2.withSecondOfMinute(0);
d2 = d2.withMillisOfSecond(0);
}
System.out.println(d2);
}
};
}
private static Runnable method1With(final Date date) {
return new Runnable() {
@Override
public void run() {
DateTime d2 = null;
for (int i = 0; i < NUM_RUN; i++) {
d2 = new DateTime(date);
d2 = d2.withTime(d2.getHourOfDay(), 0, 0, 0);
}
System.out.println(d2);
}
};
}
private static Runnable methodModulo(final Date date) {
return new Runnable() {
@Override
public void run() {
DateTime d2 = null;
for (int i = 0; i < NUM_RUN; i++) {
long truncatedTimestamp = date.getTime() - date.getTime() % 3600000;
d2 = new DateTime(truncatedTimestamp);
}
System.out.println(d2);
}
};
}
private static Runnable methodMutable(final Date date) {
return new Runnable() {
@Override
public void run() {
MutableDateTime m = null;
for (int i = 0; i < NUM_RUN; i++) {
m = new MutableDateTime(date);
m.setMinuteOfHour(0);
m.setSecondOfMinute(0);
m.setMillisOfSecond(0);
}
System.out.println(m);
}
};
}
}
EDIT
I made it 10 million runs after a warm up round of 100,000:
3037
4068
88
2864
The modulo method wins by a large margin, so it seems safe to think it will perform much better in most situations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With