应用iCalendar库Biweekly求2021年工作日及油价调整时间

应用iCalendar库Biweekly求2021年工作日及油价调整时间

iCalendar有关于重复日程的描述,这里尝试使用这方面描述,并结合iCalendar库Biweekly进行编程。选定描述2021年工作日,求出具体日期,再计算2021年油价调整日期作为应用案例。

工作日分成3部分:

  1. 周一到周五
  2. 调班
  3. 调休

周一到周五就用RRULE描述成以星期为周期,直到年底:RRULE:FREQ=WEEKLY;UNTIL=20211231T00000Z;WKST=MO;BYDAY=MO,TU,WE,TH,FR。调班就是周六日休假调整成上班时间,属于增加工作日,用RDATE表示;调休是节日遇上周一到五,要从工作日中去除,所以用EXDATE表示。根据国务院网站《国务院办公厅关于2021年部分节假日安排的通知》

2021年元旦、春节、清明节、劳动节、端午节、中秋节和国庆节放假调休日期的具体安排通知如下。

一、元旦:2021年1月1日至3日放假,共3天。

二、春节:2月11日至17日放假调休,共7天。2月7日(星期日)、2月20日(星期六)上班。

三、清明节:4月3日至5日放假调休,共3天。

四、劳动节:5月1日至5日放假调休,共5天。4月25日(星期日)、5月8日(星期六)上班。

五、端午节:6月12日至14日放假,共3天。

六、中秋节:9月19日至21日放假调休,共3天。9月18日(星期六)上班。

七、国庆节:10月1日至7日放假调休,共7天。9月26日(星期日)、10月9日(星期六)上班。

  • 调班描述为:RDATE;VALUE=DATE:20210207,20210220,20210425,20210508,20210918,20210926,20211009
  • 调休描述为:EXDATE;VALUE=DATE:20210101,20210211,20210212,20210215,20210216,20210217,20210405,20210503,20210504,20210505,20210614,20210920,20210921,20211001,20211004,20211005,20211006,20211007

写成iCalendar文件workday2021.ics,就是:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Michael Angstadt//biweekly 0.6.3//EN
BEGIN:VEVENT
UID:c6e311c1-cbfe-451e-9548-b7bf575fbfcc
DTSTAMP:20200724T231040Z
SUMMARY:工作日
RRULE:FREQ=WEEKLY;UNTIL=20211231T00000Z;WKST=MO;BYDAY=MO,TU,WE,TH,FR
RDATE;VALUE=DATE:20210207,20210220,20210425,20210508,20210918,20210926,20211009
EXDATE;VALUE=DATE:20210101,20210211,20210212,20210215,20210216,20210217,20210405,20210503,20210504,20210505,20210614,20210920,20210921,20211001,20211004,20211005,20211006,20211007
DTSTART;VALUE=DATE:20210101
DTEND;VALUE=DATE:20211231
END:VEVENT
END:VCALENDAR

然后就用Biweekly库来得到工作日的具体日期。下面是Java源码:

File file = new File("workday2021.ics");
List<ICalendar> icals = Biweekly.parse(file).all();
ICalendar ical = icals.get(0); // get first calendar

VEvent event = ical.getEvents().get(0);
DateStart dtstart = event.getDateStart();

TimeZone timezone;
TimezoneInfo tzinfo = ical.getTimezoneInfo();

if (tzinfo.isFloating(dtstart)){
    timezone = TimeZone.getDefault();
} else {
    TimezoneAssignment dtstartTimezone = tzinfo.getTimezone(dtstart);
    timezone = (dtstartTimezone == null) ? TimeZone.getTimeZone("UTC") : dtstartTimezone.getTimeZone();
}
DateIterator it = event.getDateIterator(timezone);
List<String> dates = new ArrayList<String>();
while (it.hasNext()) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    dates.add(sdf.format(it.next()));
}
System.out.println(String.join(",", dates)); // 输出工作日

运行得到2021年工作日具体日期:

20210104,20210105,20210106,20210107,20210108,20210111,20210112,20210113,20210114,20210115,20210118,20210119,20210120,20210121,20210122,20210125,20210126,20210127,20210128,20210129,20210201,20210202,20210203,20210204,20210205,20210207,20210208,20210209,20210210,20210218,20210219,20210220,20210222,20210223,20210224,20210225,20210226,20210301,20210302,20210303,20210304,20210305,20210308,20210309,20210310,20210311,20210312,20210315,20210316,20210317,20210318,20210319,20210322,20210323,20210324,20210325,20210326,20210329,20210330,20210331,20210401,20210402,20210406,20210407,20210408,20210409,20210412,20210413,20210414,20210415,20210416,20210419,20210420,20210421,20210422,20210423,20210425,20210426,20210427,20210428,20210429,20210430,20210506,20210507,20210508,20210510,20210511,20210512,20210513,20210514,20210517,20210518,20210519,20210520,20210521,20210524,20210525,20210526,20210527,20210528,20210531,20210601,20210602,20210603,20210604,20210607,20210608,20210609,20210610,20210611,20210615,20210616,20210617,20210618,20210621,20210622,20210623,20210624,20210625,20210628,20210629,20210630,20210701,20210702,20210705,20210706,20210707,20210708,20210709,20210712,20210713,20210714,20210715,20210716,20210719,20210720,20210721,20210722,20210723,20210726,20210727,20210728,20210729,20210730,20210802,20210803,20210804,20210805,20210806,20210809,20210810,20210811,20210812,20210813,20210816,20210817,20210818,20210819,20210820,20210823,20210824,20210825,20210826,20210827,20210830,20210831,20210901,20210902,20210903,20210906,20210907,20210908,20210909,20210910,20210913,20210914,20210915,20210916,20210917,20210918,20210922,20210923,20210924,20210926,20210927,20210928,20210929,20210930,20211008,20211009,20211011,20211012,20211013,20211014,20211015,20211018,20211019,20211020,20211021,20211022,20211025,20211026,20211027,20211028,20211029,20211101,20211102,20211103,20211104,20211105,20211108,20211109,20211110,20211111,20211112,20211115,20211116,20211117,20211118,20211119,20211122,20211123,20211124,20211125,20211126,20211129,20211130,20211201,20211202,20211203,20211206,20211207,20211208,20211209,20211210,20211213,20211214,20211215,20211216,20211217,20211220,20211221,20211222,20211223,20211224,20211227,20211228,20211229,20211230,20211231

油价调整是每10个工作日为一个调价周期,2020年最后一个调价日是12月31日,推算可知2021年第一个调价日是1月15日。在上面求出的工作日具体日期结果基础上,依次加上10个工作日。接下去写出下面Java代码求得全年油价调整日期。

List<String> oil = new ArrayList<String>();
int first = dates.size();
for (int i = 0; i < dates.size(); i++) {
    if (dates.get(i).equals("20210115")) {
        first = i;
        break;
    }
}
for (int i = first; i < dates.size(); i += 10) {
    oil.add(dates.get(i));
}
System.out.println(String.join(",", oil)); // 输出调价日期

运行得到如下2021年油价调整日期:

20210115,20210129,20210218,20210303,20210317,20210331,20210415,20210428,20210514,20210528,20210611,20210628,20210712,20210726,20210809,20210823,20210906,20210918,20211009,20211022,20211105,20211119,20211203,20211217,20211231

上一篇:LeetCode笔记:Biweekly Contest 47 比赛记录


下一篇:《特征工程入门与实践》--特征理解