Metric based on the time offset period ideas

One, background

Recent changes in the project bug, met a class of problems: the month starts on the case can be set (the 1st to the 28th), you need to calculate the relevant time frame corresponding month, quarter, year, etc., as well as the corresponding month, last quarter, last year, etc., and all kinds of time given timestamp belongs year, quarter, month, etc. strike.

For simplicity, give chestnuts: as if the start date is set became 5 months, so this month timeframe is:

2019.10.05 00:00:00 - 2019.11.04 23:59:59
复制代码

Time this quarter are:

2019.10.05 00:00:00 - 2020.01.04 23:59:59
复制代码

A large number of local projects need to use such calculations. Thus, the corresponding time acquisition tools are packaged in a. Which in itself is no problem, but the problem lies in a package for each tool class acquisition period wording varied, e.g. month obtaining start time, the start time of the next quarter, etc. The method of thinking different, plus different people have to realize they need a method, therefore, the whole look down tools, one is not well understood, and second, all kinds of hidden bug.

Most appear, various boundary is determined, the various processes and the corresponding logic. .

There is no simpler way to do that?

In fact, there is.


Second, ideas and implementation

2.1 ideas

Whether month start date is set to one day, when any logical calculation related to doing monthly start date, in fact, can be taken to achieve a common idea that the time offset correction and regression. For example, no matter how much the current timestamp, to calculate the starting time of the quarter, directly to the first time stamp correction, and then calculate the season starting time in the natural concept of time corresponding to the time difference and finally covering the corresponding namely can.

2.2 realized

Talk is cheap. Show me the code.
复制代码

/**
 *  根据月起始日,计算对应时间戳的季度开始时间
 *
 * @param monthStart
 * @param timeStamp
 * @return
 */
public static long getFixedQuarterBeginTimeBySetting(int monthStart, long timeStamp){
    Calendar c = Calendar.getInstance();
    c.setTimeInMillis(timeStamp);

    // 修正偏移时间
    c.add(Calendar.DAY_OF_MONTH, -monthStart + 1);

    // 获得修正后的自然季度开始时间
    long fixedNatureQuarterBeginTime = DateUtils.getNatureQuarterBeginTimeInMillis(c.getTimeInMillis());
    c.setTimeInMillis(fixedNatureQuarterBeginTime);

    // 回补月起始日
    c.add(Calendar.DAY_OF_MONTH, monthStart - 1);

    return c.getTimeInMillis();
}

/**
 *  根据月起始日,计算对应时间戳的季度结束时间
 *
 * @param monthStart
 * @param timeStamp
 * @return
 */
public static long getFixedQuarterEndTimeBySetting(int monthStart, long timeStamp){
    // 获取季度开始时间
    long fixedQuarterBeginTime = getFixedQuarterBeginTimeBySetting(monthStart, timeStamp);

    Calendar c = Calendar.getInstance();
    c.setTimeInMillis(fixedQuarterBeginTime);
    // 月份加3
    c.add(Calendar.MONTH, 3);

    // 时间戳退1
    return c.getTimeInMillis() - 1;
}

/**
 *  根据月起始日,计算对应时间戳的上个季度开始时间
 *
 * @param monthStart
 * @param timeStamp
 * @return */ public static long getFixedLastQuarterBeginTimeBySetting(int monthStart, long timeStamp){ long fixedQuarterBeginTime = getFixedQuarterBeginTimeBySetting(monthStart, timeStamp); return getFixedQuarterBeginTimeBySetting(monthStart, fixedQuarterBeginTime - 1); } /** * 根据月起始日,计算对应时间戳的上个季度结束时间 * * @param monthStart * @param timeStamp * @return */ public static long getFixedLastQuarterEndTimeBySetting(int monthStart, long timeStamp){ long fixedQuarterEndTime = getFixedQuarterBeginTimeBySetting(monthStart, timeStamp); return fixedQuarterEndTime - 1; } /** * 根据月起始日,计算对应时间戳的年开始时间 * * @param monthStart * @param timeStamp * @return */ public static long getFixedYearBeginTimeBySetting(int monthStart, long timeStamp) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timeStamp); // 修正偏差 calendar.add(Calendar.DAY_OF_MONTH, -monthStart + 1); // 获取修正偏差后的自然时间 long fixedNatureYearBeginTime = DateUtils.getNatureYearBeginTime(calendar.getTimeInMillis()); calendar.setTimeInMillis(fixedNatureYearBeginTime); // 回补月起始日 calendar.add(Calendar.DAY_OF_MONTH, monthStart - 1); return calendar.getTimeInMillis(); } 复制代码

Very easy, we will time the complex calculations might otherwise be required, all based on the same idea, namely natural time period after the time stamp of the time offset correction and regression, transformed into seek correction, and finally return the final result you want.

Such a most obvious benefit is that the entire tool class implements the idea is exactly the same, and when the strike period of time, under normal circumstances, would not be a bug produces, after understanding this line of thinking, regardless of the starting month seeking What day of the corresponding time period, the code is also very simple to achieve.


Third, the conclusion

Change the time period of January start date due, because the month has been changed at the starting date. The so-called trouble should end it, its logic and every package, do various boundary calculation process, there will be even fix various inexplicable bug. It might as well focus more on the idea of ​​January start date itself, to seek more common method of calculation.

end~


Author: HappyCorn
link: https: //juejin.im/post/5db188586fb9a020531fab1d
Source: Nuggets
copyright reserved by the authors. Commercial reprint please contact the author authorized, non-commercial reprint please indicate the source.

Guess you like

Origin www.cnblogs.com/lwbqqyumidi/p/11991810.html