1. 程式人生 > >你的程式支援複雜的時間排程嘛?

你的程式支援複雜的時間排程嘛?

時隔兩個月了,這段時間,遊戲籌備正式上線,根據遊戲平臺數據反饋,反響還不錯。

但是牽涉出新問題,就是活動。活動功能本身很簡單。問題就在於,時間配置上,什麼時間段開發活動。

配置多種多樣。比如,沒做星期2,4,6活動。每週的週六,週日,活動。指定月份和日期的活動。配置簡直是天花亂墜了。。。這尼瑪怎麼搞????

那麼有麼有萬能的配置方式呢?首先,我能想到的配置肯定是字串格式的。

必須包含,年月日星期時間,這尼瑪不就犯難了嘛????我們C#的 DateTime 型別格式化只支援年月日,時分秒啊。星期怎麼控制???例如,我要每個星期的星期天搞一個活動,拉一拉充值消費我擦。。。

我自己都把自己繞暈了。。好吧。。。

後來想到一種方式,

[年][月][日][星期][時間]

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

這樣利於分割,配置,清晰。

然後就是驗證,時間在不在配置的時間開發內?

當然想到的*肯定是預設支援所有的

[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         #region 驗證當前時間 年,月,日,星期,是否符合 static bool VerifyDate(int nowItem, string items)
 2         /// <summary>
 3         /// 驗證當前時間 年,月,日,星期,是否符合
 4         /// </summary>
 5         /// <param name="items">1-7;表示 1 到 7 , 1/7 表示 1 或者 7</param>
 6         /// <returns></returns>
7 static bool VerifyDate(int nowItem, string items) 8 { 9 string nowItemStr = nowItem.ToString(); 10 if ("*".Equals(items) || nowItemStr.Equals(items)) { return true; } 11 else if (items.IndexOf("-") > 0) 12 {//區間劃分 13 string[] itemSplit = items.Split('-'); 14 int item1 = 9999; 15 int.TryParse(itemSplit[0], out item1); 16 int item2 = 9999; 17 int.TryParse(itemSplit[1], out item2); 18 19 if (item1 <= nowItem && nowItem <= item2) { return true; } 20 } 21 else if (items.IndexOf("/") > 0) 22 {//或劃分 23 string[] weeksSplit = items.Split('/'); 24 foreach (var item in weeksSplit) 25 { 26 if (nowItemStr.Equals(item)) { return true; } 27 } 28 } 29 return false; 30 } 31 #endregion 32 33 #region 驗證當期時間格式 static bool VerifyTime(DateTime date, string itemTime) 34 /// <summary> 35 /// 驗證當期時間格式 36 /// </summary> 37 /// <param name="date"></param> 38 /// <param name="itemTime"></param> 39 /// <returns></returns> 40 static bool VerifyTime(DateTime date, string itemTime) 41 { 42 bool ret = false; 43 if (!"*".Equals(itemTime)) 44 { 45 var items = Regex.Split(itemTime, @"/"); 46 foreach (var item in items) 47 { 48 string[] itemTimes = item.Split('-'); 49 var hhmm = Regex.Split(itemTimes[0], @":|:"); 50 int hh = 24; 51 int.TryParse(hhmm[0], out hh); 52 int mm = 60; 53 int.TryParse(hhmm[1], out mm); 54 if (date.Hour > hh || (date.Hour == hh && date.Minute >= mm)) 55 { 56 if (itemTimes.Length > 1) 57 { 58 var hhmm1 = Regex.Split(itemTimes[1], @":|:"); 59 int hh1 = 24; 60 int.TryParse(hhmm1[0], out hh1); 61 int mm1 = 60; 62 int.TryParse(hhmm1[1], out mm1); 63 if (date.Hour < hh1 || (date.Hour == hh1 && date.Minute < mm1)) { ret = true; } 64 else { ret = false; } 65 } 66 else { ret = true; } 67 } 68 else { ret = false; } 69 if (ret) 70 { 71 break; 72 } 73 } 74 } 75 else { ret = true; } 76 return ret; 77 } 78 #endregion

看看結果

這樣挺萬能的吧?

如果每一天有兩檔活動開放

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

當我完成了這個需求的時候,,新的需求又來了,,,媽蛋,,,需要倒計時,,活動還有多長時間開始。。

臥槽。。

好吧,,有需求就是大爺。。只能苦逼的程式去搞定了,需求一句話,我卻花了一天時間啊。。。

我的思路是分解出,所包含的年月日,時間段開始。

 1         #region 獲取配置的年月日星期等資訊 static List<int> GetConfigDate(DateTime date, int p1, string p3)
 2         /// <summary>
 3         /// 獲取配置的年月日星期等資訊
 4         /// </summary>
 5         /// <param name="date"></param>
 6         /// <param name="p1"></param>
 7         /// <param name="p3"></param>
 8         /// <returns></returns>
 9         static List<int> GetConfigDate(DateTime date, int p1, string p3)
10         {
11             List<int> rets = new List<int>();
12             string p1Str = p1.ToString();
13             if ("*".Equals(p3) || p1Str.Equals(p3))
14             {
15                 rets.Add(p1);
16                 rets.Add(p1 + 1);
17             }
18             else if (p3.IndexOf("-") > 0)
19             {
20                 string[] weekSplit = p3.Split('-');
21                 int week1 = 9999;
22                 int.TryParse(weekSplit[0], out week1);
23 
24                 int week2 = 9999;
25                 int.TryParse(weekSplit[1], out week2);
26                 for (int i = week1; i < week2 + 1; i++)
27                 {
28                     rets.Add(i);
29                 }
30             }
31             else if (p3.IndexOf("/") > 0)
32             {
33                 string[] weeksSplit = p3.Split('/');
34                 foreach (var item in weeksSplit)
35                 {
36                     int temp = 0;
37                     if (int.TryParse(item, out temp))
38                     {
39                         rets.Add(temp);
40                     }
41                 }
42             }
43             else
44             {
45                 int temp = 0;
46                 if (int.TryParse(p3, out temp))
47                 {
48                     rets.Add(temp);
49                 }
50             }
51             return rets;
52         }
53         #endregion
54 
55         #region 獲取配置的時間字串 static List<string> GetConfigTimeStr(string itemTime)
56         /// <summary>
57         /// 獲取配置的時間字串 
58         /// </summary>
59         /// <param name="itemTime">必須類似的格式 單條 00:00-23:59  多條00:00-23:59/00:00-23:59</param>
60         /// <returns></returns>
61         static List<string> GetConfigTimeStr(string itemTime)
62         {
63             List<string> retObjs = new List<string>();
64             // 00:00-23:59
65             if (!"*".Equals(itemTime))
66             {
67                 var items = Regex.Split(itemTime, @"/");
68                 foreach (var item in items)
69                 {
70                     string[] itemTimes = item.Split('-');
71                     retObjs.Add(itemTimes[0]);
72                 }
73             }
74             else
75             {
76                 retObjs.Add("00:00");
77             }
78             return retObjs;
79         }
80         #endregion

這裡有一個蛋疼的問題,就是包含了星期,那麼無疑與日期就要牽涉跨星期跨月,跨年了,

在這裡特別鳴謝兄弟幫忙的分析。。

所以我分析出來,檢查包含的年月日來構造datetime 然後完成7天構造器。來分析時間段。

如果是本月那麼就從當前的日期開始,如果不是本月那麼就從1號開始,

 1         #region 處理星期包含的日期 日  static void ActionWeekDay(int weekmin, int weekmax, ref List<int> days, ref List<int> months, ref List<int> years)
 2         /// <summary>
 3         /// 處理星期包含的日期 日
 4         /// </summary>
 5         /// <param name="weekmin"></param>
 6         /// <param name="weekmax"></param>
 7         /// <param name="days"></param>
 8         /// <param name="months"></param>
 9         /// <param name="years"></param>
10         static void ActionWeekDay(int weekmin, int weekmax, ref List<int> days, ref List<int> months, ref List<int> years)
11         {
12             DateTime nowWeekDate = DateTime.Now;
13             List<int> tempDays, tempMonths, tempYears;
14             tempYears = years.ToList();
15             tempMonths = months.ToList();
16             tempDays = days.ToList();
17             foreach (var itemYear in tempYears)
18             {
19                 foreach (var itemMonth in tempMonths)
20                 {
21                     int itemDay = 1;
22                     if (nowWeekDate.Month == itemMonth)
23                     {
24                         itemDay = nowWeekDate.Day;
25                     }
26                     DateTime date = new DateTime(itemYear, itemMonth, itemDay);
27                     for (int i = 0; i < 7; i++)
28                     {
29                         int week = (int)date.DayOfWeek;
30                         if (week == 0)
31                         {
32                             week = 7;
33                         }
34                         if (weekmin <= week && week <= weekmax)
35                         {
36                             if (!days.Contains(date.Day))
37                             {
38                                 days.Add(date.Day);
39                             }
40                             if (!months.Contains(date.Month))
41                             {
42                                 months.Add(date.Month);
43                             }
44                             if (!years.Contains(date.Year))
45                             {
46                                 years.Add(date.Year);
47                             }
48                         }
49                         date = date.AddDays(1);
50                     }
51                 }
52             }
53         }
54         #endregion

驗證器

  1    #region 驗證時間:[*][*][20/22][*][10:00-11:59/16:00-17:59] static public long VerifyDateTime(string timeStr)
  2         /// <summary>
  3         /// 驗證時間:[*][*][20/22][*][10:00-11:59/16:00-17:59]
  4         /// <para>第一個是年,,第二個是月,第三個是日期,第四個是星期,第五個是時間,</para>
  5         /// <para>每一個引數,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/"  表示 或者 如: “2015/2017”表示2015 或者 2017</para>
  6         /// <para>返回值 -1 表示永久過期,0 表示在時間規則內,大於 0 表示倒計時</para>
  7         /// </summary> 
  8         static public long VerifyDateTime(string timeStr)
  9         {
 10             var items = Regex.Split(timeStr, @";|;");
 11             items.Reverse();
 12             long ret = -1;
 13             DateTime date = DateTime.Now;
 14             foreach (var item in items)
 15             {
 16                 //驗證時間匹配
 17                 if (VerifyConfigTimeStr(date, item))
 18                 {
 19                     ret = 0;
 20                     goto Lab_Exit;
 21                 }
 22                 //未通過時間匹配,檢查返回剩餘時間
 23                 List<string> strs = new List<string>();
 24                 string[] timeStrs = item.Split(new char[] { ']' });
 25                 for (int i = 0; i < timeStrs.Length - 1; i++)
 26                 {
 27                     string time = timeStrs[i].Replace("[", "");
 28                     strs.Add(time);
 29                 }
 30 
 31                 string times = strs[4];
 32                 string weeks = strs[3];
 33                 string days = strs[2];
 34                 string months = strs[1];
 35                 string years = strs[0];
 36 
 37                 int hour = 0, minute = 0, second = 0;
 38                 var tempYears = GetConfigDate(date, date.Year, years);
 39                 var tempMonths = GetConfigDate(date, date.Month, months);
 40                 var tempDays = GetConfigDate(date, date.Day, days);
 41                 //由於星期比較特殊所以獲取與星期相關的日期的時候有點詭異。
 42                 if (!"*".Equals(weeks))
 43                 {
 44                     if (weeks.IndexOf("-") > 0)
 45                     {
 46                         //星期的間隔模式
 47                         string[] weekSplit = weeks.Split('-');
 48                         int weekmin = 9999;
 49                         int.TryParse(weekSplit[0], out weekmin);
 50                         int weekmax = 9999;
 51                         int.TryParse(weekSplit[1], out weekmax);
 52                         ActionWeekDay(weekmin, weekmax, ref tempDays, ref tempMonths, ref tempYears);
 53                     }
 54                     else if (weeks.IndexOf("/") > 0)
 55                     {
 56                         //星期的或模式
 57                         string[] weeksSplit = weeks.Split('/');
 58                         int tempWeek;
 59                         if (int.TryParse(weeksSplit[0], out tempWeek))
 60                         {
 61                             if (0 <= tempWeek && tempWeek <= 7)
 62                             {
 63                                 ActionWeekDay(tempWeek, tempWeek, ref tempDays, ref tempMonths, ref tempYears);
 64                             }
 65                         }
 66                     }
 67                     else
 68                     {
 69                         //特定星期的模式
 70                         int tempweek = 0;
 71                         if (int.TryParse(weeks, out tempweek))
 72                         {
 73                             ActionWeekDay(tempweek, tempweek, ref tempDays, ref tempMonths, ref tempYears);
 74                         }
 75                     }
 76                 }
 77                 else
 78                 {
 79                     //未指定星期的模式
 80                     ActionWeekDay(1, 7, ref tempDays, ref tempMonths, ref tempYears);
 81                 }
 82 
 83                 var tempHHMMs = GetConfigTimeStr(times);
 84 
 85                 //進行簡單的排序
 86                 tempYears.Sort();
 87                 tempMonths.Sort();
 88                 tempDays.Sort();
 89                 tempHHMMs.Sort();
 90 
 91                 //接下來這裡是天坑,就是構造時間器比較,然後計算出倒計時
 92                 for (int y = 0; y < tempYears.Count; y++)
 93                 {
 94                     for (int m = 0; m < tempMonths.Count; m++)
 95                     {
 96                         for (int d = 0; d < tempDays.Count; d++)
 97                         {
 98                             for (int h = 0; h < tempHHMMs.Count; h++)
 99                             {
100                                 string[] hhmm = Regex.Split(tempHHMMs[h], ":|:");
101                                 if (int.TryParse(hhmm[0], out hour) && int.TryParse(hhmm[1], out minute))
102                                 {
103                                     DateTime actionTime = new DateTime(tempYears[y], tempMonths[m], tempDays[d], hour, minute, second);
104                                     if (actionTime > date)
105                                     {
106                                         if (VerifyConfigTimeStr(actionTime, item))
107                                         {
108                                             Console.WriteLine(actionTime.ToString("yyyy-MM-dd HH:mm:ss"));
109                                             TimeSpan ts = (actionTime - date);
110                                             ret = ts.Days * 24 * 60 * 60 + ts.Hours * 60 * 60 + ts.Minutes * 60 + ts.Seconds;
111                                             ret *= 1000;
112                                             ret += ts.Milliseconds;
113                                             goto Lab_Exit;
114                                         }
115                                     }
116                                 }
117                             }
118                         }
119                     }
120                 }
121             }
122         Lab_Exit:
123             return ret;
124         }
125         #endregion

驗證活動配置時間

[2016][2][*][*][10:00-11:59/14:00-16:59]

接下來我們在測試一下效能問題,

大家都懂的,在控制檯輸出列印是比較耗時的,這種情況下2000次也才1秒;效率是不必是說的。

全部完整程式碼。。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Text.RegularExpressions;
  6 using System.Threading.Tasks;
  7 
  8 /**
  9  * 
 10  * @author 失足程式設計師
 11  * @Blog http://www.cnblogs.com/ty408/
 12  * @mail [email protected]
 13  * @phone 13882122019
 14  * 
 15  */
 16 namespace Sz
 17 {
 18     /// <summary>
 19     /// 時間驗證器
 20     /// </summary>
 21     public static class TimeUtil
 22     {
 23 
 24         //static void Main(string[] args)
 25         //{
 26         //    Console.WriteLine("驗證當期時間是否滿足活動開放時間:[*][*][20/22][*][10:00-11:59/16:00-17:59]");
 27         //    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
 28         
            
           

相關推薦

程式支援複雜時間排程?如約而來的 java 版本

你的程式支援複雜的時間排程嘛? 這篇文章介紹了時間介面卡的c#版本,是給客戶端用的,伺服器自然也要有一套對應的做法,java版本的 [年][月][日][星期][時間] [*][*][*][*][*] 這樣利於分割,配置,清晰。 然後就是驗證,時間在不在配置的時間開發內? 當然想到的*肯定是預設支援所

程式支援複雜時間排程

時隔兩個月了,這段時間,遊戲籌備正式上線,根據遊戲平臺數據反饋,反響還不錯。 但是牽涉出新問題,就是活動。活動功能本身很簡單。問題就在於,時間配置上,什麼時間段開發活動。 配置多種多樣。比如,沒做星期2,4,6活動。每週的週六,週日,活動。指定月份和日期的活動。配置簡直是天花亂墜了。。。這尼瑪怎麼搞???

程式又放大招,小程式支援直播,快來看看能夠開發自己的直播小程式嗎?

小程式又放大招,小程式支援直播,快來看看你能夠開發自己的直播小程式嗎? https://blog.csdn.net/towtotow/article/details/78923839 https://blog.csdn.net/u012536034/article/details/80524748 &n

程式會做飯?我能!

別嘲笑這個標題。我想了很久。有點“投機取巧”的功效吧! 程式當然不能做飯。 之前的我們的系列文章,介紹, 多執行緒執行,任務派發。定時器執行。指令碼載入。程式狀態機。 這些都是零零散散,或者說都是模組化介紹,以及模組測試用例。 那麼今天我們就來模擬正常程式流程。使用上述的功能性程式碼完成流程。 當然

時間戳的換算,讓可以任意想要的時間形式

ace 星期 minutes sub test new date bst 小時 // 對Date的擴展,將 Date 轉化為指定格式的String// 月(M)、日(d)、小時(h)、分(m)、秒(s)、季度(q) 可以用 1-2 個占位符, // 年(y)可以用 1-4

30秒的時間會用Excel制作出一個抽獎功能嗎?

開始 可能 ndb 完整 不知道 index 返回 技術 操作 一說到抽獎,大家都是想到最近的“支付寶錦鯉信小呆”,但是今天跟大家談論的不是這個,而是:你會用Excel制作抽獎功能嗎?可能大家都不知道Excel有這麽多的神技能,但是你不知道的還有很多,Excel抽獎功能的制

如何統計PHP程式的執行時間、耗費記憶體

簡述 在專案開發中有時需要我們進行程式碼效率優化,這樣就需要知道我們的程式碼執行所需的時間,所佔用的記憶體等等問題。此篇博文就是簡單講一下如何統計PHP程式的執行時間和執行所需耗費的記憶體。 程式碼實現 <?php /** * ========================

微信小程程式支援/解析富文字內容

微信小程式不支援 html 標籤,可以使用外掛讓小程式自動解析 html 標籤並且正常顯示.推薦元件 wxParse ,github 地址 https://github.com/icindy/wxParse/ 使用淺析: 1. 下載元件 2. 複製 wxParse 資料夾

程式顯示執行時間

實現效果: 關鍵知識:   StatusStrip控制元件,TimeSpan的一些屬性,執行緒知識 實現程式碼: private void Form1_Load(object sender, EventArgs e) { DateTime

阿里巴巴程式設計師下班時間曝光,大牛程式設計師都是在用生命敲程式碼?

說起程式設計師人們的第一印象就是工資高、加班凶、話少錢多、頭髮少。再加上現在科技網際網路公司太吃香,BAT、華為、小米等公司程式設計師加班情況被廣泛傳播,程式設計師用生命在敲程式碼的印象刻在了很多人的心裡。 也許你對阿里的加班水平早有耳聞 但你是否見過他們瘋狂加班的樣子呢? 阿里巴巴

作業系統,核心定時器:使用“訊號”建立一種使用者空間機制來測量一個多執行緒程式的執行時間

      核心是一個作業系統的核心。它負責管理系統的程序、記憶體、裝置驅動程式、檔案和網路系統,決定著系統的效能和穩定性。 定時器是Linux提供的一種定時服務的機制,它在某個特定的時間喚醒某個程序來進行工作。核心在時鐘中斷髮生後檢測各定時器是否到期,在li

程式到這個時間點的時候,就可以執行。

import datetimeimport timec = datetime.datetime(2018,11,15,22,40,40) #這三句的意思是暫停程式執行。到2018年 11月15日 22:40:40秒以後才能執行。while datetime.datetime.now() < c:

使用 Rserve 實現 R 程式複雜資料返回

在 RCaller 無法返回複雜資料的研究 我們知道 RCaller 無法處理複雜資料的返回,那麼就看看其他工具吧,比如 Rserve。 使用下來的感覺是 Rserve 雖然能把值都給你,但是怎麼獲取卻是一個艱難的過程,比如和 RCaller 一樣,對矩陣值的讀取也是先列

ThinkPHP 釋出 5.1.30 版本,支援微秒時間欄位寫入

ThinkPHP V5.1.30(LTS)版本釋出,該版本為常規更新,改進了一些細節,修正了一些社群反饋的問題,支援上一版本的無縫升級(LTS版本不會再有任何的不相容更新)。 主要更新 支援時間欄位的微秒資料寫入 如果你的時間欄位使用的是datetime/timestamp型別的話,現在可以

用了python多程序,我跑程式花費的時間縮短了4倍

應用場景:本人需要對200萬條網頁html格式資料進行清洗,提取文字後將分詞結果寫入資料庫,之前做了一次,大概花費了80多個小時才跑完。機器配置是4核,記憶體8G;開完會領導讓再改點東西重新跑一遍,然後說用多程序或者多執行緒跑,速度快。 本人接觸python不到兩個月,以前也基本不怎麼程式設計,所以這種優化

過來人告訴——程式設計師如何找到第一份工作?

在很大一部分程式設計愛好者當中,有相當一部分是衝著成為程式設計師這個目的去的,遺憾的是,並非人人都能成為程式設計師。一個程式設計培訓班中,有一半的人後來沒有成為程式設計師,也是常事。 沒有工作經驗,學歷專業沒優勢,被慣性歧視,這是不少初學者找工作面臨的窘境。現實中,有很大一部分初學者成功

如何在 C++ 程式中計算時間

1.如果在基於 Windows Win32 的程式(純C++無法使用),即可以使用 GetTickCount() 函式實現。 精確到毫秒(ms)級。 DWORD dwStart = GetTickCount(); // 程式....... DWORD dwEnd = GetTickCou

c++ 求sum(n!),n可以為極大的數 並程式計算執行時間

 此程式為用C++求1! + 2! + 3! +  …… + n! 其中n可以為極大的數,通常情況下double型只能存放1! + 2! + 3! + …… + 170!採用陣列的方法儲存資料可以做到算無窮大的數的階乘的和,期限制因素只在於程式中定義的陣列的大小。假如有比該

程式/程序執行時間分析(user cpu time, system cpu time, elpapsed time)

1. 背景 近日做程式優化任務,程式碼不長,時間測試起來需要在for迴圈里加,破壞了程式執行的流水線,導致時間不準。網上查看了些相關資料,學到了一些東西,雖然對本任務沒用,但對於程式/程序執行時間可加深理解。 首先,需要明白的是: 我們平時常用的測量

C++中計算程式的執行時間

在我們實際開發中,尤其對於演算法工程師來說,有時候為了比較不同的演算法或者優化演算法,需要計算各個演算法執行的時間或者關鍵程式碼段的執行時間,以此來衡量演算法在速度上的優劣或者進行程式碼優化時的一個參考。 因此對於程式設計師來說,如何計算程式的執行時間就是一個需