以前在学校做课程设计的时候,有两个算法特别有趣,在这里留个底,以备不时之需。

第一个算法是自动获取本地当前时间的算法,无需手动输入。由于各种不同语言获取的方法各不相同,这里不做介绍,上网搜一下即可。

第二个算法是时间差算法。像很多课程设计一般都搞「停车场管理系统」、「图书馆管理系统」之类的需要计算时间差的系统,这个算法就十分重要了。

即使到了制作在线商城等高级系统时,也是需要计算时间差的,毕竟像淘宝的订单系统也是要计算 15 天自动收货的。

Talk is cheap, show you the code!

public static double TimeDiff(int startYear, int startMonth, int startDay, int startHour, int startMinute, int endYear, int endMonth, int endDay, int endHour, int endMinute) {
    int y, m, d;
    int Y, M, D;
    int Day, Hour, Minute;
    double time;
    
    m = (startMonth + 9) % 12;      // 用于判断日期是否大于 3 月(2 月是判断闰年的标识),还用于纪录到 3 月的间隔月数
    y = startYear - m / 10;     // 如果是 1 月和 2 月,则不包括当前年,因为是计算到 0 年 3 月 1 日的天数
    d = 365 * y + y / 4 - y / 100 + y / 400 + (m * 306 + 5) / 10 + (startDay - 1);      // 365 * y 是不算闰年多出那一天的天数;y / 4 - y / 100 + y / 400 是加所有闰年多出的那一天;(m * 306 + 5) / 10 用于计算当前月到 3 月 1 日间的天数,306 = 365 - 31 - 28(1 月和 2 月),5 是全年中不是 31 天月份的个数;startDay - 1 用于计算当前日到 1 日的间隔天数
    
    M = (endMonth + 9) % 12;
    Y = endYear - M / 10;
    D = 365 * Y + Y / 4 - Y / 100 + Y / 400 + (M * 306 + 5) / 10 + (endDay - 1);
    
    Day = D - d;
    Hour = 24 * Day + endHour - startHour;
    
    if (endMinute - startMinute < 0) {
        Hour--;
        Minute = endMinute + 60 - startMinute;
    } else {
        Minute = endMinute - startMinute;
    }
    
    time = (double) Hour + ((double) Minute) / 60;
    
    return time;
}

因为每个月的天数不同,因此采用直接相减的方法明显是不合理的。

该算法总体思想是计算给定日期到 0 年 3 月 1 日的天数,然后相减,获取天数的间隔。

即采取一个参照点,然后计算两个时间到同一参照点的时间差,再相减获得天数的间隔。

由于折算的单位是天数,因此 D - d 则可获得天数差。

小时差的计算里用到了天数作为借位,如果天数不足 1 天,即 24 * Day0,则没有借位。

同样,在分钟差的计算中,如果差小于 0,则需向小时借位。

这里只精确到分钟的计算,并且最终把结果转为以小时为单位的浮点数。

各位可以根据需要调整精确度和单位。

时间差算法一般和自动获取时间的算法一同使用,课程设计中可视情况采用手动输入时间的方式,但自动获取本地时间相对来说更接近应用层面,而这也恰好是课程设计中的一个重要评分点。