מחלקת עזר לעיבוד נתונים שבועיים
-
בעקבות לקוח אחד שעושה בילינג מטורף עם העובדים שלו שמבוסס בעצם על שבועות (איך לא, של הוראה!!) נוכחתי לראות שמייקרוסופט השקיעו מעט מאוד בעיבוד תאריכים על בסיס שבועי, והיינו צריכים לעקם את הקוד מאוד כדי לנתח תאריכים, אי לכך הוחלט שנכתוב מחלקת סיוע עשירה ומהממת שיכולה לעזור לנו לנתח תאריכים כאשר העבודה מכוונת שבועות. אז היכונו לפרסום המחלקה בעזרת השם.
מה שאני צריך כאן את עזרת הציבור לפונקציה סטטית אחת שאני צריך להשלים, תפקידה הוא לקבל 2 תאריכים ולקבוע האם הם חלים באותו שבוע.
הנה המסגרת, צריך "רק" למלא אותה בקוד הגיוני בעל ביצועים טובים (זה אמור לרוץ על מאות אלפי פריטים שברשימה)מי שמשתתף יקבל כאן בחינם את כל הקוד הנפלא שעוזר מאוד למי שצריך לעבוד עם תאריכים בעלי משמעות שבועית.
/// <summary> /// בודק האם שני תאריכים חלים באותו שבוע /// בפרמטרים אפשר להכניס את התאריך הגדול או הקטן מביניהם בראשון או בשני אין זה משנה כלל /// !!!!!לא לשימוש באמצע פיתוח /// </summary> /// <param name="date1">תאריך שברצונך לבדוק</param> /// <param name="date2">התאריך שמולו ברצונך לבדוק</param> /// <returns>מחזיר אמת אם שני התאריכים חלים באותו שבוע ושקר אם לא</returns> static bool IsDatesInOneWeek(DateTime date1, DateTime date2) { return false; }
פורסם במקור בפורום CODE613 ב12/11/2015 23:22 (+02:00)
-
טוב אז זאת המחלקה:
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BillingService.BLL.DateTimeHelpers { public class Week { /// <summary> /// בנה מופע של שבוע מתוך תאריך כלשהו שבאמצע השבוע /// </summary> /// <param name="date">הכנס כאן תאריך כלשהו שחל בשבוע שברצונך לבנות</param> /// <param name="weekOrder">אם ברצונך לבנות רצף הכנס כאן את המספר הסידורי של הרצף שברצונך לבנות</param> public Week(DateTime date, int weekOrder = 0) { WeekOrder = weekOrder; //גורם לכך שבכל מקרה לא יוכל להיכנס ערך שגוי למחלקה ותמיד הערך של מתאריך יהפוך ליום ראשון של אותו שבוע בעל כרחו FromDate = FirstDateInWeek(date); ToDate = LastDateInWeek(date); } #region Members public int WeekOrder { get; private set; } public DateTime FromDate { get; private set; } public DateTime ToDate { get; private set; } #endregion #region WeeksList /// <summary> /// מחזיר ליסט מסוג אוביקט שבועות בהתבסס על טווח תאריכים נתון /// </summary> /// <param name="FromDate">מאיזה תאריך נרצה את הליסט</param> /// <param name="ToDate">עד איזה תאריך</param> /// <returns>מחזיר ליסט של שבועות שלמים בלבד!!! כלומר שבוע המתחיל ביום ראשון ומסתיים בשבת גם אם ניתנו פרמטרים של תאריכים באמצע שבוע</returns> public static List<Week> GetWeeksList(DateTime FromDate, DateTime ToDate) { List<Week> WorkList = new List<Week>(); var cal = CultureInfo.CurrentCulture; int identityWeekOrder = 0; //כל עוד נמצא בטווח התאריכים הנבדקים for (var dt = FirstDateInWeek(FromDate); dt <= LastDateInWeek(ToDate); dt = dt.AddDays((7))) { WorkList.Add(new Week(dt, ++identityWeekOrder)); } return WorkList; } #endregion #region PublicFunctions /// <summary> /// מחזיר ערך בוליאני האם תאריך מסויים חל בשבוע הנוכחי /// </summary> /// <param name="date">הכנס כאן תאריך כלשהו לבדיקה</param> /// <returns>מחזיר אמת אם התאריך אכן חל בשבוע של המופע הנוכחי</returns> public bool IsDateInThisWeek(DateTime date) { return (date >= this.FromDate && date <= this.ToDate); } #endregion #region PublicStaticHelpersFunctions /// <summary> /// מחזיר את היום הראשון בשבוע לפי תאריך נתון /// </summary> /// <param name="date">הכנס כאן תאריך כלשהו על מנת לקבל את היום הראשון בשבוע</param> /// <returns></returns> public static DateTime FirstDateInWeek(DateTime date) { return date.AddDays(-((int)date.DayOfWeek)); } /// <summary> /// מחזיר את היום האחרון בשבוע לפי תאריך נתון /// </summary> /// <param name="date">הכנס כאן תאריך כלשהו על מנת לקבל את היום האחרון שבאותו שבוע</param> /// <returns></returns> public static DateTime LastDateInWeek(DateTime date) { return date.AddDays((7 - ((int)date.DayOfWeek + 1))); } /// <summary> /// בודק האם שני תאריכים חלים באותו שבוע /// בפרמטרים אפשר להכניס את התאריך הגדול או הקטן מביניהם בראשון או בשני אין זה משנה כלל /// </summary> /// <param name="date1">תאריך שברצונך לבדוק</param> /// <param name="date2">התאריך שמולו ברצונך לבדוק</param> /// <returns>מחזיר אמת אם שני התאריכים חלים באותו שבוע ושקר אם לא</returns> public static bool IsDatesInOneWeek(DateTime date1, DateTime date2) { return (date2 >= FirstDateInWeek(date1) && date2 <= LastDateInWeek(date1)); } /// <summary> /// מחזיר כמה ימים באותו חודש יש מאותו יום בשבוע לפי תאריך נתון /// כלומר אם נתתי תאריך שיוצא ביום רביעי ובאותו חודש לועזי ישנם 5 ימי רביעי הערך המוחזר יהיה חמש וכן הלאה /// </summary> /// <param name="date">הכנס כאן ערך של תאריך מדוייק של אותו יום שברצונך לבדוק </param> /// <returns></returns> public static int CountDayInWeekPerMonth(DateTime date) { //על מנת לייעל ביצועים מכניסים כאן לדיקשנרי את תוצאות החישוב בשביל הפעם הבאה if (!staticCountDayInWeekPerMonthByDate.ContainsKey(date)) { staticCountDayInWeekPerMonthByDate.Add(date, CountDaysOfWeekBetweenDates(date.DayOfWeek, date.AddDays((-date.Day) + 1), date.AddMonths(1).AddDays(-date.Day))); } return staticCountDayInWeekPerMonthByDate[date]; } #endregion #region PrivateHelpMembers private static Dictionary<DateTime, int> staticCountDayInWeekPerMonthByDate = new Dictionary<DateTime, int>(); #endregion #region PrivateFunctions private static int CountDaysOfWeekBetweenDates(DayOfWeek day, DateTime start, DateTime end) { TimeSpan ts = end - start; // Total duration int count = (int)Math.Floor(ts.TotalDays / 7); // Number of whole weeks int remainder = (int)(ts.TotalDays % 7); // Number of remaining days int sinceLastDay = (int)(end.DayOfWeek - day); // Number of days since last [day] if (sinceLastDay < 0) sinceLastDay += 7; // Adjust for negative days since last [day] // If the days in excess of an even week are greater than or equal to the number days since the last [day], then count this one, too. if (remainder >= sinceLastDay) count++; return count; } #endregion } }
פורסם במקור בפורום CODE613 ב12/11/2015 23:46 (+02:00)
-
זאת בדיקת היחידה:
using BillingService.BLL.SequencingWithStudent.WorkingHelpers; using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using BillingService.BLL.SequencingWithStudent; using System.Collections.Generic; using System.Linq; using BillingService.BLL.DateTimeHelpers; namespace BillingService.BLL.Tests.SequencingWithStudent.WorkingHelpers { [TestClass] public class WeeksListTest { [TestMethod] public void GetWeeksListTest() { List<Week> Manuallist = new List<Week>(); Manuallist.Add(new Week(new DateTime(2015, 11, 10), 1)); Manuallist.Add(new Week(new DateTime(2015, 11, 18), 2)); Manuallist.Add(new Week(new DateTime(2015, 11, 26), 3)); var AutoList = Week.GetWeeksList(new DateTime(2015, 11, 10), new DateTime(2015, 11, 26)); //בדיקה שהשבוע שנוצר מתחיל ביום המצופה Assert.AreEqual(Manuallist.Where(w => w.WeekOrder == 1).First().FromDate, new DateTime(2015, 11, 8)); //בדיקה שהשבוע שנוצר מתחיל ביום ראשון בשבוע Assert.AreEqual(Manuallist.Where(w => w.WeekOrder == 1).First().FromDate.DayOfWeek, DayOfWeek.Sunday); //בדיקה שהשבוע שנוצר מסתיים בשבת Assert.AreEqual(Manuallist.Where(w => w.WeekOrder == 1).First().ToDate.DayOfWeek ,DayOfWeek.Saturday); //בדיקה שהליסט שנוצר אוטומטית שווה לליסט שיצרנו בכוחות עצמנו Assert.AreEqual(Manuallist.First(m=>m.WeekOrder==2).FromDate, AutoList.First(a => a.WeekOrder == 2).FromDate); //בדיקת פונקציה שקובעת אם שתי תאריכים חלים באותו שבוע Assert.IsTrue(Week.IsDatesInOneWeek(new DateTime(2016, 1, 4), new DateTime(2016, 1, 8))); Assert.IsFalse(Week.IsDatesInOneWeek(new DateTime(2016, 1, 1), new DateTime(2016, 1, 8))); } } }
פורסם במקור בפורום CODE613 ב12/11/2015 23:47 (+02:00)