высокопроизводительная функция для арифметики даты - PullRequest
0 голосов
/ 13 февраля 2011

Мне нужно написать высокопроизводительную функцию, которая вычисляет новое время и дату на основе заданного времени и даты. Он принимает 2 аргумента:

  1. Строка, представляющая дату в формате ГГГГММДДЧЧмм
  2. Целое число, представляющее временной сдвиг в часах

Функция возвращает строку в формате 1-го аргумента, которая составляется в результате применения временного сдвига к 1-му аргументу

Заранее известно, что первый аргумент всегда остается неизменным в течение времени жизни программы.

Моя реализация имеет следующие шаги:

  • парсинг 1-го аргумента для извлечения года, месяца, даты, часов, мин.
  • создание объекта GregorianCalendar (год, месяц, дата, часы, мин)
  • применение метода GregorianCalendar.add (HOUR, timeshift)
  • применение SimpleDateFormat для преобразования результата обратно в строку

Проблема в том, что я не пользуюсь тем фактом, что 1-й аргумент всегда один и тот же. Если я создам члена класса GregorianCalendar (год, месяц, дата, часы, мин), то после 1-го вызова моей функции этот объект будет изменен, что не очень хорошо, потому что я не могу использовать его для следующих вызовов.

Ответы [ 5 ]

2 голосов
/ 13 февраля 2011

Если вы можете, используйте библиотеку Joda-Time , которая делает арифметику дат очень простой:

  DateTime dt = new DateTime();
  DateTime twoHoursLater = dt.plusHours(2);

У них есть класс DateTimeFormatter, который вы будете использовать для выполнениясинтаксический анализ вашей входной строки даты и времени в DateTime, например:

  DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMddHHmm");
  DateTime dt = fmt.parseDateTime(myDateString);
  DateTime result = dt.plusHours(myTimeshiftInHours);

И Joda-Time также хорошо взаимодействует с java.util.Date.Я люблю это!

0 голосов
/ 13 февраля 2011

Если вы просто хотите избежать повторения шага 1 (и, возможно, 2) снова и снова, проанализируйте дату один раз, затем сохраните полученную дату.Затем вы можете применить эту дату к своему календарю (с помощью setDate ()) перед каждым шагом add (или создать новый GregorianCalendar, если это имеет значение).

0 голосов
/ 13 февраля 2011

Я бы попробовал простое запоминание:

// This is not thread safe.  Either give each thread has its own 
// (thread confined) converter object, or make the class threadsafe.
public class MyDateConverter {

    private String lastDate;
    private int lastShift;
    private String lastResult;

    public String shiftDate(String date, int shift) {
        if (shift == lastShift && date.equals(lastDate)) {
            return lastResult;
        }
        // Your existing code here
        lastDate = date; 
        lastShift = shift
        lastResult = result;
        return result;
    }
}

Обратите внимание, что этот простой подход наиболее эффективен, если значения shift и date редко изменяются. Если какой-либо из них часто изменяется, вам потребуется более сложный кэш, код будет более сложным, а накладные расходы (в случае пропуска кэша) будут выше.

0 голосов
/ 13 февраля 2011

Если первый аргумент является значением, которое не будет часто меняться, возможно, используйте кеш:

static private Map<String,Calendar> dateCache = new HashMap<String,Calendar>();

Затем в вашем методе проверка первого аргумента (например: String dateStr)введите в кэш

Calendar cal;
if (dateCache.containsKey(dateStr)) {
    cal = (Calendar)(dateCache.get(dateStr)).clone();
} else {
    // parse date
    cal = new GregorianCalendar(...);
    dateCache.put(dateStr, (Calendar)cal.clone());
}

и добавьте значение вашего временного сдвига.

0 голосов
/ 13 февраля 2011

Как насчет этого,

  1. Синтаксический анализ и удержание вашей фиксированной даты, назовите ее fixedDate
  2. Пусть timeShift будет временной сдвиг в часах, затем Date shiftedDate = new Date(fixedDate.getTime() + (timeShift * 3600000)) будет вашей вычисленной смещенной датой (см. это и это для понимания)
  3. Примените SimpleDateFormat для преобразования shiftedDate в строку.

Повторять шаги 2 и 3 бесконечно, fixedDate не изменяется и может быть использован повторно.

...