Я хотел бы, чтобы элегантный способ округлить дату Java вверх или вниз до ближайшей минуты (или второй, час, день).
Например, дата "Wed Jan 25 10:36:34 GMT 2012", округленная до ближайшей минуты, будет "Wed Jan 25 10:37:00 GMT 2012"
Я хотел бы, чтобы элегантный способ округлить дату Java вверх или вниз до ближайшей минуты (или второй, час, день).
Например, дата "Wed Jan 25 10:36:34 GMT 2012", округленная до ближайшей минуты, будет "Wed Jan 25 10:37:00 GMT 2012"
Если вы используете Apache commons-lang, вы можете использовать DateUtils для вокруг ваших дат:
Date now = new Date();
Date nearestMinute = DateUtils.round(now, Calendar.MINUTE);
Способ сделать это без сторонних библиотек (может быть, не настолько изящный и не очень гибкий): добавьте половину поля (для округления на минуты - 30 секунд) и установите это поле и нижние к нулю.
Calendar calendar = ... // assume you already have it with a specified Date value
// 'add' cause changing larger fields if necessary
calendar.add( Calendar.SECOND, 30 );
calendar.set( Calendar.SECOND, 0 );
calendar.set( Calendar.MILLISECOND, 0 );
Если текущее значение меньше 30 секунд, значение "минута" не изменится на "добавить". В противном случае он будет увеличен на 1. В любом случае, секунды и более низкие значения обнуляются. Итак, у нас есть округление.
Вы можете использовать Apache-commons 'DateUtils
.
import org.apache.commons.lang.time.FastDateFormat;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
FastDateFormat dtFormat = DateFormatUtils.ISO_DATETIME_FORMAT;
Date now = new Date( );
Date nearestHour = DateUtils.round( now, Calendar.HOUR );
Date nearestDay = DateUtils.round( now, Calendar.DAY_OF_MONTH );
Date nearestYear = DateUtils.round( now, Calendar.YEAR );
System.out.println( "Now: " + dtFormat.format( now ) );
System.out.println( "Nearest Hour: " + dtFormat.format( nearestHour ) );
System.out.println( "Nearest Day: " + dtFormat.format( nearestDay ) );
System.out.println( "Nearest Year: " + dtFormat.format( nearestYear )
Лучшее решение - использовать DateUtils из общих ресурсов Apache. Однако, если вы хотите избежать их импорта, это будет решение на Java. Не уверен, что это означает, что это "элегантное решение" означает.
/**
Takes given date and returns date rounded to nearest minute
*/
public Date roundToMin(Date d){
Calendar date = new GregorianCalendar();
date.setTime(d);
int deltaMin = date.get(Calendar.SECOND)/30;
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);
date.add(Calendar.MINUTE, deltaMin);
return date.getTime();
}
Я пытаюсь не использовать дополнительные библиотеки, если я могу добиться этого с помощью простой Java:
new Date( ((new Date().getTime() + 500) / 1000) * 1000 )
Добавление баннера commons-lang только для округления даты - это не очень хорошая идея, я предпочитаю эту функцию:
public static Date round(Date d) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");
return sdf.parse(sdf.format(d));
} catch (ParseException ex) {
//This exception will never be thrown, because sdf parses what it formats
return d;
}
}
В следующей функции "roundBy" можно округлить дату
опционально по секундам/минутам/часам/дням.
Это может быть неточным, но идея ясна, надеюсь
public static final long MILLISECONDS_IN_SECOND = (long)(1000); public static final long MILLISECONDS_IN_MINUTE = (MILLISECONDS_IN_SECOND * 60); public static final long MILLISECONDS_IN_HOUR = (MILLISECONDS_IN_MINUTE * 60); public static final long MILLISECONDS_IN_DAY = (MILLISECONDS_IN_HOUR * 24);
public synchronized static Date roundBy(Date date, long UNIT) {
long time = date.getTime();
long timeOutOfUnit= time % UNIT;
time -= timeOutOfUnit;
if(timeOutOfUnit >= (UNIT / 2)) {
time += UNIT;
}
return new Date(time);
}
Для округления вверх/вниз с помощью Apache commons-lang вы можете использовать следующие методы:
DateUtils.ceiling(date, Calendar.HOUR)
DateUtils.truncate(date, Calendar.HOUR)
DateUtils.round(date, Calendar.HOUR)
Смотрите примеры:
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String sDate1 = "11-05-2019 19:01:00";
Date date1 = formatter.parse(sDate1);
System.out.println(DateUtils.round(date1, Calendar.HOUR)); // Sat May 11 19:00:00 MSK 2019
System.out.println(DateUtils.truncate(date1, Calendar.HOUR)); // Sat May 11 19:00:00 MSK 2019
System.out.println(DateUtils.ceiling(date1, Calendar.HOUR)); // Sat May 11 20:00:00 MSK 2019
String sDate2 = "11-05-2019 19:29:00";
Date date2 = formatter.parse(sDate2);
System.out.println(DateUtils.round(date2, Calendar.HOUR)); // Sat May 11 19:00:00 MSK 2019
System.out.println(DateUtils.truncate(date2, Calendar.HOUR)); // Sat May 11 19:00:00 MSK 2019
System.out.println(DateUtils.ceiling(date2, Calendar.HOUR)); // Sat May 11 20:00:00 MSK 2019
String sDate3 = "11-05-2019 19:30:00";
Date date3 = formatter.parse(sDate3);
System.out.println(DateUtils.round(date3, Calendar.HOUR)); // Sat May 11 20:00:00 MSK 2019
System.out.println(DateUtils.truncate(date3, Calendar.HOUR)); // Sat May 11 19:00:00 MSK 2019
System.out.println(DateUtils.ceiling(date3, Calendar.HOUR)); // Sat May 11 20:00:00 MSK 2019
String sDate4 = "11-05-2019 19:31:00";
Date date4 = formatter.parse(sDate4);
System.out.println(DateUtils.round(date4, Calendar.HOUR)); // Sat May 11 20:00:00 MSK 2019
System.out.println(DateUtils.truncate(date4, Calendar.HOUR)); // Sat May 11 19:00:00 MSK 2019
System.out.println(DateUtils.ceiling(date4, Calendar.HOUR)); // Sat May 11 20:00:00 MSK 2019
String sDate5 = "11-05-2019 19:59:00";
Date date5 = formatter.parse(sDate5);
System.out.println(DateUtils.round(date5, Calendar.HOUR)); // Sat May 11 20:00:00 MSK 2019
System.out.println(DateUtils.truncate(date5, Calendar.HOUR)); // Sat May 11 19:00:00 MSK 2019
System.out.println(DateUtils.ceiling(date5, Calendar.HOUR)); // Sat May 11 20:00:00 MSK 2019
Если вам нужно округлить минуты, вы можете сделать это: int минуты = минуты - (минуты% n);
если хотите округлить минуты на 5, то n = 5.