نقل قول:
نوشته شده توسط یكی از عزیزان برنامه نویس
با سلام خدمت شما دوست عزیز
دوست عزیز میخواستم اگر براتون امکان داره تابعی كه دوتاریخ رو با هم مقایسه میکنه رو بهم بدید من یک برنامه دارم که سرچ بین دو تاریخ و مقایسه آن برام مهمه.اگه براتون امکان داشت لطف کنید و تابع رو برام بفرستید
با تشکر از شما دوست گرامی
سلام...
یه توضیح كوچیك راجع به صورت سوال میدم، سپس میپردازم به حل اون و ...
صورت سوال:
نقل قول:
سلام
ببخشید کسی میتونه راهنمایی کنه که چطوری توی C# میتونم تداخل ساعت بگیرم ؟
من دو فیلد دارم که ساعت شروع و پایان را در فرمی در C# میدم و باید با ساعت های شروع و پایان دیگه ای که در پایگاه sql دارم در جدول قراره ملاقات چک بشه و اگر تداخلی وجود داشت آن را اعلام کنه .
نمیدونم نوع فیلد رو باید از چه نوعی تعریف کنم timedate یا شایدم text ؟
لطفاً اگه کسی می دونه راهنمایی کنه که چه کدی باید بنویسم .
با تشکر
توضیح كلی و ارائه ی راه حل برای حل سوال:
در حالتی كه فرض كنیم ساعت اول توی تاریخ اول و ساعت دوم توی تاریخ دوم قرار داره، یعنی مثلاً این دو تا زمان:
5 تیر 1388 ساعت 13:14:15
و
18 تیر 1388 ساعت 15:16:17
در این حالت، 13 حالت مختلف رو باید بررسی كرد برای بدست آوردن تمامی حالتهای تداخل موجود. كه توی این عكس براحتی قابل مشاهده هست:
https://barnamenevis.org/attach...1&d=1246040927
دو تا خط آبی ابتدا و انتهای زمان ها هستند.
خط قرمز بالا ابتدا و انتهای زمان ها هست.
خط های سبز 13 حالت مختلف هستند.
نقاط مشكی رو هم زدم كه بهتر بشه فهمید سر و ته ماجرا كجاست!
حالا اگر این 13 حالت رو یه جمع بندی كلی بكنیم، به سه حالت كلی میرسیم.
توضیح كامل شیوه ی حل مسئله و كد مورد نیاز:
این الگوریتم و شیوه ای كه الان میخوام خدمتتون عرضه كنم، نتیجه ی تقریباً 6 روز تفكر و بررسی بنده برای برای انجام این كار هست. و تا حد 100% به نتیجه ای كه میده ایمان دارم. چون توی پروژه ای ازش استفاده كردم كه اگر حتی یك ثانیه بین دو تا زمان مورد نظر، Collision وجود داشته باشه، محاله كه بشه خسارتش رو جبران كرد...
به هر حال،خیلی از كدها رو كه مشابه بودند یا مورد نیاز شما نبودند، از كدها حذف كردم و یك نمونه ی خیلی ساده رو برای شما ویرایش كردم و این هم توضیحاتش:
من توی جدولی به نام AfishTadvin چند تا فیلد دارم كه دو تا از فیلدهام از نوع DateTime هست. میدونیم كه هر كدوم از این فیلدها حاوی تاریخ و البته ساعت و دقیقه و ... هستند!
شیوه ای كه من ازش استفاده كردم، بدین ترتیب هست كه ابتدا Collision احتمالی موجود بین تاریخ های موجود رو با تاریخ های مورد نظرم، بدست میارم، سپس اگر Collision ای مشاهده شد، حالا میام دوباره Collision موجود بین زمان های مورد نظرم رو با زمان های داخل پایگاه داده بدست میارم. در نهایت اگر چنین Collision ای موجود بود، اون رو متوجه میشم و ...
این هم كد:
فرض كنید كه داخل رویداد یك دكمه این كد رو داریم. هر موقع دكمه زده شد، دو تاریخ مورد نظر خودمون و همچنین زمان های مورد نظرمون رو به تابع هایی كه در ادامه مینویسم، میفرستیم و ...
DateTime afishTimeFromCollision = new DateTime(faDatePicker1.SelectedDateTime.Year, faDatePicker1.SelectedDateTime.Month, faDatePicker1.SelectedDateTime.Day, ngmTimePicker1.Hour, ngmTimePicker1.Minute, 0);
DateTime afishTimeToCollision = new DateTime(faDatePicker2.SelectedDateTime.Year, faDatePicker2.SelectedDateTime.Month, faDatePicker2.SelectedDateTime.Day, ngmTimePicker2.Hour, ngmTimePicker2.Minute, 0);
string xAfishCodeTemp = "";
string xTempEqpSerial = "";
bool xContinue = true;
for (int i = 0; i < dataGridViewTolid.Rows.Count; i++)
{
xTempEqpSerial = dataGridViewTolid.Rows[i].Cells[1].Value.ToString();
if (myCollisionChecker.NGMEquipmentsCollisionDetectio n(xTempEqpSerial, afishTimeFromCollision, afishTimeToCollision))
{
xAfishCodeTemp = myCollisionChecker.AfishCode();
MessageBox.Show("Time Collision Detection... You are not able to continue!");
xContinue = false;
break;
}
}
if (!xContinue)
{
break;
}
این تابع اصلی هست كه درون اون دستور خاص مورد نیاز ساخته شده و به SQL داده میشه. اگر بین تاریخ های مورد نظر ما، و زمان های ذخیره شده توی بانك اطلاعاتیمون، Collision وجود داشته باشه، با استفاده از تابع بعدی كه در ادامه مینویسم، زمان های مورد نظر رو برای Collision بررسی میكنیم و ...
public bool NGMEquipmentsCollisionDetection(string eqpSerialNumber, DateTime afishTimeFrom, DateTime afishTimeTo)
{
_AfishCode = "";
TimeSpan mySpan = new TimeSpan();
mySpan = afishTimeTo - afishTimeFrom;
int dayCounter = mySpan.Days;
int myHourFrom = afishTimeFrom.Hour;
int myMinuteFrom = afishTimeFrom.Minute;
int myHourTo = afishTimeTo.Hour;
int myMinuteTo = afishTimeTo.Minute;
int xNum;
string[] xEqpList;
bool xTemp = false;
for (int i = 0; i <= dayCounter; i++)
{
DateTime xAfishTimeFrom = afishTimeFrom.AddDays(i);
_AfishTimeFrom = new DateTime(xAfishTimeFrom.Year, xAfishTimeFrom.Month, xAfishTimeFrom.Day, 0, 0, 0);
_AfishTimeTo = new DateTime(xAfishTimeFrom.Year, xAfishTimeFrom.Month, xAfishTimeFrom.Day, 23, 59, 59);
#region AfishTadvin
//Check the times for collision on SQL Command. If there is any collision on the DATES, SQL returns its rows...
cmd = new SqlCommand("SELECT AfishCode,EqpList,AfishTimeFrom,AfishTimeTo FROM AfishTadvin WHERE (AfishTimeFrom>=@p1 AND AfishTimeFrom<=@p2) OR (AfishTimeTo>=@p1 AND AfishTimeTo<=@p2) OR (AfishTimeFrom<=@p1 AND AfishTimeTo>=@p2)", con);
SqlParameter p1 = new SqlParameter("p1", _AfishTimeFrom);
SqlParameter p2 = new SqlParameter("p2", _AfishTimeTo);
p1.SqlDbType = SqlDbType.DateTime;
p2.SqlDbType = SqlDbType.DateTime;
SqlParameter[] parameterArray = new SqlParameter[] { p1, p2 };
foreach (SqlParameter parameterX in parameterArray)
{
cmd.Parameters.Add(parameterX);
}
try
{
con.Close();
con.Open();
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
try
{
while (true)
{
dr.Read();
myNGM = new NGMPersonsCodeString(dr[1].ToString());
xNum = myNGM.NGMPersonsCodeListCount;
xEqpList = new string[xNum];
if (xNum != 0)
{
for (int i1 = 0; i1 < xNum; i1++)
{
xEqpList[i1] = myNGM.NGMPersonsCodeList[i1];
}
}
//Now, after checking the DATEs collision, we should check the TIMEs collision if they have.
if (checkTimeCollision(myHourFrom, myMinuteFrom, myHourTo, myMinuteTo, DateTime.Parse(dr[2].ToString()).Hour, DateTime.Parse(dr[2].ToString()).Minute, DateTime.Parse(dr[3].ToString()).Hour, DateTime.Parse(dr[3].ToString()).Minute))
{
for (int i1 = 0; i1 < xNum; i1++)
{
if (xEqpList[i1].Equals(eqpSerialNumber))
{
_AfishCode = dr[0].ToString();
xTemp = true;
break;
}
}
}
}
}
catch (Exception)
{
//End of while with exception! LOL
}
}
else
{
xTemp = false;
}
}
catch (Exception)
{
//MessageBox.Show("NGM ERRORRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR: ");
}
if (xTemp)
{
break;
}
#endregion
else
{
xTemp = false;
}
}
con.Close();
if (xTemp)
{
//collision found
return (true);
}
else
{
//collision not found
return (false);
}
}
این هم از تابع آخر. كارش این هست كه Collision احتمالی بین دو زمان مختلف رو با دو زمان دیگه بررسی و نتیجه رو به ما اعلام میكنه...
//Check the times if they have collision in SIMPLE date!
private bool checkTimeCollision(int myHourFrom, int myMinuteFrom, int myHourTo, int myMinuteTo, int xHourFrom, int xMinuteFrom, int xHourTo, int xMinuteTo)
{
DateTime myFrom = new DateTime(2009, 9, 13, myHourFrom, myMinuteFrom, 0);
DateTime myTo = new DateTime(2009, 9, 13, myHourTo, myMinuteTo, 0);
DateTime xFrom = new DateTime(2009, 9, 13, xHourFrom, xMinuteFrom, 0);
DateTime xTo = new DateTime(2009, 9, 13, xHourTo, xMinuteTo, 0);
if ((myFrom >= xFrom) && (myFrom <= xTo) || ((myTo >= xFrom) && (myTo <= xTo)) || ((myFrom <= xFrom) && (myTo >= xTo)))
{
if (myTo == xFrom || myFrom == xTo)
{
return (false);
}
else
{
return (true);
}
}
else
{
return (false);
}
}
توضیح خاصی نیاز نمیبینم! مگر اینكه بگم چون این كد ها رو از توی پروژه ی خودم كپی كردم اینجا، شاید بعضی از مقادیر و كلاس هایی كه استفاده شده، براتون نامفهوم باشه! اصل ماجرا رو ولی براحتی میتونید برداشت كنید. ان شاء الله.
پاینده باشید و سرافراز.
یا علی مدد