日期算术的高性能函数

时间:2011-02-13 00:38:25

标签: java datetime

我需要编写高性能函数,根据给定的datetime和timeshift计算新的datetime。它接受2个论点:

  1. 字符串,以YYYYMMDDHHmm格式表示日期
  2. 整数,表示以小时为单位的时移
  3. 函数以第一个参数的格式返回字符串,该第一个参数是将timeshift应用于第一个参数的结果

    事先已知,第一个参数在程序生命周期内始终是相同的。

    我的实施有以下步骤:

    • 解析第一个参数以提取年,月,日,小时,分
    • 创建GregorianCalendar(年,月,日,小时,分钟)对象
    • 申请方法GregorianCalendar.add(HOUR,timeshift)
    • 应用SimpleDateFormat将结果转换回字符串

    问题是我没有利用第一个参数始终相同的事实。 如果我将创建一个类成员GregorianCalendar(年,月,日,小时,分钟),那么在第一次调用我的函数之后,这个对象将被修改,这是不好的,因为我不能将它重用于以下调用。

5 个答案:

答案 0 :(得分:2)

如果可以,请使用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很好地互操作。我喜欢它!

答案 1 :(得分:0)

这个怎么样,

  1. 解析并按住您的固定日期,将其称为fixedDate
  2. timeShift以小时为单位进行时移,然后Date shiftedDate = new Date(fixedDate.getTime() + (timeShift * 3600000))将是您计算的转移日期(请参阅thisthis以获取理解)
  3. 应用SimpleDateFormat将shiftedDate转换为字符串。
  4. 无限期地重复步骤2和3,fixedDate未被修改,可以重复使用。

答案 2 :(得分:0)

如果第一个参数是一个不会经常更改的值,可能使用缓存:

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());
}

并添加你的时移价值。

答案 3 :(得分:0)

我会尝试简单的记忆:

// 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;
    }
}

请注意,如果shiftdate值很少发生变化,这种简单方法最有效。如果频繁更改,则需要更复杂的缓存,代码将更复杂,并且开销(对于缓存未命中)将更高。

答案 4 :(得分:0)

如果您只是想避免一次又一次地重复步骤1(可能是2),请解析日期一次,然后保存您获得的日期。然后,您可以在每个add步骤之前将此日期应用于日历(使用setDate())(或创建新的GregorianCalendar,测量是否重要)。