你的位置:首页 > Java教程

[Java教程]你的程序支持复杂的时间调度嘛?如约而来的 java 版本

你的程序支持复杂的时间调度嘛? 这篇文章介绍了时间适配器的c#版本,是给客户端用的,服务器自然也要有一套对应的做法,java版本的

[年][月][日][星期][时间]

[*][*][*][*][*]

这样利于分割,配置,清晰。

然后就是验证,时间在不在配置的时间开发内?

当然想到的*肯定是默认支持所有的

[2015][7][*][*][10:00-11:59]

这个格式,表示2015年的7月每一天的10点到12点为配置开启时间

[2015][7-9][*][*][10:00-11:59]

这个格式,表示2015年的7月1日到9月30的每一天的10点到12点为配置开启时间 

[2015][7/9][*][*][10:00-11:59]

这个格式,表示2015年的7月或者9月的每一天的10点到12点为配置开启时间

 [2015][*][*][2/4/6][10:00-11:59]
这个格式,表示2015年的每一个星期2,星期4,星期6 的每一天的10点到12点为配置开启时间

接下来,就是验证这个时间格式。

 1 package sz.pool; 2  3 import java.util.ArrayList; 4 import java.util.Calendar; 5 import java.util.Collections; 6  7 /** 8  * 时间辅助 9  * 10  * @author 失足程序员 11  * @Blog http://www.cnblogs.com/ty408/ 12  * @mail 492794628@qq.com 13  * @phone 13882122019 14 */ 15 public class TimeUtil { 16  17   //<editor-fold desc=" 验证时间 返回倒计时 :[*][*][20/22][*][10:00-11:59/16:00-17:59] static public long verifyDateTime(String timeStr)"> 18   /// <summary> 19   /// 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59] 20   /// <para>第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间,</para> 21   /// <para>每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如: “2015/2017”表示2015 或者 2017</para> 22   /// <para>返回值 -1 表示永久过期,0 表示在时间规则内,大于 0 表示倒计时</para> 23   /// </summary> 24   /** 25    * 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59] 26    * <\br>第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间, 27    * <\br>每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如: 28    * “2015/2017”表示2015 或者 2017 29    * <\br>返回值 -1 表示永久过期,0 表示在时间规则内,大于 0 表示倒计时 30    * 31    * @param timeStr 32    * @return 33   */ 34   static public long verifyDateTime(String timeStr) { 35     String[] items = timeStr.split(";|;"); 36     Calendar calendar = Calendar.getInstance(); 37     for (String item : items) { 38       //验证时间匹配 39       if (verifyConfigTimeStr(calendar, item)) { 40         return 0; 41       } 42       //未通过时间匹配,检查返回剩余时间 43       String[] timeStrs = item.replace("[", "").split("]"); 44  45       String times = timeStrs[4]; 46       String weeks = timeStrs[3]; 47       String days = timeStrs[2]; 48       String months = timeStrs[1]; 49       String years = timeStrs[0]; 50  51       int hour = 0, minute = 0, second = 0; 52  53       ArrayList<Integer> tempYears = getConfigDate(calendar, calendar.get(Calendar.YEAR), years); 54       ArrayList<Integer> tempMonths = getConfigDate(calendar, calendar.get(Calendar.MONTH) + 1, months); 55       ArrayList<Integer> tempDays = getConfigDate(calendar, calendar.get(Calendar.DATE), days); 56       //由于星期比较特殊所以获取与星期相关的日期的时候有点诡异。 57       if (!"*".equals(weeks)) { 58         if (weeks.indexOf("-") > 0) { 59           //星期的间隔模式 60           String[] weeksplit = weeks.split("-"); 61           int weekmin = Integer.parseInt(weeksplit[0]); 62           int weekmax = Integer.parseInt(weeksplit[1]); 63           actionWeekDay(weekmin, weekmax, tempDays, tempMonths, tempYears); 64         } else if (weeks.indexOf("/") > 0) { 65           //星期的或模式 66           String[] weekssplit = weeks.split("/"); 67           int tempWeek; 68           for (String weekssplit1 : weekssplit) { 69             tempWeek = Integer.parseInt(weekssplit1); 70             if (0 <= tempWeek && tempWeek <= 7) { 71               actionWeekDay(tempWeek, tempWeek, tempDays, tempMonths, tempYears); 72             } 73           } 74         } else { 75           //特定星期的模式 76           int tempweek = Integer.parseInt(weeks); 77           actionWeekDay(tempweek, tempweek, tempDays, tempMonths, tempYears); 78         } 79       } else { 80         //未指定星期的模式 81         actionWeekDay(1, 7, tempDays, tempMonths, tempYears); 82       } 83  84       ArrayList<String> tempHHMMs = getConfigTimeStr(times); 85  86       //进行简单的排序 87       Collections.sort(tempYears); 88       Collections.sort(tempMonths); 89       Collections.sort(tempDays); 90       Collections.sort(tempHHMMs); 91  92       //接下来这里是天坑,就是构造时间器比较,然后计算出倒计时 93       for (int y = 0; y < tempYears.size(); y++) { 94         for (int m = 0; m < tempMonths.size(); m++) { 95           for (int d = 0; d < tempDays.size(); d++) { 96             if (tempYears.get(y) < calendar.get(Calendar.YEAR)) { 97               continue; 98             } 99             if (tempYears.get(y) == calendar.get(Calendar.YEAR) && tempMonths.get(m) - 1 < calendar.get(Calendar.MONTH)) {100               continue;101             }102             if (tempYears.get(y) == calendar.get(Calendar.YEAR) && tempMonths.get(m) - 1 == calendar.get(Calendar.MONTH) && tempDays.get(d) < calendar.get(Calendar.DATE)) {103               continue;104             }105             for (int h = 0; h < tempHHMMs.size(); h++) {106               String[] hhmm = tempHHMMs.get(h).split(":|:");107               hour = Integer.parseInt(hhmm[0]);108               minute = Integer.parseInt(hhmm[1]);109               Calendar calendar1 = Calendar.getInstance();110               calendar1.set(tempYears.get(y), (tempMonths.get(m) - 1), tempDays.get(d), hour, minute, second);111 //              System.out.println(DF2.format(calendar1.getTime()) + "  " + DF2.format(calendar.getTime()));112 //              System.out.println(calendar1.getTimeInMillis() + "  " + calendar.getTimeInMillis());113               if (calendar1.getTimeInMillis() > calendar.getTimeInMillis()) {114                 if (verifyConfigTimeStr(calendar1, item)) {115                   return calendar1.getTimeInMillis() - calendar.getTimeInMillis();116                 }117               }118             }119           }120         }121       }122     }123     return -1;124   }125   //</editor-fold>126 127   //<editor-fold desc=" 处理星期包含的日期 日 static void actionWeekDay(int weekmin, int weekmax, ArrayList<Integer> days, ArrayList<Integer> months, ArrayList<Integer> years)">128   /**129    * 处理星期包含的日期 日130    *131    * @param weekmin132    * @param weekmax133    * @param days134    * @param months135    * @param years136   */137   static void actionWeekDay(int weekmin, int weekmax, ArrayList<Integer> days, ArrayList<Integer> months, ArrayList<Integer> years) {138     Calendar nowWeekDate = Calendar.getInstance();139     Integer[] tempMonths, tempYears;140     tempYears = years.toArray(new Integer[0]);141     tempMonths = months.toArray(new Integer[0]);142     for (int itemYear : tempYears) {143       for (int itemMonth : tempMonths) {144         int itemDay = 1;145         if (nowWeekDate.get(Calendar.MONTH) + 1 == itemMonth) {146           itemDay = nowWeekDate.get(Calendar.DATE);147         }148         Calendar date = Calendar.getInstance();149         date.set(itemYear, itemMonth - 1, itemDay);150         for (int i = 0; i < 7; i++) {151           int week = date.get(Calendar.DAY_OF_WEEK) - 1;152           if (week < 1) {153             week = 7;154           }155           if (weekmin <= week && week <= weekmax) {156             if (!days.contains(date.get(Calendar.DATE))) {157               days.add(date.get(Calendar.DATE));158             }159             if (!months.contains(date.get(Calendar.MONTH) + 1)) {160               months.add(date.get(Calendar.MONTH) + 1);161             }162             if (!years.contains(date.get(Calendar.YEAR))) {163               years.add(date.get(Calendar.YEAR));164             }165           }166           date.add(Calendar.DATE, 1);167         }168       }169     }170   }171 //</editor-fold>172 173   //<editor-fold desc="验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59] static public boolean verifyConfigTimeStr(String timeStr)">174   /**175    * 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59]176    * <para>第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间,</para>177    * <para>每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如:178    * “2015/2017”表示2015 或者 2017</para>179    *180   */181   static public boolean verifyConfigTimeStr(String timeStr) {182     return verifyConfigTimeStr(Calendar.getInstance(), timeStr);183   }184   //</editor-fold>185 186   //<editor-fold desc="验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59] static boolean verifyConfigTimeStr(Calendar date, String timeStr)">187   /**188    * 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59]189    * <para>第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间,</para>190    * <para>每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如:191    * “2015/2017”表示2015 或者 2017</para>192    *193   */194   static boolean verifyConfigTimeStr(Calendar date, String timeStr) {195     String[] timeStrs = timeStr.replace("[", "").split("]");196     if (verifyDate(date.get(Calendar.YEAR), timeStrs[0])) {197       if (verifyDate(date.get(Calendar.MONTH) + 1, timeStrs[1])) {198         // {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};199         int week = date.get(Calendar.DAY_OF_WEEK) - 1;200         if (week < 1) {201           week = 7;202         }//星期天203         if (verifyDate(week, timeStrs[3])) {204           if (verifyDate(date.get(Calendar.DATE), timeStrs[2])) {205             if (verifyTime(date, timeStrs[4])) {206               return true;207             }208           }209         }210       }211     }212     return false;213   }214   //</editor-fold>215 216   //<editor-fold desc=" 验证当前时间 年,月,日,星期,是否符合 static boolean verifyDate(int nowItem, String items)">217   /**218    * 验证当前时间 年,月,日,星期,是否符合219    *220    * @param nowItem 参数221    * @param items 1-7;表示 1 到 7 , 1/7 表示 1 或者 7222    * @return223   */224   static boolean verifyDate(int nowItem, String items) {225     String nowItemStr = String.valueOf(nowItem);226     if ("*".equals(items) || nowItemStr.equals(items)) {227       return true;228     } else if (items.indexOf("-") > 0) {//区间划分229       String[] itemsplit = items.split("-");230       int item1 = Integer.parseInt(itemsplit[0]);231       int item2 = Integer.parseInt(itemsplit[1]);232       if (item1 <= nowItem && nowItem <= item2) {233         return true;234       }235     } else if (items.indexOf("/") > 0) {//或划分236       String[] weekssplit = items.split("/");237       for (String item : weekssplit) {238         if (nowItemStr.equals(item)) {239           return true;240         }241       }242     }243     return false;244   }245   //</editor-fold>246 247   //<editor-fold desc="验证当期时间格式 static boolean verifyTime(Calendar date, String itemTime)">248   /**249    * 验证当期时间格式250    *251    * @param date252    * @param itemTime253    * @return254   */255   static boolean verifyTime(Calendar date, String itemTime) {256     boolean ret = false;257     if (!"*".equals(itemTime)) {258       String[] items = itemTime.split("/");259       for (String item : items) {260         String[] itemTimes = item.split("-");261         String[] hhmm = itemTimes[0].split(":|:");262         int hh = Integer.parseInt(hhmm[0]);263         int mm = Integer.parseInt(hhmm[1]);264         if (date.get(Calendar.HOUR_OF_DAY) > hh || (date.get(Calendar.HOUR_OF_DAY) == hh && date.get(Calendar.MINUTE) >= mm)) {265           if (itemTimes.length > 1) {266             String[] hhmm1 = itemTimes[1].split(":|:");267             int hh1 = Integer.parseInt(hhmm1[0]);268             int mm1 = Integer.parseInt(hhmm1[1]);269             if (date.get(Calendar.HOUR_OF_DAY) < hh1 || (date.get(Calendar.HOUR_OF_DAY) == hh1 && date.get(Calendar.MINUTE) < mm1)) {270               ret = true;271             } else {272               ret = false;273             }274           } else {275             ret = true;276           }277         } else {278           ret = false;279         }280         if (ret) {281           break;282         }283       }284     } else {285       ret = true;286     }287     return ret;288   }289   //</editor-fold>290 291   //<editor-fold desc="获取配置的年月日星期等信息 static ArrayList<Integer> getConfigDate(Calendar calendar, int p1, String p3)">292   static ArrayList<Integer> getConfigDate(Calendar calendar, int p1, String p3) {293     ArrayList<Integer> rets = new ArrayList<Integer>();294     String p1Str = String.valueOf(p1);295     if ("*".equals(p3) || p1Str.equals(p3)) {296       rets.add(p1);297       rets.add(p1 + 1);298     } else if (p3.indexOf("-") > 0) {299       String[] weeksplit = p3.split("-");300       int k1 = Integer.parseInt(weeksplit[0]);301       int k2 = Integer.parseInt(weeksplit[0]);302       for (int i = k1; i <= k2 + 1; i++) {303         rets.add(i);304       }305     } else if (p3.indexOf("/") > 0) {306       String[] weekssplit = p3.split("/");307       for (String item : weekssplit) {308         int temp = Integer.parseInt(item);309         rets.add(temp);310       }311     } else {312       rets.add(Integer.parseInt(p3));313     }314     return rets;315   }316   //</editor-fold>317 318   //<editor-fold desc="获取配置的时间字符串 static ArrayList<String> getConfigTimeStr(String itemTime)">319   /**320    * 必须类似的格式 单条 00:00-23:59 多条00:00-23:59/00:00-23:59321    *322    * @param itemTime323    * @return324   */325   static ArrayList<String> getConfigTimeStr(String itemTime) {326     ArrayList<String> retObjs = new ArrayList<String>();327     // 00:00-23:59328     if (!"*".equals(itemTime)) {329       String[] items = itemTime.split("/");330       for (String item : items) {331         String[] itemTimes = item.split("-");332         retObjs.add(itemTimes[0]);333       }334     } else {335       retObjs.add("00:00");336     }337     return retObjs;338   }339   //</editor-fold>340 }

以上代码,有两个public的方法,一个是返回值bool变量,表示是否在配置开发时间内,另外一个是返回值long型,-1表示永久过期,0表示开发时间,大于0表示倒计时;

那么问题来了,服务器是java开发的,客户端是u3d c#开发的,客户端和服务器的语言不一样,使用的date也就不一样,

C#使用的是0001年1月1日,0晨开始的,java是用的是1970年1月1日0晨时间,并且是标准的gmt +8 时区,

蛋疼的研究了一上午。c#无论使用utc时间还是local时间,都和java相差8小时,尿了。。。。

服务器会在间隔一段时间同步一次服务器当前时间给客户端,然后客户端就可以得到dateTime了

 1     static DateTime dt1970 = new DateTime(1970, 1, 1, 0, 0, 0); 2  3     /// <summary> 4     /// 将java毫秒数转化成当前时间 5     /// </summary> 6     public static DateTime DateNow(long milliseconds) 7     { 8       // .net开发中计算的都是标准时区的差,但java的解析时间跟时区有关, 9       // 而我们的java服务器系统时区不是标准时区,解析时间会差8个小时。10       TimeSpan span = TimeSpan.FromMilliseconds(milliseconds) + TimeSpan.FromHours(8);11       return dt1970 + span;12     }

c#下面得到一个long型时间与java保持一致

 1     /// <summary> 2     /// 将特定时间转化成java一直的毫秒数 3     /// </summary> 4     public static long CurrentTimeMillis(DateTime dt) 5     { 6       TimeSpan span = dt - dt1970; 7       // .net开发中计算的都是标准时区的差,但java的解析时间跟时区有关, 8       // 而我们的java服务器系统时区不是标准时区,解析时间会差8个小时。 9       span -= TimeSpan.FromHours(8);10       return (long)span.TotalMilliseconds;11     }

好了,,时间验证器,和时间同步问题,java和c#两个版本