قيمة التاريخ والوقت "فارغة".
سؤال
لقد بحثت كثيرا ولكن لم أجد حلا.كيف تتعامل مع DateTime الذي يجب أن يكون قادرًا على احتواء قيمة غير مهيأة (أي ما يعادل قيمة خالية)؟لدي فئة قد تحتوي على قيمة خاصية DateTime أم لا.كنت أفكر في تهيئة مالك الخاصية إلى DateTime.MinValue، والذي يمكن بعد ذلك التحقق منه بسهولة.أعتقد أن هذا سؤال شائع جدًا، كيف يمكنك أن تفعل ذلك؟
المحلول
لDateTimes العادية، إذا لم يكن لتهيئة لهم على الإطلاق بعد ذلك سوف تطابق DateTime.MinValue
، لأنه هو نوع القيمة بدلا من نوع مرجع.
ويمكنك أيضا استخدام التاريخ والوقت قيم الفارغة، مثل هذا:
DateTime? MyNullableDate;
وأو شكل أطول:
Nullable<DateTime> MyNullableDate;
وأخيرا، هناك بنيت في الطريق إلى مرجع تقصير من أي نوع. هذا يعود null
لأنواع المرجعية، ولكن على سبيل المثال لدينا التاريخ والوقت فإنه سيعود نفس DateTime.MinValue
:
default(DateTime)
نصائح أخرى
إذا كنت تستخدم الصافي 2.0 (أو الأحدث)، يمكنك استخدام نوع قيم الفارغة:
DateTime? dt = null;
أو
Nullable<DateTime> dt = null;
وبعد ذلك في وقت لاحق:
dt = new DateTime();
ويمكنك التحقق من القيمة مع:
if (dt.HasValue)
{
// Do something with dt.Value
}
أو يمكنك استخدامه مثل:
DateTime dt2 = dt ?? DateTime.MinValue;
ويمكنك قراءة المزيد هنا:
http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx
والتاريخ والوقت؟ MyDateTime {الحصول؛ مجموعة؛}
MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);
وبعد الطريقة التي يعمل بها، وكذلك
myClass.PublishDate = toPublish ? DateTime.Now : (DateTime?)null;
تجدر الإشارة إلى أن PublishDate الملكية يجب أن يكون التاريخ والوقت؟
فما استقاموا لكم فاستقيموا النظر في استخدام أنواع nullable أ >.
وDateTime? myDate
بدلا من DateTime myDate
.
ويمكنك استخدام فئة قيم الفارغة.
DateTime? date = new DateTime?();
ويمكنك استخدام التاريخ والوقت قيم الفارغة لذلك.
Nullable<DateTime> myDateTime;
وأو نفس الشيء مكتوبة مثل هذا:
DateTime? myDateTime;
وأنا دائما ضبط الوقت إلى DateTime.MinValue
. بهذه الطريقة وأنا لا تحصل على أي NullErrorException ويمكنني مقارنتها إلى تاريخ أعرف لم يتم تعيين.
وتجدر الإشارة إلى أنه، في حين لا يمكن DateTime
متغير null
، فإنه لا يزال يمكن مقارنة null
دون خطأ المترجم:
DateTime date;
...
if(date == null) // <-- will never be 'true'
...
ويمكنك ضبط التاريخ والوقت إلى قيم الفارغة. افتراضيا التاريخ والوقت ليس قيم الفارغة. يمكنك ان تجعل من قيم الفارغة في عدة طرق. باستخدام علامة استفهام بعد نوع التاريخ والوقت؟ myTime أو باستخدام أسلوب عام قيم الفارغة. واضاف لقد اثنين من الروابط على MSDN.
فقط كن حذرًا - عند استخدام Nullable، من الواضح أنه لم يعد كائنًا "نقيًا" للتاريخ والوقت، وبالتالي لا يمكنك الوصول إلى أعضاء DateTime مباشرة.سأحاول أن أشرح.
باستخدام Nullable<> فإنك تقوم بشكل أساسي بتغليف DateTime في حاوية (شكرًا لك على الأدوية العامة) والتي تكون خالية - ومن الواضح أن الغرض منها.تحتوي هذه الحاوية على خصائصها الخاصة التي يمكنك الاتصال بها والتي ستوفر الوصول إلى كائن DateTime المذكور أعلاه؛بعد استخدام الخاصية الصحيحة - في هذه الحالة Nullable.Value - يمكنك بعد ذلك الوصول إلى أعضاء DateTime القياسيين والخصائص وما إلى ذلك.
إذن - تتبادر الآن إلى الذهن مسألة أفضل طريقة للوصول إلى كائن DateTime.هناك عدة طرق، الرقم 1 هو الأفضل على الإطلاق والرقم 2 هو "لماذا يا صاح".
باستخدام خاصية Nullable.Value،
DateTime date = myNullableObject.Value.ToUniversalTime(); //Works
DateTime date = myNullableObject.ToUniversalTime(); //Not a datetime object, fails
تحويل الكائن الفارغ إلى وقت التاريخ باستخدام Convert.ToDateTime()،
DateTime date = Convert.ToDateTime(myNullableObject).ToUniversalTime(); //works but why...
على الرغم من أن الإجابة موثقة جيدًا في هذه المرحلة، أعتقد أن استخدام Nullable ربما كان يستحق النشر عنه.آسف إذا كنت لا توافق.
يحرر:تمت إزالة الخيار الثالث لأنه كان محددًا بشكل مفرط ويعتمد على الحالة.
على الرغم من أن الجميع قد أعطاك الإجابة بالفعل، إلا أنني سأذكر طريقة تجعل من السهل تمرير التاريخ والوقت إلى إحدى الوظائف
[خطأ: لا يمكن تحويل system.datetime؟إلى النظام.التاريخ والوقت]
DateTime? dt = null;
DateTime dte = Convert.ToDateTime(dt);
يمكنك الآن تمرير dte داخل الوظيفة دون أي مشاكل.
إذا كنت، في بعض الأحيان، وتتوقع لاغية هل يمكن استخدام شيء من هذا القبيل:
var orderResults = Repository.GetOrders(id, (DateTime?)model.DateFrom, (DateTime?)model.DateTo)
في الخاص بك مستودع استخدام التاريخ والوقت، لاغية قادرة.
public Orders[] GetOrders(string id, DateTime? dateFrom, DateTime? dateTo){...}
وكان لي نفس المشكلة كما كان لي لإعطاء فارغة كمعلمة للالتاريخ والوقت أثناء أداء اختبار وحدة الرميات عملت ArgumentNullException.It في حالتي باستخدام الخيار التالي:
Assert.Throws<ArgumentNullException>(()=>sut.StartingDate = DateTime.Parse(null));
نظرًا لطبيعة نوع بيانات التاريخ/الوقت، لا يمكن أن يحتوي على ملف null
القيمة، أييجب أن يحتوي على قيمة، ولا يمكن أن يكون فارغًا أو لا يحتوي على أي شيء.إذا قمت بوضع علامة على متغير التاريخ/الوقت كـ nullable
عندها فقط يمكنك تعيين قيمة فارغة لها.لذا فإن ما تتطلع إلى القيام به هو أحد أمرين (قد يكون هناك المزيد ولكن لا يمكنني التفكير إلا في اثنين):
قم بتعيين الحد الأدنى لقيمة التاريخ/الوقت للمتغير الخاص بك إذا لم يكن لديك قيمة له.يمكنك أيضًا تعيين الحد الأقصى لقيمة التاريخ/الوقت - بأي طريقة تناسبك.فقط تأكد من أنك متسق على مستوى الموقع عند التحقق من قيم التاريخ/الوقت.اتخاذ قرار بشأن استخدام
min
أوmax
والتشبث به.قم بتمييز متغير التاريخ/الوقت الخاص بك كـ
nullable
.بهذه الطريقة يمكنك ضبط متغير التاريخ/الوقت علىnull
إذا لم يكن لديك متغير لذلك.
اسمحوا لي أن أوضح نقطتي الأولى باستخدام مثال.ال DateTime
لا يمكن تعيين نوع المتغير على قيمة فارغة، فهو يحتاج إلى قيمة، وفي هذه الحالة سأقوم بتعيينه على قيمة DateTime
الحد الأدنى لقيمة إذا لم يكن هناك قيمة.
السيناريو الخاص بي هو أن لدي BlogPost
فصل.يحتوي على العديد من الحقول/الخصائص المختلفة ولكني اخترت استخدام اثنين فقط لهذا المثال. DatePublished
هو الوقت الذي تم فيه نشر المنشور على موقع الويب ويجب أن يحتوي على قيمة تاريخ/وقت. DateModified
هو عندما يتم تعديل المنشور، لذلك ليس من الضروري أن يحتوي على قيمة، ولكن يمكن أن يحتوي على قيمة.
public class BlogPost : Entity
{
public DateTime DateModified { get; set; }
public DateTime DatePublished { get; set; }
}
استخدام ADO.NET
للحصول على البيانات من قاعدة البيانات (عيّن DateTime.MinValue
ليس هناك قيمة ):
BlogPost blogPost = new BlogPost();
blogPost.DateModified = sqlDataReader.IsDBNull(0) ? DateTime.MinValue : sqlDataReader.GetFieldValue<DateTime>(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);
يمكنك إنجاز نقطتي الثانية عن طريق وضع علامة على DateModified
الحقل كما nullable
.الآن يمكنك ضبطه على null
إذا لم يكن هناك قيمة لذلك:
public DateTime? DateModified { get; set; }
استخدام ADO.NET
للحصول على البيانات من قاعدة البيانات، سيبدو الأمر مختلفًا بعض الشيء عن الطريقة التي تم بها أعلاه (تعيين null
بدلاً من DateTime.MinValue
):
BlogPost blogPost = new BlogPost();
blogPost.DateModified = sqlDataReader.IsDBNull(0) ? (DateTime?)null : sqlDataReader.GetFieldValue<DateTime>(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);
آمل أن يساعد هذا في إزالة أي لبس.نظرًا لأن ردي كان بعد حوالي 8 سنوات، فمن المحتمل أن تكون الآن مبرمجًا خبيرًا في لغة C# :)