ASP.Net How to Store Time Value in Database

15. April 2009

نحوه ذخیره ساعت در ASP.Net

تاریخ و ساعت در برنامه نویسی حکایتهای زیادی دارند، و باید مورد توجه واقع شوند، مخصوصا وقتی که جزئی مهم از برنامه به حساب بیایند. مثل برنامه ای که قراره نظرات ارسالی از طرف کاربران رو نشون بده و البته به همراه تاریخ و ساعت اونها. یا تاریخ و ساعت خریدی که از طرف یه بنده خدایی انجام شده.
به طور کلی وقتی این مقادیر قراره جلوی چشم همه توی متن وبسایت باشند، اهمیت بیشتری پیدا میکنند.
طبیعتا ما دوست داریم تاریخ و ساعت با فرمت مناسب نوشته بشه، مثل: “چهارشنبه 26 فروردین سال 1388” به جای “26/1/88” و البته به نظر من زمان رو “درست” نشون دادن هم به همین مهمی هست.

به طور مثال: کاربر سایت، خریدی رو انجام میده ساعت 11 صبح،  و سه ساعت بعد وارد حساب شخصیش میشه تا ببینه وضعیت خریدش به چه صورت هست، ارسال شده یا نشده و این جور چیزها. خریدش رو پیدا میکنه، و میخواد روی لینک “جزییات” کلیک کنه، اما تعجب میکنه! ساعت خرید اون جنس، 16:30 نوشته شده، یعنی حدود دو ساعت و نیم “بعد” از الان!
اگر کاربر گوشی دستش باشه، میفهمه جریان چیه.. اگه هم از برنامه نویسی اطلاعی نداشته باشه، خوب این موضوع میخوره تو ذوقش! شاید اصلا فکر کنه این سایت در پیته (:دی) ، سفارشش رو کنسل کنه و بره دیگه پشت سرش رو نگاه نکنه.
اما موضوع چیه؟
ساعت خرید، با استفاده از دستور Date.Now در دیتابیس ذخیره شده، یعنی به زمان سرور و هنگام خوندنش از دیتابیس طبیعتا همین مقدار هست که برمیگرده. و البته فرض کردیم که سرور ما در ایران نیست پس هر جای دیگه ای که باشه، بالاخره یه اختلاف ساعتی با ما داره. سرور مثال ما هم اختلاف ساعت پنج ساعت و نیمه داشته با ساعت شخصی که خرید کرده.

چه کار باید کرد؟
2 راه به نظر میرسه و یا شاید 3 راه!
راه اول: فرض کنیم سرور ما در اروپا و کشور اسپانیا قرار داره. اونوقت میایم تو صفحه خرید با حروف درشت و رنگ قرمز مینویسیم:
“تمامی زمانها به وقت محلی کشور اسپانیا میباشد.”
خوب، راه حل خیلی لوسیه، و یه جورایی مسخرست.. چرا؟ فکر کن!

راه دوم: اگر بتونیم فرض کنیم که سرویس ما فقط برای کاربران ایرانی داخل ایران هست، میتونیم اختلاف ساعت سرور با ایران رو اندازه بگیریم، و زمان های خونده شده از دیتابیس رو تصحیح کنیم. راه خوبی به نظر میرسه.. و در همون صفحه مینویسیم که زمان به وقت محلی در ایران میباشد.
خوب این قابل قبول میتونه باشه. چون 90% کاربرهای سایت ما ایرانی هستند و این زمان براشون مناسب خواهد بود، بقیه هم جزو اقلیت هستند که باز میفهمن جریان این ساعت چیه.
اما این کار رو چجوری انجام بدیم؟
در web.config  این عبارت رو قرار بدید:

<appSettings>
    <add key="DefaultTimeZone" value="3:30"/>
</appSettings>

به سادگی یه متغیر درست کردیم، اسمش رو گذاشتیم DefaultTimeZone و به اون مقدار 3:30 دادیم، یعنی در این مثال باید به ساعت سرور ، سه ساعت و سی دقیقه اضافه کنیم تا بشه ساعت ایران. اگر باید زمان کم میکردیم، این مقدار میشد:

<appSettings>
    <add key="DefaultTimeZone" value="-1:30"/>
</appSettings>

بیشتر در مورد web.config

چرا حالا تو web.config ذخیره کنیم؟ چرا مستقیم تو سورس برنامه این اختلاف ساعت رو وارد نکنیم؟
خوب، برای اینکه در web.config یک بار تعریف میکنیم، و از متغیر DefaultTimeZone در سورس برنامه هزار بار استفاده میکنیم، اگر یه وقت این مقدار عوض شد ( مثل وقتی که ساعت ها رو جلو عقب میکشیم یا اصلا مجبور شدیم سرور رو عوض کنیم و محل سرور که عوض بشه اختلاف ساعتش هم عوض میشه ) یک بار تو web.config تغییر میدیم و این تغییر خود به خود در 1000 جای برنامه که از این متغیر استفاده کردیم، اعمال میشه.. ( این موضوع تا حدودی واضح بود، ولی دیگه دستم گرم شده به تایپ، گفتم بنویسم :دی )

حالا در سورس برنامه به این صورت عمل میکنیم:

Dim ServerDate As Date = ReadTimeFromDataBase

Dim ts As TimeSpan
ts = TimeSpan.Parse(ConfigurationManager.AppSettings("DefaultTimeZone"))

Dim toIranDate As Date = ServerDate.Add(ts)

در خط اول، مقدار زمان رو به هر روشی، از دیتابیس خوندیم. و بعد با استفاده از ConfigurationManager.AppSettings و اسم متغیر که تعریف کرده بودیم، مقدار اختلاف ساعت رو خوندیم و داخل یک متغیر از نوع TimeSpan ریختیم. و در نهایت با متد Add مقدار اختلاف زمان رو با ساعت خونده شده از دیتابیس، جمع کردیم. ( خوب معلومه اگه مقدار متغیر تو web.config منفی باشه، این مقدار از سرور کم میشه خوب! )
به همین سادگی!

راه سوم:
در این روش، خیلی دیگه به کاربرامون عشق میورزیم و موقع ثبت نام اولیه ازشون میپرسیم: ساعتتون چنده؟ و مقداری که وارد شده رو از ساعت کنونی سرور کم میکنیم و بدین صورت اختلاف زمان کاربر با سرور مشخص میشه و اون رو وارد دیتابیس میکنیم، و مثل مورد دوم، این اختلاف رو اعمال میکنیم با این تفاوت که دیگه اختلاف ساعت رو از web.config نمیخونیم. اون رو هم از دیتابیس خوندیم..

 

اما نکته اصلی که تو این پست کلا میخواستم بهش اشاره کنم:  ( البته اگه هنوز بیداری )
در همون مرحله ذخیره تاریخ و زمان، بهتره که زمان رو به جای اینکه زمان سرور ذخیره کنیم، اون رو به فرمت UTC ذخیره کنیم.
فرض کنید دیتابیس های شما بر روی شبکه داخلی شما یا به صورت لوکال بر روی دستگاه خود شما ساخته شده و یک سری اطلاعات که زمان وارد شدن اونها هم مهم بوده، وارد شده. حالا میخواهید این دیتابیس رو به سرور اصلی روی اینترنت بفرستید و حالا در ادامه حیات سایت شما، باز هم اطلاعات در اون وارد میشه، و شاید چند ماه بعد بخواهید سرور رو عوض کنید.. در طول همه این تغییر و تحولات، زمان های ثبت شده اگر به زمان سرور ذخیره شده باشند، شما 3 مدل ساعت دارید: ساعت ایران، زمان به وقت سرور اول و دوم. یعنی حالا جدای اینکه به کاربر نهایی چه زمانی نشون بدید، زمان های داخل دیتابیس از همون اول با هم اختلاف دارند.
خوب اگر از اول همه این زمان ها به فرمت مبدا جهانی UTC باشه، دیگه مشکلی نداریم از این بابت که سرور رو عوض کنیم و بخواهیم نگران تغییرات ساعت باشیم!

برای این کار به جای Date.Now از Date.UTCNow استفاده میکنیم. به همین راحتی. و با استفاده از ToLocalTime، این زمان رو میتونیم برگردونیم به زمان سرور. ( این کار رو فریم ورک انجام میده در پشت صحنه با توجه به تنظیمات TimeZone در ویندوز نصب شده رو سرور )

'خواندن ساعت کنونی با فرمت یو تی سی
Dim date1 As Date = Date.UtcNow

'تبدیل زمان یو تی سی به زمان سرور
Dim date2 As Date = date1.ToLocalTime

و بعدش میتونیم با استفاده از تکنیکهای گفته شده (راه اول و دوم) زمان رو به کاربر نهایی نشون بدیم.

تمام.

*این مطالب از خودم میباشد! اگر در اون مورد اشتباهی میبینید، ممنون میشم که اعلام کنید و استفاده از این مطلب آزاد هست و اگر دوست دارید با انصاف باشید، منبع رو هم ذکر کنید.


دسته بندی موضوعی: ASP.Net
برچسب ها: - - - -

Comments

javad
javad
1/10/2010 10:03:48 AM #
سلام persian calander فقط تاریخ و تبدیل می کنه کاری به ساعت نداره ؟
البته خودم بعدا تست میکنم
ممنون
me
1/10/2010 10:36:57 AM #
جواد:
خوب ساعت که کاری به زبون طرف نداره - مهم محل زندگی هست. پس تبدیل کردنش بر اساس زبون یک کشور مفهومی نداره Smile

Pingbacks & Trackbacks

  1. pingback from: zabet.ir   (29 Sep 2009)

Add comment


(Will show your Gravatar icon)

biuquoteLTR
Loading



Clicky Web Analytics
Subscribe
Follow me