الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

هل يوجد حل جذري لمشاكل تغير تنسيق التاريخ في ويندوز

بدأه yhab في 16 مايو 2008 · 12 رد · 2,346 مشاهدة · في لغة Delphi
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

الأخوة الأعزاء

السلام عليكم

كل مرة أضطر فيها للتعامل مع التاريخ في الاستعلام أواجه هذه المشكلة

لدي نافذة تحوي الحقول التابعة للجدول كالعادة وزر اسمه نمط البحث عند النقر عليه تفرغ الحقول ليدخل المستخدم المعلومات التي يريد البحث عنها وثم يضغط زر البحث الذي يشكل الاستعلام ديناميكيا ويأتي بالنتائج

لكن المشكلة في حقل التاريخ الذي سيختلف تنسيقه حسب اعدادات ويندوز والاستعلام يتطلب مني تحديد تنسيق التاريخ فعندما اغير هذا التنسيق أحصل على نتائج كارثية

أرجو أن يكون السؤال واضحا واتمنى المساعدة

تحياتي

#2

استخدم FormatDateTime لتغييره

قطرة الماء تـثـقب الحجر.. لا بالعنف. لكن بتكرار المحاولة

at4re.gif

منتديات الفريق العربي للهندسة العكسية 不喜欢的勿入! www.at4re.com

#3

و عليكم السلام

مرة قمت ببرمجة تطبيق لصالح إحدى الموسسات الحكومية وتفاجات بهاتف أن تطبيقي لا يعمل.. غريب

عندما انتقلت إليهم اكتشفت أن إعدادت الوقت تختلف عما أستعمله .. لذلك قمت بسرعة بالأتي

var ADay,AMonth,AYear: word;
begin 
  DecodeDate(now,AYear,AMonth,ADay);
  with MyQuery do
  begin
   close;
   SQL.Clear;
   SQL.Add('select * from MyDB where PDate + Periode < "'+inttostr(AMonth)+'/'+inttostr(ADay)+'/'+inttostr(AYear)+'"');
//   SQL.Add('select * from MyDB where PDate + Periode < "'+datetostr(now)+'"');  // هذه كانت المشكلة
   open;
end;
end;

كما توجد فكرة أخرى تعتمد على كيفية القراءة للوقت من طرف دلفي

Unité
System

Syntaxe Delphi :
type TDateTime =type Double;

أيضا TDate هي عبارة عن قيمة من TDateTime بدون الطرف العشري

يمكننا أن نعمل التالي

var t1:TDateTime;
	 V: double;
	 S: string;
begin
	t1:=now;
	V:=t1;
  Str(V:0:0,s);
	label1.caption:=S+' -- '+datetostr(V);
end;

في Label1 سيظهر رقم بدون القيمة العشرية وكذلك اليوم بالاعتماد على الرقم V، مثلا ليوم 11/05/2008 سيظهر : 11/05/2008 -- 39579

هكذا مهما تغير فاصل التاريخ (/ ، - ، .) قيمة V نفسها لا تتغير

بطبيعة الحال هذا اجتهاد مني ، قد تجد ماهو أحسن و/أو أوثق

تحياتي :)

تم تعديل هذه المشاركة بواسطة merouane في 16 مايو 2008 في 23:27

#4

شكرا للرد

سأدرس جوابك وسأحاول الاستفادة منه

وإذا توصلت لحل أفضل لن أتأخر في وضعه

#5

السلام عليكم

الاخ العزيز لماذ لا تجرب ان تغير الاعدادات الاقيلمية فى الجهاز بين الولايات المتحدة و المملكة المتحدة

هذا اذا كانت الويندوز انجليزية

والا فأنا مع استخدام (formatdatetime)

بالتوفيق

#6

الأخ العزيز c-vita

المشكلة أنني أريد أن يعمل الاستعلام مهما كان تنسيق التاريخ في ويندوز

أما formatdatetime فهي تتطلب معرفة هذا التنسيق

وشكرا للمرور

#7

يمكنك معرفة الإعدادات قبل تشكيل التاريخ ثم التعامل مع النتيجة

إذا كان البرنامج يعمل من البداية عند مستعمل واحد لا توجد مشكلة ، اما قاعدة البيانات مشتركة بين عدة مستعملين هنا يجب التعامل مع التاريخ قبل عملية البحث

Uses SysUtils;

  DateSeparator: Char;
  ShortDateFormat: string;
  LongDateFormat: string;

منه تستطيع معرفة تنسيق التاريخ ، بعده إذا أردت استعمل FormatDateTime

#8

هذا الكلام جميل جدا

شكرا جزيلا

#9

السلام عليكم...

في الواقع لسنا في حاجة إلى معرفة تنسيق التاريخ عند المستخدم، لكن يجب الانتباه إلى نقطتين:

1. أن الدالة StrToDate تقوم بتحويل النص إلى تاريخ حسب الإعدادات الإقليمية للمستخدم (Localization Information)و بالتالي يمكننا استعمالها لتحويل النص إلى تاريخ صحيح بصرف النظر عن الإعدادات في حاسوب المستخدم.

2. أن محركات قواعد البيانات تستخدم داخلياً النظام الأمريكي لتنسيق التاريخ (mm/dd/yyyy) أي الشهر قبل اليوم، و لهذا يجب إرسال التاريخ في جمل SQL بهذه الصيغة (باستعمال الدالة FormatDateTime).

الكود التالي (المأخوذ من أحد برامجي التجارية التي تتعامل مع قاعدة بيانات Access) يبين حل هذه المسألة:

var
	StartDate, EndDate: TDate;
begin
	// Other code here.

	StartDate := StrToDate(edtDate1.Text);
	EndDate := StrToDate(edtDate2.Text);

	SQLPart2 := ' WHERE (OperationDate >= #' + FormatDateTime('mm/dd/yyyy', StartDate)
		+ '#) AND (OperationDate <= #' + FormatDateTime('mm/dd/yyyy', EndDate) + '#)';

	qrySalesAndGains.Close;
	qrySalesAndGains.SQL.Clear;
	qrySalesAndGains.SQL.Text := SQLPart1 + SQLPart2;
	// Value of SQLPart1 is set in an other part of program.
	qrySalesAndGains.Open;

	// Other code here.

و إذا كنا نتعامل مع قاعدة بيانات SQL Server فإنه يمكننا وضع علامات اقتباس فردية (single quotation marks) بدل علامات #.

نرجو الاستفادة و السلام.

وَ قُلِ اعْمَلُوا فَسَيَرَى اللهُ عَمَلَكُمْ وَ رَسُولُهُ وَ الْمُؤْمِنُونَ

صدق الله العظيم

#10
اقتباس
في الواقع لسنا في حاجة إلى معرفة تنسيق التاريخ عند المستخدم،

بلا، نحتاج .. فعندما تستعمل قاعدة بيانات جاهزة للمستعمل، خاصة إذا هذه القاعدة تنتقل من حاسوب إلى أخر

أما بخصوص StrToDate فإذا أراد العمل مع المكونات الخاصة بالوقت فإنه لا يستطيع، و استعمالها يوفر لنا - وهذا ما ينقص في مثالك - التحقق من صحة التاريخ

#11

السلام عليكم...

أولاً أؤكد لك أنك لست في حاجة إلى ذلك، و أنا شخصياً "مرتاح" من هذه المشكلة الآن (بعدما عانيت منها في بداية تعلمي للبرمجة، مما دفعني إلى إنشاء بعض البرامج الشخصية الصغيرة خصيصاً لدراسة كيفية التعامل مع التاريخ).

ثانياً إذا كنت تستعمل في قاعدة البيانات حقولاً من النوع Text أو nvarchar أو غيرها من الحقول النصية لحفظ التواريخ (و قد رأيت بعضهم يفعل ذلك!) بدل النوع datetime فذلك عيب في تصميم قاعدة البيانات.

ثالثاً الوقت و التاريخ لا يخزن في قواعد البيانات على شكل نص بل في هيئة أعداد كسرية.

رابعاً الكود الذي كتبته في المشاركة السابقة هو جزء من إجراء (لعلك لاحظت عبارة "Other code here" في البداية) لأنني أردت فقط توضيح الجزء المتعلق بالمسألة متجاوزاً جمل التحقق من صحة التاريخ و غير ذلك.

خامساً إذا تم استخدام مكونات الوقت و التاريخ (مثل DateTimePicker) فإننا لسنا في حاجة لاستخدام الدالة StrToDate أصلاً، لكن ذلك لن يعفيك من استخدام الدالة FormatDateTime إذا كنت تريد الحصول على نتائج بحث صحيحة (FormatDateTime('mm/dd/yyyy', DateTimePicker1.Date)).

سادساً نرجو مرة أخرى الاستفادة و السلام.

وَ قُلِ اعْمَلُوا فَسَيَرَى اللهُ عَمَلَكُمْ وَ رَسُولُهُ وَ الْمُؤْمِنُونَ

صدق الله العظيم

#12

حاول استخدام الكود التالي في بداية برنامجك وستحل المشكلة بإذن الله:

  
  DateSeparator := '/';
  ShortDateFormat:= 'yyyy/MM/dd';

حيث أن :

yyyy أربع خانات عشرية للسنة .

MM خانتان عشريتان للشهر.

dd خانتان عشريتان لليوم.

مع ملاحظة حالة الحرف اللاتيني من حيث (سمول ، كابيتال).

مع تمنياتي بالتوفيق..

أخوكم / نجم..

تم تعديل هذه المشاركة بواسطة نجم في 3 ديسمبر 2008 في 03:29

#13

اخواني الكرام..تعقيباً على بعض مشاركات الأخوان..

لكل مبرمج طريقة في التعامل مع التاريخ ، وشخصياً أتعامل مع التاريخ في قواعد البيانات بصورة "تمثيل نصي" ، وذلك راجع لعدة أسباب منها:

1- عند التحويل للتاريخ الهجري والتعامل مع هذا التاريخ بصورة "تمثيل تاريخ" في استخراج نتيجة ما قد تحدث بعض الأخطاء التي لا يقبلها نظام ويندوز ويعتبرها خطأ.

2- عند إدخال التاريخ الهجري 30/02/1429هـ "بتمثيل تاريخ" ، فإن النظام لا يقبلها بأي حال من الأحوال ويعتبرها خطأ من المستخدم، وذلك راجع بأن النظام يعتمد التاريخ الميلادي كمرجعية له ويعتبر عدد أيام الشهر الثاني لكل سنة ميلادية هو 28 يوم للسنة البسيطة عدا السنة الكبيسة 29 يوما، ولا وجود لـ 30 يوما في هذا الشهر ، وقس على ذلك بقية أشهر السنة من كون بعضها 30 يوما ،31 يوما.

إن.. تمثيل التاريخ بصورة نصية وتخزينه في قواعد البيانات يعفيك من هذه المشاكل وليس لها أي تأثيرات من ناحية المقارنات أو الجمع والطرح والعمليات الحسابية الأخرى.

أيضاً.. يمكن وضع إدخالات المستخدم تحت الإختبار لضمان عدم إدخال تاريخ خطأ، ومنها على سبيل المثال MaskEdit بتنسيق التاريخ (!9999/99/00;1;_) .

أيضاً.. يعطي نفس النتائج عند تنفيذ تعليمات SQL على قواعد البيانات.

مع تمنياتي بالتوفيق..

أخوكم/نجم

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…