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

时间:2023-01-20 12:03:14

你的程序支持复杂的时间调度嘛? 这篇文章介绍了时间适配器的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点为配置开启时间

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

 package sz.pool;

 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collections;

 /**
  * 时间辅助
  *
  * @author 失足程序员
  * @Blog http://www.cnblogs.com/ty408/
  * @mail 492794628@qq.com
  * @phone 13882122019
  */
 public class TimeUtil {

     //<editor-fold desc=" 验证时间 返回倒计时 :[*][*][20/22][*][10:00-11:59/16:00-17:59] static public long verifyDateTime(String timeStr)">
     /// <summary>
     /// 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59]
     /// <para>第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间,</para>
     /// <para>每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/"  表示 或者 如: “2015/2017”表示2015 或者 2017</para>
     /// <para>返回值 -1 表示永久过期,0 表示在时间规则内,大于 0 表示倒计时</para>
     /// </summary>
     /**
      * 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59]
      * <\br>第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间,
      * <\br>每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如:
      * “2015/2017”表示2015 或者 2017
      * <\br>返回值 -1 表示永久过期,0 表示在时间规则内,大于 0 表示倒计时
      *
      * @param timeStr
      * @return
      */
     static public long verifyDateTime(String timeStr) {
         String[] items = timeStr.split(";|;");
         Calendar calendar = Calendar.getInstance();
         for (String item : items) {
             //验证时间匹配
             if (verifyConfigTimeStr(calendar, item)) {
                 return 0;
             }
             //未通过时间匹配,检查返回剩余时间
             String[] timeStrs = item.replace("[", "").split("]");

             String times = timeStrs[4];
             String weeks = timeStrs[3];
             String days = timeStrs[2];
             String months = timeStrs[1];
             String years = timeStrs[0];

             int hour = 0, minute = 0, second = 0;

             ArrayList<Integer> tempYears = getConfigDate(calendar, calendar.get(Calendar.YEAR), years);
             ArrayList<Integer> tempMonths = getConfigDate(calendar, calendar.get(Calendar.MONTH) + 1, months);
             ArrayList<Integer> tempDays = getConfigDate(calendar, calendar.get(Calendar.DATE), days);
             //由于星期比较特殊所以获取与星期相关的日期的时候有点诡异。
             if (!"*".equals(weeks)) {
                 if (weeks.indexOf("-") > 0) {
                     //星期的间隔模式
                     String[] weeksplit = weeks.split("-");
                     int weekmin = Integer.parseInt(weeksplit[0]);
                     int weekmax = Integer.parseInt(weeksplit[1]);
                     actionWeekDay(weekmin, weekmax, tempDays, tempMonths, tempYears);
                 } else if (weeks.indexOf("/") > 0) {
                     //星期的或模式
                     String[] weekssplit = weeks.split("/");
                     int tempWeek;
                     for (String weekssplit1 : weekssplit) {
                         tempWeek = Integer.parseInt(weekssplit1);
                         if (0 <= tempWeek && tempWeek <= 7) {
                             actionWeekDay(tempWeek, tempWeek, tempDays, tempMonths, tempYears);
                         }
                     }
                 } else {
                     //特定星期的模式
                     int tempweek = Integer.parseInt(weeks);
                     actionWeekDay(tempweek, tempweek, tempDays, tempMonths, tempYears);
                 }
             } else {
                 //未指定星期的模式
                 actionWeekDay(1, 7, tempDays, tempMonths, tempYears);
             }

             ArrayList<String> tempHHMMs = getConfigTimeStr(times);

             //进行简单的排序
             Collections.sort(tempYears);
             Collections.sort(tempMonths);
             Collections.sort(tempDays);
             Collections.sort(tempHHMMs);

             //接下来这里是天坑,就是构造时间器比较,然后计算出倒计时
             for (int y = 0; y < tempYears.size(); y++) {
                 for (int m = 0; m < tempMonths.size(); m++) {
                     for (int d = 0; d < tempDays.size(); d++) {
                         if (tempYears.get(y) < calendar.get(Calendar.YEAR)) {
                             continue;
                         }
                         if (tempYears.get(y) == calendar.get(Calendar.YEAR) && tempMonths.get(m) - 1 < calendar.get(Calendar.MONTH)) {
                             continue;
                         }
                         if (tempYears.get(y) == calendar.get(Calendar.YEAR) && tempMonths.get(m) - 1 == calendar.get(Calendar.MONTH) && tempDays.get(d) < calendar.get(Calendar.DATE)) {
                             continue;
                         }
                         for (int h = 0; h < tempHHMMs.size(); h++) {
                             String[] hhmm = tempHHMMs.get(h).split(":|:");
                             hour = Integer.parseInt(hhmm[0]);
                             minute = Integer.parseInt(hhmm[1]);
                             Calendar calendar1 = Calendar.getInstance();
                             calendar1.set(tempYears.get(y), (tempMonths.get(m) - 1), tempDays.get(d), hour, minute, second);
 //                            System.out.println(DF2.format(calendar1.getTime()) + "   " + DF2.format(calendar.getTime()));
 //                            System.out.println(calendar1.getTimeInMillis() + "   " + calendar.getTimeInMillis());
                             if (calendar1.getTimeInMillis() > calendar.getTimeInMillis()) {
                                 if (verifyConfigTimeStr(calendar1, item)) {
                                     return calendar1.getTimeInMillis() - calendar.getTimeInMillis();
                                 }
                             }
                         }
                     }
                 }
             }
         }
         return -1;
     }
     //</editor-fold>

     //<editor-fold desc=" 处理星期包含的日期 日 static void actionWeekDay(int weekmin, int weekmax, ArrayList<Integer> days, ArrayList<Integer> months, ArrayList<Integer> years)">
     /**
      * 处理星期包含的日期 日
      *
      * @param weekmin
      * @param weekmax
      * @param days
      * @param months
      * @param years
      */
     static void actionWeekDay(int weekmin, int weekmax, ArrayList<Integer> days, ArrayList<Integer> months, ArrayList<Integer> years) {
         Calendar nowWeekDate = Calendar.getInstance();
         Integer[] tempMonths, tempYears;
         tempYears = years.toArray(new Integer[0]);
         tempMonths = months.toArray(new Integer[0]);
         for (int itemYear : tempYears) {
             for (int itemMonth : tempMonths) {
                 int itemDay = 1;
                 if (nowWeekDate.get(Calendar.MONTH) + 1 == itemMonth) {
                     itemDay = nowWeekDate.get(Calendar.DATE);
                 }
                 Calendar date = Calendar.getInstance();
                 date.set(itemYear, itemMonth - 1, itemDay);
                 for (int i = 0; i < 7; i++) {
                     int week = date.get(Calendar.DAY_OF_WEEK) - 1;
                     if (week < 1) {
                         week = 7;
                     }
                     if (weekmin <= week && week <= weekmax) {
                         if (!days.contains(date.get(Calendar.DATE))) {
                             days.add(date.get(Calendar.DATE));
                         }
                         if (!months.contains(date.get(Calendar.MONTH) + 1)) {
                             months.add(date.get(Calendar.MONTH) + 1);
                         }
                         if (!years.contains(date.get(Calendar.YEAR))) {
                             years.add(date.get(Calendar.YEAR));
                         }
                     }
                     date.add(Calendar.DATE, 1);
                 }
             }
         }
     }
  //</editor-fold>

     //<editor-fold desc="验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59] static public boolean verifyConfigTimeStr(String timeStr)">
     /**
      * 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59]
      * <para>第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间,</para>
      * <para>每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如:
      * “2015/2017”表示2015 或者 2017</para>
      *
      */
     static public boolean verifyConfigTimeStr(String timeStr) {
         return verifyConfigTimeStr(Calendar.getInstance(), timeStr);
     }
     //</editor-fold>

     //<editor-fold desc="验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59] static boolean verifyConfigTimeStr(Calendar date, String timeStr)">
     /**
      * 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59]
      * <para>第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间,</para>
      * <para>每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如:
      * “2015/2017”表示2015 或者 2017</para>
      *
      */
     static boolean verifyConfigTimeStr(Calendar date, String timeStr) {
         String[] timeStrs = timeStr.replace("[", "").split("]");
         if (verifyDate(date.get(Calendar.YEAR), timeStrs[0])) {
             if (verifyDate(date.get(Calendar.MONTH) + 1, timeStrs[1])) {
                 // {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
                 int week = date.get(Calendar.DAY_OF_WEEK) - 1;
                 if (week < 1) {
                     week = 7;
                 }//星期天
                 if (verifyDate(week, timeStrs[3])) {
                     if (verifyDate(date.get(Calendar.DATE), timeStrs[2])) {
                         if (verifyTime(date, timeStrs[4])) {
                             return true;
                         }
                     }
                 }
             }
         }
         return false;
     }
     //</editor-fold>

     //<editor-fold desc=" 验证当前时间 年,月,日,星期,是否符合 static boolean verifyDate(int nowItem, String items)">
     /**
      * 验证当前时间 年,月,日,星期,是否符合
      *
      * @param nowItem 参数
      * @param items 1-7;表示 1 到 7 , 1/7 表示 1 或者 7
      * @return
      */
     static boolean verifyDate(int nowItem, String items) {
         String nowItemStr = String.valueOf(nowItem);
         if ("*".equals(items) || nowItemStr.equals(items)) {
             return true;
         } else if (items.indexOf("-") > 0) {//区间划分
             String[] itemsplit = items.split("-");
             int item1 = Integer.parseInt(itemsplit[0]);
             int item2 = Integer.parseInt(itemsplit[1]);
             if (item1 <= nowItem && nowItem <= item2) {
                 return true;
             }
         } else if (items.indexOf("/") > 0) {//或划分
             String[] weekssplit = items.split("/");
             for (String item : weekssplit) {
                 if (nowItemStr.equals(item)) {
                     return true;
                 }
             }
         }
         return false;
     }
     //</editor-fold>

     //<editor-fold desc="验证当期时间格式 static boolean verifyTime(Calendar date, String itemTime)">
     /**
      * 验证当期时间格式
      *
      * @param date
      * @param itemTime
      * @return
      */
     static boolean verifyTime(Calendar date, String itemTime) {
         boolean ret = false;
         if (!"*".equals(itemTime)) {
             String[] items = itemTime.split("/");
             for (String item : items) {
                 String[] itemTimes = item.split("-");
                 String[] hhmm = itemTimes[0].split(":|:");
                 int hh = Integer.parseInt(hhmm[0]);
                 int mm = Integer.parseInt(hhmm[1]);
                 if (date.get(Calendar.HOUR_OF_DAY) > hh || (date.get(Calendar.HOUR_OF_DAY) == hh && date.get(Calendar.MINUTE) >= mm)) {
                     if (itemTimes.length > 1) {
                         String[] hhmm1 = itemTimes[1].split(":|:");
                         int hh1 = Integer.parseInt(hhmm1[0]);
                         int mm1 = Integer.parseInt(hhmm1[1]);
                         if (date.get(Calendar.HOUR_OF_DAY) < hh1 || (date.get(Calendar.HOUR_OF_DAY) == hh1 && date.get(Calendar.MINUTE) < mm1)) {
                             ret = true;
                         } else {
                             ret = false;
                         }
                     } else {
                         ret = true;
                     }
                 } else {
                     ret = false;
                 }
                 if (ret) {
                     break;
                 }
             }
         } else {
             ret = true;
         }
         return ret;
     }
     //</editor-fold>

     //<editor-fold desc="获取配置的年月日星期等信息  static ArrayList<Integer> getConfigDate(Calendar calendar, int p1, String p3)">
     static ArrayList<Integer> getConfigDate(Calendar calendar, int p1, String p3) {
         ArrayList<Integer> rets = new ArrayList<Integer>();
         String p1Str = String.valueOf(p1);
         if ("*".equals(p3) || p1Str.equals(p3)) {
             rets.add(p1);
             rets.add(p1 + 1);
         } else if (p3.indexOf("-") > 0) {
             String[] weeksplit = p3.split("-");
             int k1 = Integer.parseInt(weeksplit[0]);
             int k2 = Integer.parseInt(weeksplit[0]);
             for (int i = k1; i <= k2 + 1; i++) {
                 rets.add(i);
             }
         } else if (p3.indexOf("/") > 0) {
             String[] weekssplit = p3.split("/");
             for (String item : weekssplit) {
                 int temp = Integer.parseInt(item);
                 rets.add(temp);
             }
         } else {
             rets.add(Integer.parseInt(p3));
         }
         return rets;
     }
     //</editor-fold>

     //<editor-fold desc="获取配置的时间字符串 static ArrayList<String> getConfigTimeStr(String itemTime)">
     /**
      * 必须类似的格式 单条 00:00-23:59 多条00:00-23:59/00:00-23:59
      *
      * @param itemTime
      * @return
      */
     static ArrayList<String> getConfigTimeStr(String itemTime) {
         ArrayList<String> retObjs = new ArrayList<String>();
         // 00:00-23:59
         if (!"*".equals(itemTime)) {
             String[] items = itemTime.split("/");
             for (String item : items) {
                 String[] itemTimes = item.split("-");
                 retObjs.add(itemTimes[0]);
             }
         } else {
             retObjs.add("00:00");
         }
         return retObjs;
     }
     //</editor-fold>
 }

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

以上代码,有两个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了

         , , , , , );

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

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

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

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

你的程序支持复杂的时间调度嘛?如约而来的 java 版本的更多相关文章

  1. iOS开发:后台运行以及保持程序在后台长时间运行

    第一部分 1.先说说iOS 应用程序5个状态: 停止运行-应用程序已经终止,或者还未启动. 不活动-应用程序处于前台但不再接收事件(例如,用户在app处于活动时锁住了设备). 活动-app处于“使用中 ...

  2. quartz任务时间调度入门使用

    Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现. 作为一个优秀的开源调度框架,Quartz 具有以下特点: 强大的调度功能,例如支持丰富多样 ...

  3. iOS开发:保持程序在后台长时间运行

    iOS开发:保持程序在后台长时间运行 2014 年 5 月 26 日 / NIVALXER / 0 COMMENTS iOS为了让设备尽量省电,减少不必要的开销,保持系统流畅,因而对后台机制采用墓碑式 ...

  4. 保持程序在后台长时间运行-b

    iOS为了让设备尽量省电,减少不必要的开销,保持系统流畅,因而对后台机制采用墓碑式的“假后台”.除了系统官方极少数程序可以真后台,一般开发者开发出来的应用程序后台受到以下限制:1.用户按Home之后, ...

  5. 八、mysql视图、存储过程、函数以及时间调度器

    .create or replace view emp_view as select * from t4 ;给t4表创建一个名为emp_view的视图 .drop view emp_view 删除视图 ...

  6. SpiderMonkey-让你的C&plus;&plus;程序支持JavaScript脚本

    译序 有些网友对为什么D2JSP能执行JavaScript脚本程序感到奇怪,因此我翻译了这篇文章,原文在这里.这篇教程手把手教你怎样利用SpiderMonkey创建一个能执行JavaScript脚本的 ...

  7. vs调试windows mobile程序时布署时间太长的解决办法

    vs调试windows mobile程序时布署时间太长的解决办法 1.VS平台上,选工具-选项-项目和解决方案-MS BUILD项目生成输出详细信息中选择“诊断”,目的是在调试窗口中看出哪个过程编译的 ...

  8. 如何让你的Python程序支持多语言

    如何让你的Python程序支持多语言 本文介绍如何通过Python标准库gettext帮助你的程序支持多语言. 代码例子 import random guessesTaken = 0 print(_( ...

  9. WPF应用程序支持多国语言解决方案

    原文:WPF应用程序支持多国语言解决方案 促使程序赢得更多客户的最好.最经济的方法是使之支持多国语言,而不是将潜在的客户群限制为全球近70亿人口中的一小部分.本文介绍四种实现WPF应用程序支持多国语言 ...

随机推荐

  1. 通过weburl 启动windows程序

    1. 注册表修改 建立一个reg文件 执行导入  以RunLocal协议为例子 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\RunL ...

  2. &lbrack;转&rsqb;Designing a User Interface

    UI design can be divided into three essential elements : functionality, aesthetics, and performance. ...

  3. HDR Defered Shading &lpar;using MRT&rpar;

    http://http.download.nvidia.com/developer/SDK/Individual_Samples/DEMOS/Direct3D9/DeferredShading.zip ...

  4. 浅谈扩展欧几里得算法&lpar;exgcd&rpar;

    在讲解扩展欧几里得之前我们先回顾下辗转相除法: \(gcd(a,b)=gcd(b,a\%b)\)当a%b==0的时候b即为所求最大公约数 好了切入正题: 简单地来说exgcd函数求解的是\(ax+by ...

  5. 阿里聚安全&&num;183&semi;安全周刊】一种秘密窃取数据的新型 Android 木马&vert;iOS 11相机惊现BUG

    本周的七个关键词:  新型 Android 木马丨 TLS 1.3 丨  阿里安全图灵实验室 丨 漏洞感染 Linux 服务器 丨 CPU曝极危漏洞 丨   iOS 11相机BUG 丨R2D2技术 - ...

  6. 【转】&lbrack;Network&rsqb; 计算机网络基础知识总结

    阅读目录 1. 网络层次划分 2. OSI七层网络模型 3. IP地址 4. 子网掩码及网络划分 5. ARP/RARP协议 6. 路由选择协议 7. TCP/IP协议 8. UDP协议 9. DNS ...

  7. The issue about the GMT paper can&&num;39&semi;t display all the seismograms

    I try to display seismograms using 'pssac' by the command: gmt pssac *.z -JX20c/40c -R0/// -Bx20+l'T ...

  8. (转)Linux中设置服务自启动的三种方式

    有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务 主要用三种方式进行这一操作: ln -s                       在/etc/rc.d/rc*.d目录中建立/e ...

  9. rcp(插件开发)点击按钮出现 The chosen operation is not enabled 解决办法

    别的项目组,遇到以下错误信息: 首先看一下log日志里的异常信息,估计就知道是什么问题了. 项目组遇到的这个错误是source 指向错误 找不到相关的class.

  10. ES6之函数参数

    ES6中对于函数参数主要增加了以下内容: 1.参数的扩展/数组的展开: 2.默认参数. 什么是参数的扩展? 看下面代码: <!DOCTYPE html> <html lang=&qu ...