چگونه در ASP.NET تاریخ میلادی را به شمسی تبدیل کنیم؟ فرض کنید درون پایگاه داده SQL Server جدولی ساخته اید و یکی از ستون های آن را از نوع datetime تعریف کرده اید. استفاده از نوع داده ای datetime کاربر را ملزم می کند که فقط از تاریخ های میلادی استفاده کند. در صورتی که کاربر از تاریخ های دیگری (مثلا هجری شمسی) استفاده کند، با خطا مواجه می شود. در ادامه، با به کارگیری زبان سی شارپ راهکاری برای رفع این مشکل ارائه می دهیم.
یکی از اولین راه حل هایی که برای غلبه بر این مشکل به ذهن میرسد این است که به جای تعریف ستون جدول از نوع datetime، آن را از نوع nvarchar تعریف کنیم. این کار سبب می شود که کاربر تاریخ مورد نظر خود را درون پایگاه داده به صورت رشته وارد کند. راهکار ذکر شده در مواردی می تواند مفید واقع شود اما مشکلاتی را نیز به همراه دارد و ممکن است در بعضی مواقع پاسخگوی نیازهای ما نباشد.
روش دیگر این است که تاریخ هجری شمسی وارد شده توسط کاربر را به طریقی به میلادی تبدیل کنیم و سپس تاریخ میلادی به دست آمده را درون فیلدی که از نوع datetime است ذخیره کنیم. این کار با استفاده از کلاس PersianCalendar که در فضای نام System.Globalization واقع است امکان پذیر می باشد. کلاس PersianCalendar دارای متدهایی گوناگونی است که در ادامه به برخی از آن ها اشاره می کنیم:
بعد از خواندن فیلدی از نوع datetime از پایگاه داده، میتوانیم با استفاده از متدهای GetDayOfMonth ، GetMonth و GetYear آن را به هجری شمسی تبدیل کرده و سپس به کاربر نمایش دهیم.(در ادامه خواهیم دید) بدین ترتیب کاربر تاریخ مورد نظر خود را از طریق واسط کاربر به صورت هجری شمسی وارد می کند و هنگامی هم که می خواهد آن ها را از پایگاه داده بازیابی کند، آن ها را به صورت هجری شمسی مشاهده خواهد کرد، اما در اصل، داده ها درون پایگاه داده به شکل صحیح خود یعنی میلادی وارد شده اند.حال جهت ارائه یک مثال، با استفاده از ASP.NET یک webform به عنوان واسط کاربر طراحی می کنیم و موارد ذکر شده را با استفاده از آن توضیح خواهیم داد.
در اینجا می خواهیم از پایگاه داده Northwind استفاده کرده و نام، نام خانوادگی و تاریخ استخدام افراد را از جدول Employees بازیابی کنیم و آن ها را در یک gridview نمایش دهیم. همچنین می خواهیم امکان وارد کردن کارمند جدید به این جدول را نیز داشته باشیم. پس فرمی مانند زیر طراحی کرده و برای برقراری ارتباط با پایگاه، یک SqlDataSource نیز به آن اضافه می کنیم:
سپس تنظیمات لازم را برای ارتباط SqlDataSource با پایگاه داده Northwind و بازیابی نام، نام خانوادگی و تاریخ استخدام کارمندان را انجام می دهیم:
<asp:GridView ID="gvEmployees" CssClass="gridStyle" runat="server" Caption="کارمندان موجود در پایگاه داده" DataSourceID="sqlDtSrcEmployees"> <AlternatingRowStyle BackColor="#FF99CC" /> <EditRowStyle BackColor="#FF99CC" /> <HeaderStyle BackColor="#FF66CC" Font-Bold="True" Font-Names="Calibri" ForeColor="White" /> <RowStyle BackColor="#FFCCFF" Font-Names="Calibri" HorizontalAlign="Center" /> </asp:GridView> <asp:SqlDataSource ID="sqlDtSrcEmployees" runat="server" ConnectionString="<%$ ConnectionStrings:Northwind %>" InsertCommand="INSERT INTO [Employees] ([LastName], [FirstName], [HireDate]) VALUES (@LastName, @FirstName, @HireDate)" ProviderName="System.Data.SqlClient" SelectCommand="SELECT [EmployeeID], [LastName], [FirstName], [HireDate] FROM [Employees]"> <InsertParameters> <asp:ControlParameter ControlID="txtLastName" Name="LastName" PropertyName="Text" Type="String" /> <asp:ControlParameter ControlID="txtFirstName" Name="FirstName" PropertyName="Text" Type="String" /> <asp:Parameter Name="HireDate" Type="DateTime" /> </InsertParameters> </asp:SqlDataSource>
حال به قسمت مورد بحث یعنی بازیابی تاریخ به صورت هجری شمسی می پردازیم. GridView دارای یک رویداد به نام RowDataBound می باشد. این رویداد بعد از databound شدن هر سطر GridView اتفاق می افتد. می توانیم از این رویداد استفاده کرده و پس از Databound شدن هر سطر، فیلد تاریخ آن را با استفاده از متدهای ذکر شده در بالا از میلادی به هجری شمسی تبدیل کنیم:
protected void gvEmployees_RowDataBound(object sender, GridViewRowEventArgs e) { try { if (e.Row.RowType == DataControlRowType.DataRow) { DateTime usDate = (DateTime)DataBinder.Eval(e.Row.DataItem, "HireDate"); System.Globalization.PersianCalendar faDate = new System.Globalization.PersianCalendar(); string day = faDate.GetDayOfMonth(usDate).ToString("D2"); string month = faDate.GetMonth(usDate).ToString("D2"); string year = faDate.GetYear(usDate).ToString("D4"); e.Row.Cells[3].Text = string.Format("{0} / {1} / {2}", year, month, day); } } catch { } }
اگر برنامه را اجرا کنید، نتیجه ای مانند زیر مشاهده خواهید کرد. (تمامی تاریخ های زیر ستون HireDate به هجری شمسی تبدیل شده اند.)
حال به حالتی می پردازیم که کاربر می خواهد کارمند جدیدی را در پایگاه داده ثبت کند و تاریخ استخدام را نیز به هجری شمسی وارد می کند. ما باید قبل از اجرای دستور insert تاریخ وارد شده را به میلادی تبدیل کنیم. برای این کار به سراغ SqlDataSource می رویم. SqlDataSource دارای رویدادی به نام Inserting می باشد. این رویداد دقیقا قبل از این که عملیات Insert اجرا شود، فعال می شود و ما می توانیم از طریق آن پارامترهای لازم را برای دستور insert فراهم کنیم. (مثلا تاریخ وارد شده توسط کاربر را به میلادی تبدیل کنیم):
protected void sqlDtSrcEmployees_Inserting(object sender, SqlDataSourceCommandEventArgs e) { try { int day = Convert.ToInt32(txtHireDay.Text); int month = Convert.ToInt32(txtHireMonth.Text); int year = Convert.ToInt32(txtHireYear.Text); System.Globalization.PersianCalendar faDate = new System.Globalization.PersianCalendar(); e.Command.Parameters["@HireDate"].Value = faDate.ToDateTime(year, month, day, 23, 0, 0, 0); } catch { } }
SqlDataSource هم چنین یک متد به نام ()Insert دارد که با فراخوانی آن InsertCommand اجرا شده و داده درون پایگاه داده ثبت می شود. این متد را درون رویداد کلیک دکمه موجود روی فرم، فراخوانی می کنیم:
protected void btnInsert_Click(object sender, EventArgs e) { sqlDtSrcEmployees.Insert(); }
حال برنامه را اجرا کرده و داده ای را درون پایگاه داده ثبت می کنیم:
همانطور که مشاهده می کنید پس از فشار دادن دکمه صفحه refresh شده و مشخصات کارمند جدید از جمله تاریخ استخدام (به صورت هجری شمسی) درون GridView نمایان می شود اما اگر نگاهی به پایگاه داده بیندازیم، می بینیم که تاریخ استخدام بدون هیچ مشکلی به شکل صحیح خود یعنی میلادی وارد شده است:
به عنوان نتیجه گیری کلی، هنگام طراحی جداول پایگاه داده، ستون های تاریخ را از نوع datetime تعریف می کنیم و به هنگام بازیابی یا وارد کردن داده درون فیلدهایی از این نوع از ابزارهایی که زبان سی شارپ برای تبدیل کردن تاریخ ها در اختیارمان می گذارد استفاده می کنیم.
زمان پاسخ گویی روز های شنبه الی چهارشنبه ساعت 9 الی 18
فقط به موضوعات مربوط به محصولات آموزشی و فروش پاسخ داده می شود