PDA

View Full Version : گفتگو: کلاسی برای تبدیل تاریخ



ROSTAM2
پنج شنبه 12 آبان 1401, 19:54 عصر
سلام به همه.
من یک کلاس ایجاد کردم به نام PersianDate که تنها با گرفتن تاریخ میلادی تاریخ رو به شمسی تبدیل می کنه.
همچنین می تونه تاریخ شمسی خودش رو مجددا به میلادی برگردونه یعنی اگه تاریخ شمسی حتی بصورت رشته تبدیل به PersianDate بشه می شه از طریق متود ToDateTime به تاریخ میلادی تبدیل کرد و یک کلاس جامع و کامل قراره باشه برای تاریخ شمسی.
پس اگر کلاس من در کدهاش مشکلی داشت حتما تو همین تاپیک تذکر بدید.
154153

Imports System.Globalization
Public Class PersianDate

Private PCalendar As New PersianCalendar
Public Shared Narrowing Operator CType(ByVal initialData As String) As PersianDate
'{0}/{1}/{2} {3}:{4}:{5}
Dim Spl As String() = initialData.Split(Space(1))
Dim y, m, d, h, min, s As Integer
Try
Select Case Spl.Length
Case 1, 2
Dim DateSpl As String() = Spl(0).Split("/")
y = Val(DateSpl(0))
m = Val(DateSpl(1))
d = Val(DateSpl(2))
If Spl.Length = 1 Then Exit Select
Dim TimeSpl As String() = Spl(1).Split(":")
h = Val(TimeSpl(0))
min = Val(TimeSpl(1))
s = Val(TimeSpl(2))
End Select
Return New PersianDate(New Date(y, m, d, h, min, s, PCalendar))
Catch ex As Exception
Throw New FormatException(ex.Message, ex)
End Try
End Operator

Public Shared Widening Operator CType(ByVal initialData As PersianDate) As String
With initialData
Return String.Format("{0:0000}/{1:00}/{2:00} {3:00}:{4:00}:{5:00}", .Year, .Month, .DayOfMonth, .Hour, .Minute, .Second, .MilliSecond)
End With
End Operator

#Region "Properties"
Public ReadOnly Property Eras As Integer()
Get
Return PCalendar.Eras
End Get
End Property
Public ReadOnly Property Year() As Integer
Get
Return PCalendar.GetYear([Date])
End Get
End Property

Public ReadOnly Property Month() As Integer
Get
Return PCalendar.GetMonth([Date])
End Get
End Property

Public ReadOnly Property DayOfMonth() As Integer
Get
Return PCalendar.GetDayOfMonth([Date])
End Get
End Property

Public ReadOnly Property Hour() As Integer
Get
Return PCalendar.GetHour([Date])
End Get
End Property

Public ReadOnly Property Minute() As Integer
Get
Return PCalendar.GetMinute([Date])
End Get
End Property

Public ReadOnly Property Second() As Integer
Get
Return PCalendar.GetSecond([Date])
End Get
End Property

Public ReadOnly Property MilliSecond() As Integer
Get
Return PCalendar.GetMilliseconds([Date])
End Get
End Property

Public ReadOnly Property DayOfWeek() As DayOfWeek
Get
Return PCalendar.GetDayOfWeek([Date])
End Get
End Property

Public ReadOnly Property DayOfYear() As Integer
Get
Return PCalendar.GetDayOfYear([Date])
End Get
End Property

Public ReadOnly Property DaysInMonth() As Integer
Get
Return PCalendar.GetDaysInMonth([Date].Year, [Date].Month)
End Get
End Property

Public ReadOnly Property DaysInYear() As Integer
Get
Return PCalendar.GetDaysInYear([Date].Year)
End Get
End Property

Public ReadOnly Property LeapMonth() As Integer
Get
Return PCalendar.GetLeapMonth([Date].Year)
End Get
End Property

Public ReadOnly Property MonthsInYear() As Integer
Get
Return PCalendar.GetMonthsInYear([Date].Year)
End Get
End Property

Public ReadOnly Property WeekOfYear() As Integer
Get
Return PCalendar.GetWeekOfYear([Date], CalendarWeekRule.FirstDay, DayOfWeek.Saturday)
End Get
End Property

Public ReadOnly Property FourDigitYear() As Integer
Get
Return PCalendar.ToFourDigitYear([Date].Year)
End Get
End Property

Public ReadOnly Property IsLeapYear() As Integer
Get
Return PCalendar.IsLeapYear([Date].Year)
End Get
End Property
Public ReadOnly Property IsLeapYear(Year%) As Integer
Get
Return PCalendar.IsLeapYear(Year)
End Get
End Property
Public ReadOnly Property IsLeapDay(Year%, Month%, Day%) As Integer
Get
Return PCalendar.IsLeapDay(Year%, Month%, Day%)
End Get
End Property
Public ReadOnly Property IsLeapMonth(Year%, Month%, Day%) As Integer
Get
Return PCalendar.IsLeapMonth(Year%, Month%, Day%)
End Get
End Property
#End Region

Private [Date] As Date
''' <summary>
''' Make Persian Date form Current Gregorian Date As Now.
''' </summary>
Sub New()
MyBase.New()
[Date] = DateAndTime.Now
End Sub
''' <summary>
''' New Persian Date from Gregorian Date.
''' </summary>
''' <param name="GDate">Gregorian Date for convert to Persian Date.</param>
Sub New(GDate As Date)
MyBase.New()
[Date] = GDate
End Sub
Public Overrides Function ToString() As String
Return CType(Me, String)
End Function
Public Function AddHours(Value As Integer) As PersianDate
Try
Return New PersianDate(Me.ToDateTime.AddHours(Value))
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function AddMinutes(Value As Integer) As PersianDate
Try
Return New PersianDate(Me.ToDateTime.AddMinutes(Value))
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function AddSeconds(Value As Integer) As PersianDate
Try
Return New PersianDate(Me.ToDateTime.AddSeconds(Value))
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function AddMilliseconds(Value As Integer) As PersianDate
Try
Return New PersianDate(Me.ToDateTime.AddMilliseconds(Value))
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function AddTicks(Value As Integer) As PersianDate
Try
Return New PersianDate(Me.ToDateTime.AddTicks(Value))
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function AddDays(Days As Integer) As PersianDate
Try
Return New PersianDate(Me.ToDateTime.AddDays(Days))
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
Public Function AddMonths(months As Integer) As PersianDate
Try
Return New PersianDate(Me.ToDateTime.AddMonths(months))
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
''' <summary>
''' Add Years to Current Persian Date.
''' </summary>
''' <param name="years"></param>
''' <returns></returns>
Public Function AddYears(years As Integer) As PersianDate
Try
Return New PersianDate(Me.ToDateTime.AddYears(years))
Catch ex As Exception
Throw New Exception(ex.Message, ex)
End Try
End Function
''' <summary>
''' Convert Current PersionDate to Gregorian Date.
''' </summary>
''' <returns></returns>
Public Function ToDateTime() As Date
Return New Date(Year, Month, DayOfMonth, Hour, Minute, Second, MilliSecond, PCalendar)
End Function
End Class

ROSTAM2
پنج شنبه 12 آبان 1401, 20:41 عصر
سلام مجدد.
ازونجایی که Date یک Structure هست من هم کلاس PersianDate رو به Structure تبدیل کردم و حالا کارائیش بهتر شده:

برای کلاس حتما باید متغیر از نوع جدید ایجاد می شد:

Dim Shamsidate As New PersianDate


ولی در Structure کافیه مثل Date متغیرش ایجاد بشه و از اون استفاده بشه:

Dim Shamsidate As PersianDate
Shamsidate = "1401/07/12"

ROSTAM2
جمعه 13 آبان 1401, 08:10 صبح
سلام.
توی PersianDate در عملگر CType برای تبدیل تاریخ بصورت رشته به تاریخ شمسی دستور اشتباه بود که تصحیح کردم:


Public Shared Narrowing Operator CType(ByVal initialData As String) As PersianDate
'{0}/{1}/{2} {3}:{4}:{5}
Dim Spl As String() = initialData.Split(Space(1))
Dim y, m, d, h, min, s As Integer
Try
Select Case Spl.Length
Case 1, 2
Dim DateSpl As String() = Spl(0).Split("/")
y = Val(DateSpl(0))
m = Val(DateSpl(1))
d = Val(DateSpl(2))
If Spl.Length = 1 Then Exit Select
Dim TimeSpl As String() = Spl(1).Split(":")
h = Val(TimeSpl(0))
min = Val(TimeSpl(1))
s = Val(TimeSpl(2))
End Select
Return New PersianDate(New Date(y, m, d, h, min, s, PCalendar))
Catch ex As Exception
Throw New FormatException(ex.Message, ex)
End Try
End Operator

ROSTAM2
جمعه 13 آبان 1401, 08:18 صبح
در PersianDate می شه تاریخ رو به اینصورت استفاده کرد:


Dim Shamsidate As PersianDate
Shamsidate = "1400/08/13 10:20:22"


و یا:

Dim Shamsidate As PersianDate
Shamsidate = Now



برای تبدیل به تاریخ میلادی هم اومدم و یک عملگر CType برای تبدیل شمسی به میلادی و بالعکس ایجاد کردم که براحتی به میلادی و بالعکس تبدیل می شه:

Dim Shamsidate As PersianDate
Shamsidate = "1400/08/13 10:20:22"
Dim D As Date = ShamsiDate


برای تبدیل یک تاریخ معین میلادی به شمسی:

Dim Shamsidate As PersianDate
Shamsidate = #11/05/2022 14:05:18#
Console.WriteLine("{0}PersianDate: {1}", vbCrLf, Shamsidate)

یا به اینصورت:

Dim Shamsidate As New PersianDate(#11/05/2022 14:05:18#)

یا:

Shamsidate = CDate("11/05/2022 14:05:18")

ROSTAM2
جمعه 13 آبان 1401, 16:21 عصر
سلام مجدد؛

این هم یک کلاس برای نام روز هفته به فارسی که به PersianDate اضافه شده و کافیه از خصوصیت DayOfWeek استفاده بشه:

Public Class PersianDayOfWeek
Public Shared Widening Operator CType(ByVal initialData As PersianDayOfWeek) As String
Return initialData.Name
End Operator
Private OwnerValue As PersianDate
Public ReadOnly Property Owner() As PersianDate
Get
Return OwnerValue
End Get
End Property
Sub New(Owner As PersianDate)
Me.OwnerValue = Owner
End Sub
Private ReadOnly Property Name() As String
Get
Return Choose(Owner.Date.DayOfWeek + 1, "یکشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه")
End Get
End Property
Public Overrides Function ToString() As String
Return Me.Name
End Function
End Class


بکارگیری:

MsgBox(PersianDate.Now.DayOfWeek)


سورس کد بهمراه آخرین تغییرات:

پرستو پارسایی
یک شنبه 15 آبان 1401, 11:17 صبح
ممنون از ارائه سورس مورد نظر ، برای من بسیار کاربردی بود سپاس