├── MD.PersianDateTime.Standard
├── Icon
│ └── PersianDateTime.png
├── MD.PersianDateTime.Standard.csproj.DotSettings
├── HijriDateTime.cs
├── PersianDayOfWeek.cs
├── MD.PersianDateTime.Standard.csproj
├── Helpers
│ └── ExtensionsHelper.cs
└── PersianDateTime.cs
├── MD.PersianDateTime
├── MD.PersianDateTime.csproj.DotSettings
├── HijriDateTime.cs
├── PersianDayOfWeek.cs
├── Properties
│ └── AssemblyInfo.cs
├── Helpers
│ └── ExtensionsHelper.cs
├── MD.PersianDateTime.csproj
└── PersianDateTime.cs
├── MD.PersianDateTime.Standard.Test
├── MD.PersianDateTime.Standard.Test.csproj
├── CultureScope.cs
├── UseCultureAttribute.cs
└── UnitTest1.cs
├── Properties
└── AssemblyInfo.cs
├── .gitattributes
├── .gitignore
├── MD.PersianDateTime.sln
└── README.md
/MD.PersianDateTime.Standard/Icon/PersianDateTime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mds92/MD.PersianDateTime/HEAD/MD.PersianDateTime.Standard/Icon/PersianDateTime.png
--------------------------------------------------------------------------------
/MD.PersianDateTime/MD.PersianDateTime.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/MD.PersianDateTime.Standard/MD.PersianDateTime.Standard.csproj.DotSettings:
--------------------------------------------------------------------------------
1 |
2 | True
--------------------------------------------------------------------------------
/MD.PersianDateTime.Standard/HijriDateTime.cs:
--------------------------------------------------------------------------------
1 | namespace MD.PersianDateTime.Standard;
2 |
3 | ///
4 | /// تاریخ هجری قمری
5 | ///
6 | public struct HijriDateTime
7 | {
8 | ///
9 | /// سال قمری
10 | ///
11 | public int Year { get; set; }
12 |
13 | ///
14 | /// ماه قمری
15 | ///
16 | public int Month { get; set; }
17 |
18 | ///
19 | /// نام ماه قمری
20 | ///
21 | public string MonthName { get; set; }
22 |
23 | ///
24 | /// روز ماه قمری
25 | ///
26 | public int Day { get; set; }
27 | }
--------------------------------------------------------------------------------
/MD.PersianDateTime/HijriDateTime.cs:
--------------------------------------------------------------------------------
1 | namespace MD.PersianDateTime
2 | {
3 | ///
4 | /// تاریخ هجری قمری
5 | ///
6 | public struct HijriDateTime
7 | {
8 | ///
9 | /// سال قمری
10 | ///
11 | public int Year { get; set; }
12 |
13 | ///
14 | /// ماه قمری
15 | ///
16 | public int Month { get; set; }
17 |
18 | ///
19 | /// نام ماه قمری
20 | ///
21 | public string MonthName { get; set; }
22 |
23 | ///
24 | /// روز ماه قمری
25 | ///
26 | public int Day { get; set; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/MD.PersianDateTime.Standard.Test/MD.PersianDateTime.Standard.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | preview
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/MD.PersianDateTime.Standard/PersianDayOfWeek.cs:
--------------------------------------------------------------------------------
1 | namespace MD.PersianDateTime.Standard;
2 |
3 | ///
4 | /// روزهای شمسی هفته
5 | ///
6 | public enum PersianDayOfWeek
7 | {
8 | ///
9 | /// شنبه
10 | ///
11 | Saturday = 0,
12 |
13 | ///
14 | /// یکشنبه
15 | ///
16 | Sunday = 1,
17 |
18 | ///
19 | /// دو شنبه
20 | ///
21 | Monday = 2,
22 |
23 | ///
24 | /// سه شنبه
25 | ///
26 | Tuesday = 3,
27 |
28 | ///
29 | /// چهار شنبه
30 | ///
31 | Wednesday = 4,
32 |
33 | ///
34 | /// پنج شنبه
35 | ///
36 | Thursday = 5,
37 |
38 | ///
39 | /// جمعه
40 | ///
41 | Friday = 6
42 | }
--------------------------------------------------------------------------------
/MD.PersianDateTime.Standard.Test/CultureScope.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 |
4 | namespace MD.PersianDateTime.Standard.Test;
5 |
6 | public sealed class CultureScope : IDisposable
7 | {
8 | private readonly CultureInfo _originalCulture;
9 | private readonly CultureInfo _originalUiCulture;
10 |
11 | public CultureScope(string cultureName)
12 | {
13 | _originalCulture = CultureInfo.CurrentCulture;
14 | _originalUiCulture = CultureInfo.CurrentUICulture;
15 |
16 | var newCulture = new CultureInfo(cultureName);
17 | CultureInfo.CurrentCulture = newCulture;
18 | CultureInfo.CurrentUICulture = newCulture;
19 | }
20 |
21 | public void Dispose()
22 | {
23 | CultureInfo.CurrentCulture = _originalCulture;
24 | CultureInfo.CurrentUICulture = _originalUiCulture;
25 | }
26 | }
--------------------------------------------------------------------------------
/MD.PersianDateTime/PersianDayOfWeek.cs:
--------------------------------------------------------------------------------
1 | namespace MD.PersianDateTime
2 | {
3 | ///
4 | /// روزهای شمسی هفته
5 | ///
6 | public enum PersianDayOfWeek
7 | {
8 | ///
9 | /// شنبه
10 | ///
11 | Saturday = 0,
12 |
13 | ///
14 | /// یکشنبه
15 | ///
16 | Sunday = 1,
17 |
18 | ///
19 | /// دو شنبه
20 | ///
21 | Monday = 2,
22 |
23 | ///
24 | /// سه شنبه
25 | ///
26 | Tuesday = 3,
27 |
28 | ///
29 | /// چهار شنبه
30 | ///
31 | Wednesday = 4,
32 |
33 | ///
34 | /// پنج شنبه
35 | ///
36 | Thursday = 5,
37 |
38 | ///
39 | /// جمعه
40 | ///
41 | Friday = 6
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/MD.PersianDateTime.Standard.Test/UseCultureAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Reflection;
4 | using Xunit.Sdk;
5 |
6 | namespace MD.PersianDateTime.Standard.Test;
7 |
8 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
9 | public class UseCultureAttribute(string cultureName) : BeforeAfterTestAttribute
10 | {
11 | private readonly CultureInfo _testCulture = new(cultureName);
12 | private CultureInfo _originalCulture;
13 | private CultureInfo _originalUiCulture;
14 |
15 | public override void Before(MethodInfo methodUnderTest)
16 | {
17 | // ذخیره Culture فعلی
18 | _originalCulture = CultureInfo.CurrentCulture;
19 | _originalUiCulture = CultureInfo.CurrentUICulture;
20 |
21 | // تنظیم Culture جدید برای Thread جاری
22 | CultureInfo.CurrentCulture = _testCulture;
23 | CultureInfo.CurrentUICulture = _testCulture;
24 | }
25 |
26 | public override void After(MethodInfo methodUnderTest)
27 | {
28 | // بازگردانی به Culture قبلی
29 | if (_originalCulture != null)
30 | CultureInfo.CurrentCulture = _originalCulture;
31 | if (_originalUiCulture != null)
32 | CultureInfo.CurrentUICulture = _originalUiCulture;
33 | }
34 | }
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("MD.PersianDateTime")]
8 | [assembly: AssemblyDescription("Created By Mohammad Dayyan, 1393-1394")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("Written By Mohammad Dayyan, mds_soft@yahoo.com")]
11 | [assembly: AssemblyProduct("MD.PersianDateTime")]
12 | [assembly: AssemblyCopyright("Copyright © Mohammad Dayyan (mds_soft@yahoo.com) 2014-2015")]
13 | [assembly: AssemblyTrademark("Mohammad Dayyan")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("85ad36ff-1baf-4f41-aaa9-afc5989a7e10")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("3.3.0.0")]
35 | [assembly: AssemblyFileVersion("3.3.0.0")]
36 |
--------------------------------------------------------------------------------
/MD.PersianDateTime/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("MD.PersianDateTime")]
8 | [assembly: AssemblyDescription("Created By Mohammad Dayyan, 1393-1394")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("Written By Mohammad Dayyan, mds_soft@yahoo.com")]
11 | [assembly: AssemblyProduct("MD.PersianDateTime")]
12 | [assembly: AssemblyCopyright("Copyright © Mohammad Dayyan (mds_soft@yahoo.com) 2014-2015")]
13 | [assembly: AssemblyTrademark("Mohammad Dayyan")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("85ad36ff-1baf-4f41-aaa9-afc5989a7e10")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("4.6.0.0")]
35 | [assembly: AssemblyFileVersion("4.6.0.0")]
36 |
--------------------------------------------------------------------------------
/MD.PersianDateTime.Standard/MD.PersianDateTime.Standard.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | A C# library to use PersianCalendar as easy as DateTime
6 | Mohammad Dayyan - @mds1401
7 | https://licenses.nuget.org/MIT
8 | https://github.com/Mds92/MD.PersianDateTime
9 | https://github.com/Mds92/MD.PersianDateTime
10 | c# .net-standard persiandatetime datetime calendar
11 | true
12 | 2.6.0
13 | 2.6.0
14 | 2.6.0
15 | PersianDateTime.png
16 |
17 | Mohammad Dayyan
18 | Mohammad Dayyan
19 | Culture Improvements
20 | MD.PersianDateTime.Standard
21 | preview
22 | Apache-2.0
23 |
24 |
25 |
26 | bin\Release\netstandard2.0\MD.PersianDateTime.Standard.xml
27 |
28 |
29 |
30 |
31 | Code
32 |
33 |
34 |
35 |
36 |
37 | True
38 | \
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/MD.PersianDateTime.Standard/Helpers/ExtensionsHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace MD.PersianDateTime.Standard.Helpers;
4 |
5 | internal static class ExtensionsHelper
6 | {
7 | ///
8 | /// Convert all persian and arabic digit to english in any string
9 | ///
10 | ///
11 | /// input string that maybe contain persian or arabic digit
12 | /// a string with english digit
13 | internal static string ConvertDigitsToLatin(string inputString)
14 | {
15 | var sb = new StringBuilder();
16 |
17 | foreach (var c in inputString)
18 | {
19 | switch (c)
20 | {
21 | case '\u06f0': //Persian digit
22 | case '\u0660': //Arabic digit
23 | sb.Append('0');
24 | break;
25 | case '\u06f1':
26 | case '\u0661':
27 | sb.Append('1');
28 | break;
29 | case '\u06f2':
30 | case '\u0662':
31 | sb.Append('2');
32 | break;
33 | case '\u06f3':
34 | case '\u0663':
35 | sb.Append('3');
36 | break;
37 | case '\u06f4':
38 | case '\u0664':
39 | sb.Append('4');
40 | break;
41 | case '\u06f5':
42 | case '\u0665':
43 | sb.Append('5');
44 | break;
45 | case '\u06f6':
46 | case '\u0666':
47 | sb.Append('6');
48 | break;
49 | case '\u06f7':
50 | case '\u0667':
51 | sb.Append('7');
52 | break;
53 | case '\u06f8':
54 | case '\u0668':
55 | sb.Append('8');
56 | break;
57 | case '\u06f9':
58 | case '\u0669':
59 | sb.Append('9');
60 | break;
61 |
62 | default:
63 | sb.Append(c);
64 | break;
65 | }
66 | }
67 |
68 | return sb.ToString();
69 | }
70 | }
--------------------------------------------------------------------------------
/MD.PersianDateTime/Helpers/ExtensionsHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace MD.PersianDateTime
4 | {
5 | internal static class ExtensionsHelper
6 | {
7 | ///
8 | /// Convert all persian and arabic digit to english in any string
9 | ///
10 | ///
11 | /// input string that maybe contain persian or arabic digit
12 | /// a string with english digit
13 | internal static string ConvertDigitsToLatin(string inputString)
14 | {
15 | var sb = new StringBuilder();
16 |
17 | foreach (var c in inputString)
18 | {
19 | switch (c)
20 | {
21 | case '\u06f0': //Persian digit
22 | case '\u0660': //Arabic digit
23 | sb.Append('0');
24 | break;
25 | case '\u06f1':
26 | case '\u0661':
27 | sb.Append('1');
28 | break;
29 | case '\u06f2':
30 | case '\u0662':
31 | sb.Append('2');
32 | break;
33 | case '\u06f3':
34 | case '\u0663':
35 | sb.Append('3');
36 | break;
37 | case '\u06f4':
38 | case '\u0664':
39 | sb.Append('4');
40 | break;
41 | case '\u06f5':
42 | case '\u0665':
43 | sb.Append('5');
44 | break;
45 | case '\u06f6':
46 | case '\u0666':
47 | sb.Append('6');
48 | break;
49 | case '\u06f7':
50 | case '\u0667':
51 | sb.Append('7');
52 | break;
53 | case '\u06f8':
54 | case '\u0668':
55 | sb.Append('8');
56 | break;
57 | case '\u06f9':
58 | case '\u0669':
59 | sb.Append('9');
60 | break;
61 |
62 | default:
63 | sb.Append(c);
64 | break;
65 | }
66 | }
67 |
68 | return sb.ToString();
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/MD.PersianDateTime/MD.PersianDateTime.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Release
6 | AnyCPU
7 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}
8 | Library
9 | Properties
10 | MD.PersianDateTime
11 | MD.PersianDateTime
12 | v2.0
13 | 512
14 | SAK
15 | SAK
16 | SAK
17 | SAK
18 |
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\Debug\
25 | DEBUG;TRACE
26 | prompt
27 | 2
28 | false
29 |
30 |
31 | pdbonly
32 | true
33 | bin\Release\
34 | TRACE
35 | prompt
36 | 4
37 | bin\Release\MD.PersianDateTime.XML
38 | false
39 |
40 |
41 | false
42 |
43 |
44 |
45 |
46 | C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Core.dll
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | Code
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
70 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 | *.git/
9 | *.nuget/
10 | *.vs/
11 |
12 | # Build results
13 | [Dd]ebug/
14 | [Dd]ebugPublic/
15 | [Rr]elease/
16 | x64/
17 | build/
18 | bld/
19 | [Bb]in/
20 | [Oo]bj/
21 |
22 | # Roslyn cache directories
23 | *.ide/
24 |
25 | # MSTest test Results
26 | [Tt]est[Rr]esult*/
27 | [Bb]uild[Ll]og.*
28 |
29 | #NUNIT
30 | *.VisualState.xml
31 | TestResult.xml
32 |
33 | # Build Results of an ATL Project
34 | [Dd]ebugPS/
35 | [Rr]eleasePS/
36 | dlldata.c
37 |
38 | *_i.c
39 | *_p.c
40 | *_i.h
41 | *.ilk
42 | *.meta
43 | *.obj
44 | *.pch
45 | *.pdb
46 | *.pgc
47 | *.pgd
48 | *.rsp
49 | *.sbr
50 | *.tlb
51 | *.tli
52 | *.tlh
53 | *.tmp
54 | *.tmp_proj
55 | *.log
56 | *.vspscc
57 | *.vssscc
58 | .builds
59 | *.pidb
60 | *.svclog
61 | *.scc
62 |
63 | # Chutzpah Test files
64 | _Chutzpah*
65 |
66 | # Visual C++ cache files
67 | ipch/
68 | *.aps
69 | *.ncb
70 | *.opensdf
71 | *.sdf
72 | *.cachefile
73 |
74 | # Visual Studio profiler
75 | *.psess
76 | *.vsp
77 | *.vspx
78 |
79 | # TFS 2012 Local Workspace
80 | $tf/
81 |
82 | # Guidance Automation Toolkit
83 | *.gpState
84 |
85 | # ReSharper is a .NET coding add-in
86 | _ReSharper*/
87 | *.[Rr]e[Ss]harper
88 | *.DotSettings.user
89 |
90 | # JustCode is a .NET coding addin-in
91 | .JustCode
92 |
93 | # TeamCity is a build add-in
94 | _TeamCity*
95 |
96 | # DotCover is a Code Coverage Tool
97 | *.dotCover
98 |
99 | # NCrunch
100 | _NCrunch_*
101 | .*crunch*.local.xml
102 |
103 | # MightyMoose
104 | *.mm.*
105 | AutoTest.Net/
106 |
107 | # Web workbench (sass)
108 | .sass-cache/
109 |
110 | # Installshield output folder
111 | [Ee]xpress/
112 |
113 | # DocProject is a documentation generator add-in
114 | DocProject/buildhelp/
115 | DocProject/Help/*.HxT
116 | DocProject/Help/*.HxC
117 | DocProject/Help/*.hhc
118 | DocProject/Help/*.hhk
119 | DocProject/Help/*.hhp
120 | DocProject/Help/Html2
121 | DocProject/Help/html
122 |
123 | # Click-Once directory
124 | publish/
125 |
126 | # Publish Web Output
127 | *.[Pp]ublish.xml
128 | *.azurePubxml
129 | ## TODO: Comment the next line if you want to checkin your
130 | ## web deploy settings but do note that will include unencrypted
131 | ## passwords
132 | #*.pubxml
133 |
134 | # NuGet Packages Directory
135 | packages/*
136 | ## TODO: If the tool you use requires repositories.config
137 | ## uncomment the next line
138 | #!packages/repositories.config
139 |
140 | # Enable "build/" folder in the NuGet Packages folder since
141 | # NuGet packages use it for MSBuild targets.
142 | # This line needs to be after the ignore of the build folder
143 | # (and the packages folder if the line above has been uncommented)
144 | !packages/build/
145 |
146 | # Windows Azure Build Output
147 | csx/
148 | *.build.csdef
149 |
150 | # Windows Store app package directory
151 | AppPackages/
152 |
153 | # Others
154 | sql/
155 | *.Cache
156 | ClientBin/
157 | [Ss]tyle[Cc]op.*
158 | ~$*
159 | *~
160 | *.dbmdl
161 | *.dbproj.schemaview
162 | *.pfx
163 | *.publishsettings
164 | node_modules/
165 |
166 | # RIA/Silverlight projects
167 | Generated_Code/
168 |
169 | # Backup & report files from converting an old project file
170 | # to a newer Visual Studio version. Backup files are not needed,
171 | # because we have git ;-)
172 | _UpgradeReport_Files/
173 | Backup*/
174 | UpgradeLog*.XML
175 | UpgradeLog*.htm
176 |
177 | # SQL Server files
178 | *.mdf
179 | *.ldf
180 |
181 | # Business Intelligence projects
182 | *.rdl.data
183 | *.bim.layout
184 | *.bim_*.settings
185 |
186 | # Microsoft Fakes
187 | FakesAssemblies/
188 |
189 | # LightSwitch generated files
190 | GeneratedArtifacts/
191 | _Pvt_Extensions/
192 | ModelManifest.xml
--------------------------------------------------------------------------------
/MD.PersianDateTime.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30330.147
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{A53E45BD-6B6E-4603-8EC4-723CBABA9B60}"
7 | ProjectSection(SolutionItems) = preProject
8 | .nuget\NuGet.Config = .nuget\NuGet.Config
9 | .nuget\NuGet.exe = .nuget\NuGet.exe
10 | .nuget\NuGet.targets = .nuget\NuGet.targets
11 | EndProjectSection
12 | EndProject
13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MD.PersianDateTime", "MD.PersianDateTime\MD.PersianDateTime.csproj", "{21DB3B69-D93B-4E7F-9F52-672546F0F15C}"
14 | EndProject
15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MD.PersianDateTime.Standard", "MD.PersianDateTime.Standard\MD.PersianDateTime.Standard.csproj", "{A1061D11-41DF-4AD1-896B-9AEC48DF984A}"
16 | EndProject
17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MD.PersianDateTime.Standard.Test", "MD.PersianDateTime.Standard.Test\MD.PersianDateTime.Standard.Test.csproj", "{7E3FBFB6-1E76-4252-8383-88326714D358}"
18 | EndProject
19 | Global
20 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
21 | Debug|Any CPU = Debug|Any CPU
22 | Debug|x64 = Debug|x64
23 | Debug|x86 = Debug|x86
24 | Release|Any CPU = Release|Any CPU
25 | Release|x64 = Release|x64
26 | Release|x86 = Release|x86
27 | EndGlobalSection
28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
29 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Debug|Any CPU.Build.0 = Debug|Any CPU
31 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Debug|x64.ActiveCfg = Debug|Any CPU
32 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Debug|x64.Build.0 = Debug|Any CPU
33 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Debug|x86.ActiveCfg = Debug|Any CPU
34 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Debug|x86.Build.0 = Debug|Any CPU
35 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Release|x64.ActiveCfg = Release|Any CPU
38 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Release|x64.Build.0 = Release|Any CPU
39 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Release|x86.ActiveCfg = Release|Any CPU
40 | {21DB3B69-D93B-4E7F-9F52-672546F0F15C}.Release|x86.Build.0 = Release|Any CPU
41 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
42 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Debug|Any CPU.Build.0 = Debug|Any CPU
43 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Debug|x64.ActiveCfg = Debug|Any CPU
44 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Debug|x64.Build.0 = Debug|Any CPU
45 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Debug|x86.ActiveCfg = Debug|Any CPU
46 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Debug|x86.Build.0 = Debug|Any CPU
47 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Release|Any CPU.ActiveCfg = Release|Any CPU
48 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Release|Any CPU.Build.0 = Release|Any CPU
49 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Release|x64.ActiveCfg = Release|Any CPU
50 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Release|x64.Build.0 = Release|Any CPU
51 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Release|x86.ActiveCfg = Release|Any CPU
52 | {A1061D11-41DF-4AD1-896B-9AEC48DF984A}.Release|x86.Build.0 = Release|Any CPU
53 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
54 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Debug|Any CPU.Build.0 = Debug|Any CPU
55 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Debug|x64.ActiveCfg = Debug|Any CPU
56 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Debug|x64.Build.0 = Debug|Any CPU
57 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Debug|x86.ActiveCfg = Debug|Any CPU
58 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Debug|x86.Build.0 = Debug|Any CPU
59 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Release|Any CPU.ActiveCfg = Release|Any CPU
60 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Release|Any CPU.Build.0 = Release|Any CPU
61 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Release|x64.ActiveCfg = Release|Any CPU
62 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Release|x64.Build.0 = Release|Any CPU
63 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Release|x86.ActiveCfg = Release|Any CPU
64 | {7E3FBFB6-1E76-4252-8383-88326714D358}.Release|x86.Build.0 = Release|Any CPU
65 | EndGlobalSection
66 | GlobalSection(SolutionProperties) = preSolution
67 | HideSolutionNode = FALSE
68 | EndGlobalSection
69 | GlobalSection(ExtensibilityGlobals) = postSolution
70 | SolutionGuid = {E451A89F-A93C-4FC4-8E0D-3A5B54983DBF}
71 | EndGlobalSection
72 | EndGlobal
73 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MD.PersianDateTime
2 | A C# library to use PersianCalendar as easy as DateTime
3 | تقویم شمسی و هجری قمری در C#
4 |
5 | ### Installing:
6 |
7 | .Net Framework 2+
8 | ```
9 | Install-Package MD.PersianDateTime
10 | ```
11 |
12 | .Net Standard 2+ (.Net Core)
13 | ```
14 | Install-Package MD.PersianDateTime.Standard
15 | ```
16 |
17 |
18 | ### Coding:
19 |
20 | Creating new object:
21 | 1. New with DateTime object
22 | ```C#
23 | var persianDateTime = new PersianDateTime(DateTime.Now);
24 | ```
25 |
26 | 2. New with persian date
27 | ```C#
28 | var persianDateTime = new PersianDateTime(1394, 5, 9);
29 | var persianDateTime = new PersianDateTime(1394, 5, 9, 10, 5, 3);
30 | var persianDateTime = new PersianDateTime(1394, 5, 9, 10, 5, 3, 103);
31 | ```
32 |
33 | 3. Parse
34 | ```C#
35 | var persianDateTime1 = PersianDateTime.Parse("دوشنبه 05 مرداد 1395 ساعت 04:03");
36 | var persianDateTime2 = PersianDateTime.Parse(13901229); // تاریخ
37 | var persianDateTime2 = PersianDateTime.Parse(13901229231232102); // تاریخ به همراه زمان تا دقت میلی ثانیه
38 | var persianDateTime3 = PersianDateTime.Parse("چهارشنبه، ۱۰ دی ۱۳۹۳ ۱۲:۳۸");
39 | var persianDateTime4 = PersianDateTime.Parse("24 آذر 1393");
40 | var persianDateTime5 = PersianDateTime.Parse("د 24 آذر 1393 4:2:5:5 ب.ظ");
41 | var persianDateTime6 = PersianDateTime.Parse("1393/02/01");
42 | var persianDateTime7 = PersianDateTime.Parse("1393/02/01 02:03");
43 | var persianDateTime8 = PersianDateTime.Parse("1393-02-01 02:03:10:30");
44 | var persianDateTime9 = PersianDateTime.Parse("93-1-1 3:15 ب.ظ");
45 | var persianDateTime10 = PersianDateTime.Parse("جمعه 93/2/1 ساعت 3:2 ب.ظ");
46 | ```
47 |
48 | 4. Today, Now
49 | ```C#
50 | var persianDateTime1 = PersianDateTime.Now;
51 | var persianDateTime2 = PersianDateTime.Today; // without time
52 | ```
53 |
54 | ------------------------------------------
55 | ### Enable persian numbers
56 | ```C#
57 | var persianDateTime = PersianDateTime.Parse("چهارشنبه 5 آذر 58");
58 | persianDateTime.PersianNumber = true;
59 | Console.Write(PersianDateTime.Now.ToString("yyyy/MM/dd"));
60 | // ۱۳۹۹/۱۰/۰۳
61 | ```
62 | ------------------------------------------
63 | ### Convert to DateTime
64 | PersianDateTime object can convert automatically to datetime without any redundant code
65 | ```C#
66 | DateTime dateTime = PersianDateTime.Now
67 | ```
68 | Also you can use `ToDateTime` method
69 | ```C#
70 | DateTime datetime = persianDateTime.ToDateTime();
71 | ```
72 | ------------------------------------------
73 | ### Get HijriDate
74 | ```C#
75 | var persianDateTimeNow = PersianDateTime.Now;
76 | var hijriDateTime = persianDateTimeNow.ToHijri(-1);
77 | Console.WriteLine($"{hijriDateTime.Year}-{hijriDateTime.Month}-{hijriDateTime.Day}");
78 | ```
79 |
80 | ------------------------------------------
81 | ### Formats
82 | you can use the following formats in `ToString` method.
83 | ```C#
84 | yyyy: سال چهار رقمی
85 | yy: سال دو رقمی
86 | MMMM: نام فارسی ماه
87 | MM: عدد دو رقمی ماه
88 | M: عدد یک رقمی ماه
89 | dddd: نام فارسی روز هفته
90 | dd: عدد دو رقمی روز ماه
91 | d: عدد یک رقمی روز ماه
92 | HH: ساعت دو رقمی با فرمت 00 تا 24
93 | H: ساعت یک رقمی با فرمت 0 تا 24
94 | hh: ساعت دو رقمی با فرمت 00 تا 12
95 | h: ساعت یک رقمی با فرمت 0 تا 12
96 | mm: عدد دو رقمی دقیقه
97 | m: عدد یک رقمی دقیقه
98 | ss: ثانیه دو رقمی
99 | s: ثانیه یک رقمی
100 | fff: میلی ثانیه 3 رقمی
101 | ff: میلی ثانیه 2 رقمی
102 | f: میلی ثانیه یک رقمی
103 | tt: ب.ظ یا ق.ظ
104 | t: حرف اول از ب.ظ یا ق.ظ
105 | ```
106 | ------------------------------------------
107 | ### Some useful methods
108 | ```
109 | IsSqlDateTime \\ Check datetime and return a boolean if it is valid for SQL
110 | IsChristianDate \\ Check if the input string is a christian datetime
111 | ElapsedTime \\ Get past time until now e.g: ۱ روز قبل
112 | Add*** \\ add day, month, year, ... to persian datetime
113 | Subtract*** \\ Subtract a datetime from current object
114 | GetDifferenceQuarter \\ Date Difference base on seasons
115 | ```
116 | ------------------------------------------
117 | ### Comparing
118 | You can compare two PersianDateTime object together with C# operators
119 | ```C#
120 | var persianDateTime1 = new PersianDateTime(1396, 03, 28);
121 | var persianDateTime2 = new PersianDateTime(1396, 03, 29);
122 | var persianDateTime3 = new PersianDateTime(1396, 03, 28);
123 |
124 | persianDateTime1 > persianDateTime2; // false
125 | persianDateTime1 < persianDateTime2; // true
126 | persianDateTime1 == persianDateTime3; // true
127 | persianDateTime1 != persianDateTime3; // false
128 | ```
129 |
130 | ------------------------------------------
131 | ### Add and Subtract with operator
132 | You can use + - operators
133 | ```C#
134 | var persianDateTime1 = new PersianDateTime(1396, 03, 28);
135 |
136 | persianDateTime1 = persianDateTime1 + new TimeSpan(0, 0, 12); // add 12 minutes
137 | persianDateTime1 = persianDateTime1 - new TimeSpan(0, 0, 1); // subtract 1 minutes
138 | persianDateTime1 = persianDateTime1.AddDays(1); // add one day
139 | persianDateTime1 = persianDateTime1.AddMonth(-1); // subtract 1 month
140 | .
141 | .
142 | .
143 |
144 | ```
145 |
--------------------------------------------------------------------------------
/MD.PersianDateTime.Standard.Test/UnitTest1.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using Xunit;
4 |
5 | namespace MD.PersianDateTime.Standard.Test;
6 |
7 | public class UnitTest1
8 | {
9 | [Fact]
10 | public void GetPersianDateOfLastDayOfMonth1()
11 | {
12 | var date = new PersianDateTime(1399, 5, 1);
13 | Assert.Equal(new PersianDateTime(date.Year, date.Month, date.GetMonthDays), date.GetPersianDateOfLastDayOfMonth());
14 | }
15 |
16 | [Fact]
17 | public void GetPersianDateOfLastDayOfMonth2()
18 | {
19 | var date = new PersianDateTime(1399, 10, 1);
20 | Assert.Equal(new PersianDateTime(date.Year, date.Month, date.GetMonthDays), date.GetPersianDateOfLastDayOfMonth());
21 | }
22 |
23 | [Fact]
24 | public void GetPersianDateOfLastDayOfMonth3()
25 | {
26 | var date = new PersianDateTime(1399, 12, 1);
27 | Assert.Equal(new PersianDateTime(date.Year, date.Month, date.GetMonthDays), date.GetPersianDateOfLastDayOfMonth());
28 | }
29 |
30 | [Fact]
31 | public void GetPersianDateOfLastDayOfYear1()
32 | {
33 | var date1 = new PersianDateTime(1400, 1, 1);
34 | var date2 = new PersianDateTime(1400, 12, 29);
35 | Assert.Equal(date1.GetPersianDateOfLastDayOfYear(), date2);
36 | }
37 |
38 | [Fact]
39 | public void GetPersianWeekend()
40 | {
41 | var persianDateFriday1 = new PersianDateTime(1401, 7, 22); // جمعه
42 | var persianDateFriday2 = new PersianDateTime(1401, 7, 29); // جمعه
43 | var persianDateFriday3 = new PersianDateTime(1401, 8, 6); // جمعه
44 | var persianDateFriday4 = new PersianDateTime(1401, 8, 13); // جمعه
45 |
46 | Assert.Equal(persianDateFriday1.AddDays(-1).GetPersianWeekend(), persianDateFriday1);
47 | Assert.Equal(persianDateFriday1.AddDays(-5).GetPersianWeekend(), persianDateFriday1);
48 | Assert.Equal(persianDateFriday2.AddDays(-4).GetPersianWeekend(), persianDateFriday2);
49 | Assert.Equal(persianDateFriday2.AddDays(-6).GetPersianWeekend(), persianDateFriday2);
50 | Assert.Equal(persianDateFriday3.AddDays(-3).GetPersianWeekend(), persianDateFriday3);
51 | Assert.Equal(persianDateFriday4.AddDays(-6).GetPersianWeekend(), persianDateFriday4);
52 | Assert.Equal(persianDateFriday4.GetPersianWeekend(), persianDateFriday4);
53 | }
54 |
55 | [Fact]
56 | public void GetFirstDayOfWeek()
57 | {
58 | var persianDateSaturday1 = new PersianDateTime(1401, 7, 23); // شنبه
59 | var persianDateSaturday2 = new PersianDateTime(1401, 7, 30); // شنبه
60 | var persianDateSaturday3 = new PersianDateTime(1401, 8, 7); // شنبه
61 | var persianDateSaturday4 = new PersianDateTime(1401, 8, 14); // شنبه
62 |
63 | Assert.Equal(persianDateSaturday1.AddDays(1).GetFirstDayOfWeek(), persianDateSaturday1);
64 | Assert.Equal(persianDateSaturday1.AddDays(5).GetFirstDayOfWeek(), persianDateSaturday1);
65 | Assert.Equal(persianDateSaturday2.AddDays(4).GetFirstDayOfWeek(), persianDateSaturday2);
66 | Assert.Equal(persianDateSaturday2.AddDays(6).GetFirstDayOfWeek(), persianDateSaturday2);
67 | Assert.Equal(persianDateSaturday3.AddDays(3).GetFirstDayOfWeek(), persianDateSaturday3);
68 | Assert.Equal(persianDateSaturday4.AddDays(6).GetFirstDayOfWeek(), persianDateSaturday4);
69 | Assert.Equal(persianDateSaturday4.GetFirstDayOfWeek(), persianDateSaturday4);
70 | }
71 |
72 | [Fact]
73 | public void ToTimeShort1()
74 | {
75 | var date = new PersianDateTime(1399, 5, 1, 12, 20, 33);
76 | Assert.Equal(1220, date.ToTimeShort());
77 | }
78 |
79 | [Fact]
80 | public void ToTimeShort2()
81 | {
82 | var date = new PersianDateTime(1402, 3, 22, 9, 8, 5);
83 | Assert.Equal(908, date.ToTimeShort());
84 | }
85 |
86 | [Fact]
87 | public void ToTimeShort3()
88 | {
89 | var date = new PersianDateTime(1402, 3, 22, 9, 22, 15);
90 | Assert.Equal(922, date.ToTimeShort());
91 | }
92 |
93 | [Theory]
94 | [InlineData("fr-CA")]
95 | [InlineData("fa-IR")]
96 | [InlineData("en-US")]
97 | [InlineData("ar-SA")]
98 | [InlineData("ar-LB")]
99 | public void TestPersianCulture1(string cultureName)
100 | {
101 | using (new CultureScope(cultureName))
102 | {
103 | var persianDate = PersianDateTime.Parse("1404/07/20");
104 | Assert.Equal("1404", persianDate.ToString("yyyy"));
105 | Assert.Equal("7", persianDate.ToString("M"));
106 | Assert.Equal("07", persianDate.ToString("MM"));
107 | Assert.Equal("20", persianDate.ToString("dd"));
108 | }
109 | }
110 |
111 | [Theory]
112 | [InlineData("fr-CA")]
113 | [InlineData("fa-IR")]
114 | [InlineData("en-US")]
115 | [InlineData("ar-SA")]
116 | [InlineData("ar-LB")]
117 | public void TestPersianCulture2(string cultureName)
118 | {
119 | using (new CultureScope(cultureName))
120 | {
121 | var persianDate = new PersianDateTime(1404, 07, 20, 1, 1, 1, 123);
122 | var result = persianDate.ToString("fff");
123 | Assert.Contains("123", result);
124 | }
125 | }
126 |
127 | [Theory]
128 | [InlineData("fr-CA")]
129 | [InlineData("fa-IR")]
130 | [InlineData("en-US")]
131 | [InlineData("ar-SA")]
132 | [InlineData("ar-LB")]
133 | public void TestPersianCulture3(string cultureName)
134 | {
135 | using (new CultureScope(cultureName))
136 | {
137 | var persianDate = new PersianDateTime(new DateTime(2025, 10, 09));
138 | Assert.Equal(1404, persianDate.Year);
139 | Assert.Equal(7, persianDate.Month);
140 | Assert.Equal(17, persianDate.Day);
141 | }
142 | }
143 |
144 | [Theory]
145 | [InlineData("fr-CA")]
146 | [InlineData("fa-IR")]
147 | [InlineData("en-US")]
148 | [InlineData("ar-SA")]
149 | [InlineData("ar-LB")]
150 | public void TestPersianCulture4(string cultureName)
151 | {
152 | using (new CultureScope(cultureName))
153 | {
154 | var dateTime = DateTime.Parse("2025-10-09", CultureInfo.InvariantCulture);
155 | var persianDate = new PersianDateTime(dateTime);
156 | Assert.Equal(1404, persianDate.Year);
157 | Assert.Equal(7, persianDate.Month);
158 | Assert.Equal(17, persianDate.Day);
159 | }
160 | }
161 |
162 | [Theory]
163 | [InlineData("fr-CA")]
164 | [InlineData("fa-IR")]
165 | [InlineData("en-US")]
166 | [InlineData("ar-SA")]
167 | [InlineData("ar-LB")]
168 | public void TestPersianCulture5(string cultureName)
169 | {
170 | using (new CultureScope(cultureName))
171 | {
172 | var dateTime = DateTime.Parse("2025-10-09", CultureInfo.InvariantCulture);
173 | Assert.Equal(2025, dateTime.Year);
174 | Assert.Equal(10, dateTime.Month);
175 | Assert.Equal(09, dateTime.Day);
176 | }
177 | }
178 |
179 | [Theory]
180 | [InlineData("fr-CA")]
181 | [InlineData("fa-IR")]
182 | [InlineData("en-US")]
183 | [InlineData("ar-SA")]
184 | [InlineData("ar-LB")]
185 | public void TestPersianCulture6(string cultureName)
186 | {
187 | using (new CultureScope(cultureName))
188 | {
189 | var persianDate = new PersianDateTime(1404, 07, 20, 1, 1, 1, 123);
190 | var result1 = persianDate.ToString("yyyy", CultureInfo.GetCultureInfo(cultureName));
191 | var result2 = persianDate.ToString("yyyy", CultureInfo.InvariantCulture);
192 | var result3 = persianDate.ToString("yyyy");
193 | Assert.Equal("1404", result1);
194 | Assert.Equal("1404", result2);
195 | Assert.Equal("1404", result3);
196 | }
197 | }
198 |
199 | [Theory]
200 | [InlineData("fr-CA")]
201 | [InlineData("fa-IR")]
202 | [InlineData("en-US")]
203 | [InlineData("ar-SA")]
204 | [InlineData("ar-LB")]
205 | public void TestPersianCulture7(string cultureName)
206 | {
207 | using (new CultureScope(cultureName))
208 | {
209 | var persianDate = new PersianDateTime(1404, 07, 20, 1, 1, 1, 123);
210 | Assert.Equal(1404, persianDate.Year);
211 | Assert.Equal(7, persianDate.Month);
212 | Assert.Equal(20, persianDate.Day);
213 | }
214 | }
215 |
216 | [Theory]
217 | [InlineData("fr-CA")]
218 | [InlineData("fa-IR")]
219 | [InlineData("en-US")]
220 | [InlineData("ar-SA")]
221 | [InlineData("ar-LB")]
222 | public void TestPersianCulture8(string cultureName)
223 | {
224 | using (new CultureScope(cultureName))
225 | {
226 | var persianDate = PersianDateTime.Parse("1404-07-20");
227 | Assert.Equal("1404", persianDate.ToString("yyyy"));
228 | Assert.Equal("7", persianDate.ToString("M"));
229 | Assert.Equal("07", persianDate.ToString("MM"));
230 | Assert.Equal("20", persianDate.ToString("dd"));
231 | }
232 | }
233 |
234 | }
--------------------------------------------------------------------------------
/MD.PersianDateTime.Standard/PersianDateTime.cs:
--------------------------------------------------------------------------------
1 | using MD.PersianDateTime.Standard.Helpers;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Globalization;
5 | using System.Linq;
6 | using System.Runtime.Serialization;
7 | using System.Text.RegularExpressions;
8 |
9 | // ReSharper disable UnusedMember.Local
10 |
11 | namespace MD.PersianDateTime.Standard;
12 |
13 | ///
14 | /// Created By Mohammad Dayyan, @mdssoft
15 | /// 1397/01/10
16 | ///
17 | [Serializable]
18 | public struct PersianDateTime :
19 | ISerializable, IFormattable, IConvertible,
20 | IComparable, IComparable,
21 | IEquatable, IEquatable
22 | {
23 | #region properties and fields
24 |
25 | private static PersianCalendar _persianCalendar;
26 | private static PersianCalendar PersianCalendar
27 | {
28 | get
29 | {
30 | if (_persianCalendar != null) return _persianCalendar;
31 | _persianCalendar = new PersianCalendar();
32 | return _persianCalendar;
33 | }
34 | }
35 | private readonly DateTime _dateTime;
36 |
37 | ///
38 | /// آیا اعداد در خروجی به صورت انگلیسی نمایش داده شوند؟
39 | ///
40 | public bool PersianNumber { get; set; }
41 |
42 | ///
43 | /// سال شمسی
44 | ///
45 | public int Year
46 | {
47 | get
48 | {
49 | if (_dateTime <= DateTime.MinValue) return DateTime.MinValue.Year;
50 | return PersianCalendar.GetYear(_dateTime);
51 | }
52 | }
53 |
54 | ///
55 | /// ماه شمسی
56 | ///
57 | public int Month
58 | {
59 | get
60 | {
61 | if (_dateTime <= DateTime.MinValue) return DateTime.MinValue.Month;
62 | return PersianCalendar.GetMonth(_dateTime);
63 | }
64 | }
65 |
66 | ///
67 | /// نام فارسی ماه
68 | ///
69 | public string MonthName => ((PersianDateTimeMonthEnum)Month).ToString();
70 |
71 | ///
72 | /// روز ماه
73 | ///
74 | public int Day
75 | {
76 | get
77 | {
78 | if (_dateTime <= DateTime.MinValue) return DateTime.MinValue.Day;
79 | return PersianCalendar.GetDayOfMonth(_dateTime);
80 | }
81 | }
82 |
83 | ///
84 | /// روز هفته
85 | ///
86 | public DayOfWeek DayOfWeek
87 | {
88 | get
89 | {
90 | if (_dateTime <= DateTime.MinValue) return DateTime.MinValue.DayOfWeek;
91 | return PersianCalendar.GetDayOfWeek(_dateTime);
92 | }
93 | }
94 |
95 | ///
96 | /// روز هفته یا ایندکس شمسی
97 | ///
98 | /// شنبه دارای ایندکس صفر است
99 | ///
100 | public PersianDayOfWeek PersianDayOfWeek
101 | {
102 | get
103 | {
104 | var dayOfWeek = PersianCalendar.GetDayOfWeek(_dateTime);
105 | // ReSharper disable once InconsistentNaming
106 | PersianDayOfWeek persianDayOfWeek;
107 | switch (dayOfWeek)
108 | {
109 | case DayOfWeek.Sunday:
110 | persianDayOfWeek = PersianDayOfWeek.Sunday;
111 | break;
112 | case DayOfWeek.Monday:
113 | persianDayOfWeek = PersianDayOfWeek.Monday;
114 | break;
115 | case DayOfWeek.Tuesday:
116 | persianDayOfWeek = PersianDayOfWeek.Tuesday;
117 | break;
118 | case DayOfWeek.Wednesday:
119 | persianDayOfWeek = PersianDayOfWeek.Wednesday;
120 | break;
121 | case DayOfWeek.Thursday:
122 | persianDayOfWeek = PersianDayOfWeek.Thursday;
123 | break;
124 | case DayOfWeek.Friday:
125 | persianDayOfWeek = PersianDayOfWeek.Friday;
126 | break;
127 | case DayOfWeek.Saturday:
128 | persianDayOfWeek = PersianDayOfWeek.Saturday;
129 | break;
130 | default:
131 | throw new ArgumentOutOfRangeException();
132 | }
133 | return persianDayOfWeek;
134 | }
135 | }
136 |
137 | ///
138 | /// ساعت
139 | ///
140 | public int Hour
141 | {
142 | get
143 | {
144 | if (_dateTime <= DateTime.MinValue) return 12;
145 | return PersianCalendar.GetHour(_dateTime);
146 | }
147 | }
148 |
149 | ///
150 | /// ساعت دو رقمی
151 | ///
152 | public int ShortHour
153 | {
154 | get
155 | {
156 | int shortHour;
157 | if (Hour > 12)
158 | shortHour = Hour - 12;
159 | else
160 | shortHour = Hour;
161 | return shortHour;
162 | }
163 | }
164 |
165 | ///
166 | /// دقیقه
167 | ///
168 | public int Minute
169 | {
170 | get
171 | {
172 | if (_dateTime <= DateTime.MinValue) return 0;
173 | return PersianCalendar.GetMinute(_dateTime);
174 | }
175 | }
176 |
177 | ///
178 | /// ثانیه
179 | ///
180 | public int Second
181 | {
182 | get
183 | {
184 | if (_dateTime <= DateTime.MinValue) return 0;
185 | return PersianCalendar.GetSecond(_dateTime);
186 | }
187 | }
188 |
189 | ///
190 | /// میلی ثانیه
191 | ///
192 | public int Millisecond
193 | {
194 | get
195 | {
196 | if (_dateTime <= DateTime.MinValue) return 0;
197 | return (int)PersianCalendar.GetMilliseconds(_dateTime);
198 | }
199 | }
200 |
201 | ///
202 | /// تعداد روز در ماه
203 | ///
204 | public int GetMonthDays
205 | {
206 | get
207 | {
208 | int days;
209 | switch (Month)
210 | {
211 | case 1:
212 | case 2:
213 | case 3:
214 | case 4:
215 | case 5:
216 | case 6:
217 | days = 31;
218 | break;
219 |
220 | case 7:
221 | case 8:
222 | case 9:
223 | case 10:
224 | case 11:
225 | days = 30;
226 | break;
227 |
228 | case 12:
229 | {
230 | if (IsLeapYear) days = 30;
231 | else days = 29;
232 | break;
233 | }
234 |
235 | default:
236 | throw new Exception("Month number is wrong !!!");
237 | }
238 | return days;
239 | }
240 | }
241 |
242 | ///
243 | /// هفته چندم سال
244 | ///
245 | public int GetWeekOfYear
246 | {
247 | get
248 | {
249 | if (_dateTime <= DateTime.MinValue) return 0;
250 | return PersianCalendar.GetWeekOfYear(_dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Saturday);
251 | }
252 | }
253 |
254 | ///
255 | /// هفته چندم ماه
256 | ///
257 | public int GetWeekOfMonth
258 | {
259 | get
260 | {
261 | if (_dateTime <= DateTime.MinValue) return 0;
262 | var persianDateTime = AddDays(1 - Day);
263 | return GetWeekOfYear - persianDateTime.GetWeekOfYear + 1;
264 | }
265 | }
266 |
267 | ///
268 | /// روز چندم سال
269 | ///
270 | public int GetDayOfYear
271 | {
272 | get
273 | {
274 | if (_dateTime <= DateTime.MinValue) return 0;
275 | return PersianCalendar.GetDayOfYear(_dateTime);
276 | }
277 | }
278 |
279 | ///
280 | /// آیا سال کبیسه است؟
281 | ///
282 | public bool IsLeapYear
283 | {
284 | get
285 | {
286 | if (_dateTime <= DateTime.MinValue) return false;
287 | return PersianCalendar.IsLeapYear(Year);
288 | }
289 | }
290 |
291 | ///
292 | /// قبل از ظهر، بعد از ظهر
293 | ///
294 | private AmPmEnum PersianAmPm => _dateTime.ToString("tt", CultureInfo.InvariantCulture) == "PM" ? AmPmEnum.PM : AmPmEnum.AM;
295 |
296 | ///
297 | /// قبل از ظهر، بعد از ظهر به شکل مخفف . کوتاه
298 | ///
299 | public string GetPersianAmPm
300 | {
301 | get
302 | {
303 | var result = string.Empty;
304 | switch (PersianAmPm)
305 | {
306 | case AmPmEnum.AM:
307 | result = "ق.ظ";
308 | break;
309 |
310 | case AmPmEnum.PM:
311 | result = "ب.ظ";
312 | break;
313 | }
314 | return result;
315 | }
316 | }
317 |
318 | ///
319 | /// نام کامل ماه
320 | ///
321 | public string GetLongMonthName => GetPersianMonthNamePrivate(Month);
322 |
323 | ///
324 | /// سال دو رقمی
325 | ///
326 | public int GetShortYear => Year % 100;
327 |
328 | ///
329 | /// نام کامل روز
330 | ///
331 | public string GetLongDayOfWeekName
332 | {
333 | get
334 | {
335 | string weekDayName = null;
336 | switch (DayOfWeek)
337 | {
338 | case DayOfWeek.Sunday:
339 | weekDayName = PersianWeekDaysStruct.یکشنبه.Value;
340 | break;
341 |
342 | case DayOfWeek.Monday:
343 | weekDayName = PersianWeekDaysStruct.دوشنبه.Value;
344 | break;
345 |
346 | case DayOfWeek.Tuesday:
347 | weekDayName = PersianWeekDaysStruct.سه_شنبه.Value;
348 | break;
349 |
350 | case DayOfWeek.Wednesday:
351 | weekDayName = PersianWeekDaysStruct.چهارشنبه.Value;
352 | break;
353 |
354 | case DayOfWeek.Thursday:
355 | weekDayName = PersianWeekDaysStruct.پنجشنبه.Value;
356 | break;
357 |
358 | case DayOfWeek.Friday:
359 | weekDayName = PersianWeekDaysStruct.جمعه.Value;
360 | break;
361 |
362 | case DayOfWeek.Saturday:
363 | weekDayName = PersianWeekDaysStruct.شنبه.Value;
364 | break;
365 | }
366 | return weekDayName;
367 | }
368 | }
369 |
370 | ///
371 | /// نام یک حرفی روز، حرف اول روز
372 | ///
373 | public string GetShortDayOfWeekName
374 | {
375 | get
376 | {
377 | string weekDayName = null;
378 | switch (DayOfWeek)
379 | {
380 | case DayOfWeek.Sunday:
381 | weekDayName = "ی";
382 | break;
383 |
384 | case DayOfWeek.Monday:
385 | weekDayName = "د";
386 | break;
387 |
388 | case DayOfWeek.Tuesday:
389 | weekDayName = "س";
390 | break;
391 |
392 | case DayOfWeek.Wednesday:
393 | weekDayName = "چ";
394 | break;
395 |
396 | case DayOfWeek.Thursday:
397 | weekDayName = "پ";
398 | break;
399 |
400 | case DayOfWeek.Friday:
401 | weekDayName = "ج";
402 | break;
403 |
404 | case DayOfWeek.Saturday:
405 | weekDayName = "ش";
406 | break;
407 | }
408 |
409 | return weekDayName;
410 | }
411 | }
412 |
413 | ///
414 | /// تاریخ و زمان همین الان
415 | ///
416 | public static PersianDateTime Now => new(DateTime.Now);
417 |
418 | ///
419 | /// تاریخ امروز
420 | ///
421 | public static PersianDateTime Today => new(DateTime.Today);
422 |
423 | ///
424 | /// زمان به فرمتی مشابه
425 | ///
426 | /// 13:47:40:530
427 | ///
428 | public string TimeOfDay
429 | {
430 | get
431 | {
432 | var result = $"{Hour:00}:{Minute:00}:{Second:00}:{Millisecond:000}";
433 | if (!PersianNumber) return result;
434 | return ToPersianNumber(result);
435 | }
436 | }
437 |
438 | ///
439 | /// زمان به فرمتی مشابه زیر
440 | ///
441 | /// ساعت 01:47:40:530 ب.ظ
442 | ///
443 | public string LongTimeOfDay
444 | {
445 | get
446 | {
447 | var result = $"ساعت {ShortHour:00}:{Minute:00}:{Second:00}:{Millisecond:000} {GetPersianAmPm}";
448 | if (!PersianNumber) return result;
449 | return ToPersianNumber(result);
450 | }
451 | }
452 |
453 | ///
454 | /// زمان به فرمتی مشابه زیر
455 | ///
456 | /// 01:47:40 ب.ظ
457 | ///
458 | public string ShortTimeOfDay
459 | {
460 | get
461 | {
462 | var result = $"{ShortHour:00}:{Minute:00}:{Second:00} {GetPersianAmPm}";
463 | if (!PersianNumber) return result;
464 | return ToPersianNumber(result);
465 | }
466 | }
467 |
468 | ///
469 | /// تاریخ بدون احتساب زمان
470 | ///
471 | public PersianDateTime Date
472 | {
473 | get
474 | {
475 | var persianDateTime = new PersianDateTime(Year, Month, Day)
476 | {
477 | PersianNumber = PersianNumber
478 | };
479 | return persianDateTime;
480 | }
481 | }
482 |
483 | ///
484 | /// حداقل مقدار
485 | ///
486 | public static PersianDateTime MinValue => new(DateTime.MinValue);
487 |
488 | ///
489 | /// حداکثر مقدار
490 | ///
491 | public static PersianDateTime MaxValue => new(DateTime.MaxValue);
492 |
493 | #endregion
494 |
495 | #region ctor
496 |
497 | ///
498 | /// متد سازنده برای دی سریالایز شدن
499 | ///
500 | private PersianDateTime(SerializationInfo info, StreamingContext context)
501 | : this()
502 | {
503 | _dateTime = info.GetDateTime("DateTime");
504 | PersianNumber = info.GetBoolean("PersianNumber");
505 | }
506 |
507 | ///
508 | /// مقدار دهی اولیه با استفاده از دیت تایم میلادی
509 | ///
510 | /// DateTime
511 | /// آیا اعداد در خروجی های این آبجکت به صورت فارسی نمایش داده شوند یا فارسی؟
512 | private PersianDateTime(DateTime dateTime, bool persianNumber)
513 | : this()
514 | {
515 | _dateTime = dateTime;
516 | PersianNumber = persianNumber;
517 | }
518 |
519 | ///
520 | /// مقدار دهی اولیه با استفاده از دیت تایم میلادی
521 | ///
522 | public PersianDateTime(DateTime dateTime)
523 | : this()
524 | {
525 | _dateTime = dateTime;
526 | }
527 |
528 | ///
529 | /// مقدار دهی اولیه با استفاده از دیت تایم قابل نال میلادی
530 | ///
531 | public PersianDateTime(DateTime? nullableDateTime)
532 | : this()
533 | {
534 | if (!nullableDateTime.HasValue)
535 | {
536 | _dateTime = DateTime.MinValue;
537 | return;
538 | }
539 | _dateTime = nullableDateTime.Value;
540 | }
541 |
542 | ///
543 | /// مقدار دهی اولیه
544 | ///
545 | /// سال شمسی
546 | /// ماه شمسی
547 | /// روز شمسی
548 | public PersianDateTime(int persianYear, int persianMonth, int persianDay)
549 | : this()
550 | {
551 | _dateTime = PersianCalendar.ToDateTime(persianYear, persianMonth, persianDay, 0, 0, 0, 0);
552 | }
553 |
554 | ///
555 | /// مقدار دهی اولیه
556 | ///
557 | /// سال شمسی
558 | /// ماه شمسی
559 | /// روز شمسی
560 | /// ساعت
561 | /// دقیقه
562 | /// ثانیه
563 | public PersianDateTime(int persianYear, int persianMonth, int persianDay, int hour, int minute, int second)
564 | : this()
565 | {
566 | _dateTime = PersianCalendar.ToDateTime(persianYear, persianMonth, persianDay, hour, minute, second, 0);
567 | }
568 |
569 | ///
570 | /// مقدار دهی اولیه
571 | ///
572 | /// سال شمسی
573 | /// ماه شمسی
574 | /// روز شمسی
575 | /// سال
576 | /// دقیقه
577 | /// ثانیه
578 | /// میلی ثانیه
579 | public PersianDateTime(int persianYear, int persianMonth, int persianDay, int hour, int minute, int second, int milliseconds)
580 | : this()
581 | {
582 | _dateTime = PersianCalendar.ToDateTime(persianYear, persianMonth, persianDay, hour, minute, second, milliseconds);
583 | }
584 |
585 | #endregion
586 |
587 | #region Types
588 |
589 | private enum AmPmEnum
590 | {
591 | // ReSharper disable once InconsistentNaming
592 | AM = 0,
593 | // ReSharper disable once InconsistentNaming
594 | PM = 1,
595 | None = 2
596 | }
597 |
598 | private enum PersianDateTimeMonthEnum
599 | {
600 | فروردین = 1,
601 | اردیبهشت = 2,
602 | خرداد = 3,
603 | تیر = 4,
604 | مرداد = 5,
605 | شهریور = 6,
606 | مهر = 7,
607 | آبان = 8,
608 | آذر = 9,
609 | دی = 10,
610 | بهمن = 11,
611 | اسفند = 12
612 | }
613 |
614 | private struct PersianWeekDaysStruct
615 | {
616 | public static KeyValuePair شنبه => new((int)DayOfWeek.Saturday, "شنبه");
617 | public static KeyValuePair یکشنبه => new((int)DayOfWeek.Sunday, "یکشنبه");
618 | public static KeyValuePair دوشنبه => new((int)DayOfWeek.Monday, "دوشنبه");
619 | // ReSharper disable once InconsistentNaming
620 | public static KeyValuePair سه_شنبه => new((int)DayOfWeek.Tuesday, "سه شنبه");
621 | public static KeyValuePair چهارشنبه => new((int)DayOfWeek.Thursday, "چهارشنبه");
622 | public static KeyValuePair پنجشنبه => new((int)DayOfWeek.Wednesday, "پنج شنبه");
623 | public static KeyValuePair جمعه => new((int)DayOfWeek.Friday, "جمعه");
624 | }
625 |
626 | #endregion
627 |
628 | #region override
629 |
630 | ///
631 | /// تبدیل تاریخ به رشته با فرمت مشابه زیر
632 | ///
633 | /// 1393/09/14 13:49:40
634 | ///
635 | public override string ToString()
636 | {
637 | return ToString("");
638 | }
639 |
640 | ///
641 | public override bool Equals(object obj)
642 | {
643 | if (obj is not PersianDateTime) return false;
644 | var persianDateTime = (PersianDateTime)obj;
645 | return _dateTime == persianDateTime.ToDateTime();
646 | }
647 |
648 | ///
649 | public override int GetHashCode()
650 | {
651 | return _dateTime.GetHashCode();
652 | }
653 |
654 | ///
655 | /// مقایسه با تاریخ دیگر
656 | ///
657 | /// مقدار بازگشتی همانند مقدار بازگشتی متد کامپیر در دیت تایم دات نت است
658 | public int CompareTo(PersianDateTime otherPersianDateTime)
659 | {
660 | return _dateTime.CompareTo(otherPersianDateTime.ToDateTime());
661 | }
662 |
663 | ///
664 | /// مقایسه با تاریخ دیگر
665 | ///
666 | /// مقدار بازگشتی همانند مقدار بازگشتی متد کامپیر در دیت تایم دات نت است
667 | public int CompareTo(DateTime otherDateTime)
668 | {
669 | return _dateTime.CompareTo(otherDateTime);
670 | }
671 |
672 | #region operators
673 |
674 | ///
675 | /// تبدیل خودکار به دیت تایم میلادی
676 | ///
677 | public static implicit operator DateTime(PersianDateTime persianDateTime)
678 | {
679 | return persianDateTime.ToDateTime();
680 | }
681 |
682 | ///
683 | /// اپراتور برابر
684 | ///
685 | public static bool operator ==(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
686 | {
687 | return persianDateTime1.Equals(persianDateTime2);
688 | }
689 |
690 | ///
691 | /// اپراتور نامساوی
692 | ///
693 | public static bool operator !=(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
694 | {
695 | return !persianDateTime1.Equals(persianDateTime2);
696 | }
697 |
698 | ///
699 | /// اپراتور بزرگتری
700 | ///
701 | public static bool operator >(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
702 | {
703 | return persianDateTime1.ToDateTime() > persianDateTime2.ToDateTime();
704 | }
705 |
706 | ///
707 | /// اپراتور کوچکتری
708 | ///
709 | public static bool operator <(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
710 | {
711 | return persianDateTime1.ToDateTime() < persianDateTime2.ToDateTime();
712 | }
713 |
714 | ///
715 | /// اپراتور بزرگتر مساوی
716 | ///
717 | public static bool operator >=(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
718 | {
719 | return persianDateTime1.ToDateTime() >= persianDateTime2.ToDateTime();
720 | }
721 |
722 | ///
723 | /// اپراتور کوچکتر مساوی
724 | ///
725 | public static bool operator <=(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
726 | {
727 | return persianDateTime1.ToDateTime() <= persianDateTime2.ToDateTime();
728 | }
729 |
730 | ///
731 | /// اپراتور جمع تو زمان
732 | ///
733 | public static PersianDateTime operator +(PersianDateTime persianDateTime1, TimeSpan timeSpanToAdd)
734 | {
735 | DateTime dateTime1 = persianDateTime1;
736 | return new PersianDateTime(dateTime1.Add(timeSpanToAdd));
737 | }
738 |
739 | ///
740 | /// اپراتور کم کردن دو زمان از هم
741 | ///
742 | public static TimeSpan operator -(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
743 | {
744 | DateTime dateTime1 = persianDateTime1;
745 | DateTime dateTime2 = persianDateTime2;
746 | return dateTime1 - dateTime2;
747 | }
748 |
749 | #endregion
750 |
751 | #endregion
752 |
753 | #region ISerializable
754 |
755 | ///
756 | public void GetObjectData(SerializationInfo info, StreamingContext context)
757 | {
758 | info.AddValue("DateTime", ToDateTime());
759 | info.AddValue("PersianNumber", PersianNumber);
760 | }
761 |
762 | #endregion
763 |
764 | #region IComparable
765 |
766 | ///
767 | public bool Equals(PersianDateTime other)
768 | {
769 | return Year == other.Year && Month == other.Month && Day == other.Day &&
770 | Hour == other.Hour && Minute == other.Minute && Second == other.Second && Millisecond == other.Millisecond;
771 | }
772 |
773 | ///
774 | public bool Equals(DateTime other)
775 | {
776 | return _dateTime == other;
777 | }
778 |
779 | #endregion
780 |
781 | #region Methods
782 |
783 | ///
784 | /// تاریخ شروع ماه رمضان
785 | ///
786 | /// چون ممکن است در یک سال شمسی دو شروع ماه رمضان داشته باشیم
787 | ///
788 | /// مقدار بازگشتی آرایه است که حداکثر دو آیتم دارد
789 | ///
790 | public PersianDateTime[] GetStartDayOfRamadan(int hijriAdjustment)
791 | {
792 | var result = new List();
793 | var hijriCalendar = new HijriCalendar { HijriAdjustment = hijriAdjustment };
794 |
795 | var currentHijriYear = hijriCalendar.GetYear(_dateTime);
796 |
797 | var startDayOfRamadan1 = new PersianDateTime(hijriCalendar.ToDateTime(currentHijriYear, 9, 1, 0, 0, 0, 0));
798 | result.Add(startDayOfRamadan1);
799 |
800 | var startDayOfRamadan2 = new PersianDateTime(hijriCalendar.ToDateTime(++currentHijriYear, 9, 1, 0, 0, 0, 0));
801 | if (startDayOfRamadan1.Year == startDayOfRamadan2.Year)
802 | result.Add(startDayOfRamadan2);
803 |
804 | return result.ToArray();
805 | }
806 |
807 | ///
808 | /// تاریخ آخرین روز ماه شمسی
809 | ///
810 | public PersianDateTime GetPersianDateOfLastDayOfMonth()
811 | {
812 | return new PersianDateTime(Year, Month, GetMonthDays);
813 | }
814 |
815 | ///
816 | /// تاریخ آخرین روز سال شمسی
817 | ///
818 | public PersianDateTime GetPersianDateOfLastDayOfYear()
819 | {
820 | return new PersianDateTime(Year, 12, IsLeapYear ? 30 : 29);
821 | }
822 |
823 | ///
824 | /// پارس کردن رشته و تبدیل به نوع PersianDateTime
825 | ///
826 | /// متنی که باید پارس شود
827 | /// کاراکتری که جدا کننده تاریخ ها است
828 | public static PersianDateTime Parse(string persianDateTimeInString, string dateSeparatorPattern = @"\/|-")
829 | {
830 | //Convert persian and arabic digit to english to avoid throwing exception in Parse method
831 | persianDateTimeInString = ExtensionsHelper.ConvertDigitsToLatin(persianDateTimeInString);
832 |
833 | string month = "", year, day,
834 | hour = "0",
835 | minute = "0",
836 | second = "0",
837 | milliseconds = "0";
838 | var amPmEnum = AmPmEnum.None;
839 | var containMonthSeparator = Regex.IsMatch(persianDateTimeInString, dateSeparatorPattern);
840 |
841 | persianDateTimeInString = ToEnglishNumber(persianDateTimeInString.Replace(" ", " ").Replace(" ", "-").Replace("\\", "-"));
842 | persianDateTimeInString = Regex.Replace(persianDateTimeInString, dateSeparatorPattern, "-");
843 | persianDateTimeInString = persianDateTimeInString.Replace("ك", "ک").Replace("ي", "ی");
844 |
845 | persianDateTimeInString = $"-{persianDateTimeInString}-";
846 |
847 | // بدست آوردن ب.ظ یا ق.ظ
848 | if (persianDateTimeInString.IndexOf("ق.ظ", StringComparison.InvariantCultureIgnoreCase) > -1)
849 | amPmEnum = AmPmEnum.AM;
850 | else if (persianDateTimeInString.IndexOf("ب.ظ", StringComparison.InvariantCultureIgnoreCase) > -1)
851 | amPmEnum = AmPmEnum.PM;
852 |
853 | if (persianDateTimeInString.IndexOf(":", StringComparison.InvariantCultureIgnoreCase) > -1) // رشته ورودی شامل ساعت نیز هست
854 | {
855 | persianDateTimeInString = Regex.Replace(persianDateTimeInString, "-*:-*", ":");
856 | hour = Regex.Match(persianDateTimeInString, @"(?<=-)\d{1,2}(?=:)", RegexOptions.IgnoreCase).Value;
857 | minute = Regex.Match(persianDateTimeInString, @"(?<=-\d{1,2}:)\d{1,2}(?=:?)", RegexOptions.IgnoreCase).Value;
858 | if (persianDateTimeInString.IndexOf(':') != persianDateTimeInString.LastIndexOf(':'))
859 | {
860 | second = Regex.Match(persianDateTimeInString, @"(?<=-\d{1,2}:\d{1,2}:)\d{1,2}(?=(\d{1,2})?)", RegexOptions.IgnoreCase).Value;
861 | milliseconds = Regex.Match(persianDateTimeInString, @"(?<=-\d{1,2}:\d{1,2}:\d{1,2}:)\d{1,4}(?=(\d{1,2})?)", RegexOptions.IgnoreCase).Value;
862 | if (string.IsNullOrEmpty(milliseconds)) milliseconds = "0";
863 | }
864 | }
865 |
866 | if (containMonthSeparator)
867 | {
868 | // بدست آوردن ماه
869 | month = Regex.Match(persianDateTimeInString, @"(?<=\d{2,4}-)\d{1,2}(?=-\d{1,2}-\d{1,2}(?!-\d{1,2}:))", RegexOptions.IgnoreCase).Value;
870 | if (string.IsNullOrEmpty(month))
871 | month = Regex.Match(persianDateTimeInString, @"(?<=\d{2,4}-)\d{1,2}(?=-\d{1,2}[^:])", RegexOptions.IgnoreCase).Value;
872 |
873 | // بدست آوردن روز
874 | day = Regex.Match(persianDateTimeInString, @"(?<=\d{2,4}-\d{1,2}-)\d{1,2}(?=-)", RegexOptions.IgnoreCase).Value;
875 |
876 | // بدست آوردن سال
877 | year = Regex.Match(persianDateTimeInString, @"(?<=-)\d{2,4}(?=-\d{1,2}-\d{1,2})", RegexOptions.IgnoreCase).Value;
878 | }
879 | else
880 | {
881 | foreach (PersianDateTimeMonthEnum item in Enum.GetValues(typeof(PersianDateTimeMonthEnum)))
882 | {
883 | var itemValueInString = item.ToString();
884 | if (!persianDateTimeInString.Contains(itemValueInString)) continue;
885 | month = ((int)item).ToString(CultureInfo.InvariantCulture);
886 | break;
887 | }
888 |
889 | if (string.IsNullOrEmpty(month))
890 | throw new Exception("عدد یا حرف ماه در رشته ورودی وجود ندارد");
891 |
892 | // بدست آوردن روز
893 | var dayMatch = Regex.Match(persianDateTimeInString, @"(?<=-)\d{1,2}(?=-)", RegexOptions.IgnoreCase);
894 | if (dayMatch.Success)
895 | {
896 | day = dayMatch.Value;
897 | persianDateTimeInString = Regex.Replace(persianDateTimeInString, $"(?<=-){day}(?=-)", "");
898 | }
899 | else
900 | throw new Exception("عدد روز در رشته ورودی وجود ندارد");
901 |
902 | // بدست آوردن سال
903 | var yearMatch = Regex.Match(persianDateTimeInString, @"(?<=-)\d{4}(?=-)", RegexOptions.IgnoreCase);
904 | if (yearMatch.Success)
905 | year = yearMatch.Value;
906 | else
907 | {
908 | yearMatch = Regex.Match(persianDateTimeInString, @"(?<=-)\d{2,4}(?=-)", RegexOptions.IgnoreCase);
909 | if (yearMatch.Success)
910 | year = yearMatch.Value;
911 | else
912 | throw new Exception("عدد سال در رشته ورودی وجود ندارد");
913 | }
914 | }
915 |
916 | //if (year.Length <= 2 && year[0] == '9') year = string.Format("13{0}", year);
917 | //else if (year.Length <= 2) year = string.Format("14{0}", year);
918 |
919 | var numericYear = int.Parse(year);
920 | var numericMonth = int.Parse(month);
921 | var numericDay = int.Parse(day);
922 | var numericHour = int.Parse(hour);
923 | var numericMinute = int.Parse(minute);
924 | var numericSecond = int.Parse(second);
925 | var numericMillisecond = int.Parse(milliseconds);
926 |
927 | if (numericYear < 100)
928 | numericYear += 1300;
929 |
930 | switch (amPmEnum)
931 | {
932 | case AmPmEnum.PM:
933 | if (numericHour < 12)
934 | numericHour = numericHour + 12;
935 | break;
936 | case AmPmEnum.AM:
937 | case AmPmEnum.None:
938 | break;
939 | }
940 |
941 | return new PersianDateTime(numericYear, numericMonth, numericDay, numericHour, numericMinute, numericSecond, numericMillisecond);
942 | }
943 |
944 | ///
945 | /// پارس کردن یک رشته برای یافتن تاریخ شمسی
946 | ///
947 | public static bool TryParse(string persianDateTimeInString, out PersianDateTime result, string dateSeparatorPattern = @"\/|-")
948 | {
949 | if (string.IsNullOrEmpty(persianDateTimeInString))
950 | {
951 | result = MinValue;
952 | return false;
953 | }
954 | try
955 | {
956 | result = Parse(persianDateTimeInString, dateSeparatorPattern);
957 | return true;
958 | }
959 | catch
960 | {
961 | result = MinValue;
962 | return false;
963 | }
964 | }
965 |
966 | ///
967 | /// پارس کردن عددی در فرمت تاریخ شمسی
968 | ///
969 | /// همانند 13920305
970 | ///
971 | public static PersianDateTime Parse(int numericPersianDate)
972 | {
973 | if (numericPersianDate.ToString(CultureInfo.InvariantCulture).Length != 8)
974 | throw new InvalidCastException("Numeric persian date must have a format like 13920101.");
975 | var year = numericPersianDate / 10000;
976 | var day = numericPersianDate % 100;
977 | var month = numericPersianDate / 100 % 100;
978 | return new PersianDateTime(year, month, day);
979 | }
980 | ///
981 | /// پارس کردن عددی در فرمت تاریخ شمسی
982 | ///
983 | /// همانند 13920305
984 | ///
985 | public static bool TryParse(int numericPersianDate, out PersianDateTime result)
986 | {
987 | try
988 | {
989 | result = Parse(numericPersianDate);
990 | return true;
991 | }
992 | catch
993 | {
994 | result = MinValue;
995 | return false;
996 | }
997 | }
998 |
999 | ///
1000 | /// پارس کردن عددی در فرمت تاریخ و زمان شمسی
1001 | ///
1002 | /// همانند 13961223072132004
1003 | ///
1004 | public static PersianDateTime Parse(long numericPersianDateTime)
1005 | {
1006 | if (numericPersianDateTime.ToString(CultureInfo.InvariantCulture).Length != 17)
1007 | throw new InvalidCastException("Numeric persian date time must have a format like 1396122310223246.");
1008 | var year = numericPersianDateTime / 10000000000000;
1009 | var month = numericPersianDateTime / 100000000000 % 100;
1010 | var day = numericPersianDateTime / 1000000000 % 100;
1011 | var hour = numericPersianDateTime / 10000000 % 100;
1012 | var minute = numericPersianDateTime / 100000 % 100;
1013 | var second = numericPersianDateTime / 1000 % 100;
1014 | var millisecond = numericPersianDateTime % 1000;
1015 | return new PersianDateTime((int)year, (int)month, (int)day, (int)hour, (int)minute, (int)second, (int)millisecond);
1016 | }
1017 | ///
1018 | /// پارس کردن عددی در فرمت تاریخ و زمان شمسی
1019 | ///
1020 | /// همانند 13961223102232461
1021 | ///
1022 | public static bool TryParse(long numericPersianDateTime, out PersianDateTime result)
1023 | {
1024 | try
1025 | {
1026 | result = Parse(numericPersianDateTime);
1027 | return true;
1028 | }
1029 | catch
1030 | {
1031 | result = MinValue;
1032 | return false;
1033 | }
1034 | }
1035 |
1036 | private static readonly List GregorianWeekDayNames = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"];
1037 | private static readonly List GregorianMonthNames =
1038 | [
1039 | "january", "february", "march",
1040 | "april", "may", "june",
1041 | "july", "august", "september",
1042 | "october", "november", "december"
1043 | ];
1044 | private static readonly List PmAm = ["pm", "am"];
1045 |
1046 | ///
1047 | /// تبدیل به ساعت گرینویچ
1048 | ///
1049 | public PersianDateTime ToUniversalTime()
1050 | {
1051 | return new PersianDateTime(_dateTime.ToUniversalTime());
1052 | }
1053 |
1054 | ///
1055 | /// دریافت تعداد ثانیه های سپری شده از اولین روز سال 1397
1056 | ///
1057 | public int ToEpochTime()
1058 | {
1059 | var timeSpan = _dateTime - new DateTime(1970, 1, 1);
1060 | return (int)timeSpan.TotalSeconds;
1061 | }
1062 |
1063 | ///
1064 | /// فرمت های که پشتیبانی می شوند
1065 | ///
1066 | /// yyyy: سال چهار رقمی
1067 | ///
1068 | /// yy: سال دو رقمی
1069 | ///
1070 | /// MMMM: نام فارسی ماه
1071 | ///
1072 | /// MM: عدد دو رقمی ماه
1073 | ///
1074 | /// M: عدد یک رقمی ماه
1075 | ///
1076 | /// dddd: نام فارسی روز هفته
1077 | ///
1078 | /// dd: عدد دو رقمی روز ماه
1079 | ///
1080 | /// d: عدد یک رقمی روز ماه
1081 | ///
1082 | /// HH: ساعت دو رقمی با فرمت 00 تا 24
1083 | ///
1084 | /// H: ساعت یک رقمی با فرمت 0 تا 24
1085 | ///
1086 | /// hh: ساعت دو رقمی با فرمت 00 تا 12
1087 | ///
1088 | /// h: ساعت یک رقمی با فرمت 0 تا 12
1089 | ///
1090 | /// mm: عدد دو رقمی دقیقه
1091 | ///
1092 | /// m: عدد یک رقمی دقیقه
1093 | ///
1094 | /// ss: ثانیه دو رقمی
1095 | ///
1096 | /// s: ثانیه یک رقمی
1097 | ///
1098 | /// fff: میلی ثانیه 3 رقمی
1099 | ///
1100 | /// ff: میلی ثانیه 2 رقمی
1101 | ///
1102 | /// f: میلی ثانیه یک رقمی
1103 | ///
1104 | /// tt: ب.ظ یا ق.ظ
1105 | ///
1106 | /// t: حرف اول از ب.ظ یا ق.ظ
1107 | ///
1108 | public string ToString(string format, IFormatProvider fp = null)
1109 | {
1110 | if (string.IsNullOrEmpty(format)) format = "yyyy/MM/dd HH:mm:ss";
1111 | var dateTimeString = format.Trim();
1112 |
1113 | dateTimeString = dateTimeString.Replace("yyyy", Year.ToString(CultureInfo.InvariantCulture));
1114 | dateTimeString = dateTimeString.Replace("yy", GetShortYear.ToString("00", CultureInfo.InvariantCulture));
1115 | dateTimeString = dateTimeString.Replace("MMMM", MonthName);
1116 | dateTimeString = dateTimeString.Replace("MM", Month.ToString("00", CultureInfo.InvariantCulture));
1117 | dateTimeString = dateTimeString.Replace("M", Month.ToString(CultureInfo.InvariantCulture));
1118 | dateTimeString = dateTimeString.Replace("dddd", GetLongDayOfWeekName);
1119 | dateTimeString = dateTimeString.Replace("dd", Day.ToString("00", CultureInfo.InvariantCulture));
1120 | dateTimeString = dateTimeString.Replace("d", Day.ToString(CultureInfo.InvariantCulture));
1121 | dateTimeString = dateTimeString.Replace("HH", Hour.ToString("00", CultureInfo.InvariantCulture));
1122 | dateTimeString = dateTimeString.Replace("H", Hour.ToString(CultureInfo.InvariantCulture));
1123 | dateTimeString = dateTimeString.Replace("hh", ShortHour.ToString("00", CultureInfo.InvariantCulture));
1124 | dateTimeString = dateTimeString.Replace("h", ShortHour.ToString(CultureInfo.InvariantCulture));
1125 | dateTimeString = dateTimeString.Replace("mm", Minute.ToString("00", CultureInfo.InvariantCulture));
1126 | dateTimeString = dateTimeString.Replace("m", Minute.ToString(CultureInfo.InvariantCulture));
1127 | dateTimeString = dateTimeString.Replace("ss", Second.ToString("00", CultureInfo.InvariantCulture));
1128 | dateTimeString = dateTimeString.Replace("s", Second.ToString(CultureInfo.InvariantCulture));
1129 | dateTimeString = dateTimeString.Replace("fff", Millisecond.ToString("000", CultureInfo.InvariantCulture));
1130 | dateTimeString = dateTimeString.Replace("ff", (Millisecond / 10).ToString("00", CultureInfo.InvariantCulture));
1131 | dateTimeString = dateTimeString.Replace("f", (Millisecond / 100).ToString(CultureInfo.InvariantCulture));
1132 | dateTimeString = dateTimeString.Replace("tt", GetPersianAmPm);
1133 | dateTimeString = dateTimeString.Replace("t", GetPersianAmPm[0].ToString(CultureInfo.InvariantCulture));
1134 |
1135 | if (PersianNumber)
1136 | dateTimeString = ToPersianNumber(dateTimeString);
1137 |
1138 | return dateTimeString;
1139 | }
1140 |
1141 | ///
1142 | /// بررسی میکند آیا تاریخ ورودی تاریخ میلادی است یا نه
1143 | ///
1144 | public static bool IsChristianDate(string inputString)
1145 | {
1146 | inputString = inputString.ToLower();
1147 | bool result;
1148 |
1149 | foreach (var gregorianWeekDayName in GregorianWeekDayNames)
1150 | {
1151 | result = inputString.Contains(gregorianWeekDayName);
1152 | if (result) return true;
1153 | }
1154 |
1155 | foreach (var gregorianMonthName in GregorianMonthNames)
1156 | {
1157 | result = inputString.Contains(gregorianMonthName);
1158 | if (result) return true;
1159 | }
1160 |
1161 | foreach (var item in PmAm)
1162 | {
1163 | result = inputString.Contains(item);
1164 | if (result) return true;
1165 | }
1166 |
1167 | result = Regex.IsMatch(inputString, @"(1[8-9]|[2-9][0-9])\d{2}", RegexOptions.IgnoreCase);
1168 |
1169 | return result;
1170 | }
1171 |
1172 | ///
1173 | /// بررسی میکند آیا تاریخ ورودی مطابق تاریخ اس کسو ال سرور می باشد یا نه
1174 | ///
1175 | public static bool IsSqlDateTime(DateTime dateTime)
1176 | {
1177 | var minSqlDateTimeValue = new DateTime(1753, 1, 1);
1178 | return dateTime >= minSqlDateTimeValue;
1179 | }
1180 |
1181 | ///
1182 | /// تبدیل نام ماه شمسی به عدد معادل آن
1183 | ///
1184 | /// به طور مثال آذر را به 9 تبدیل می کند
1185 | ///
1186 | public int GetMonthEnum(string longMonthName)
1187 | {
1188 | var monthEnum = (PersianDateTimeMonthEnum)Enum.Parse(typeof(PersianDateTimeMonthEnum), longMonthName);
1189 | return (int)monthEnum;
1190 | }
1191 |
1192 | ///
1193 | /// نمایش تاریخ به فرمتی مشابه زیر
1194 | ///
1195 | /// 1393/09/14
1196 | ///
1197 | public string ToShortDateString()
1198 | {
1199 | var result = $"{Year:0000}/{Month:00}/{Day:00}";
1200 | if (!PersianNumber) return result;
1201 | return ToPersianNumber(result);
1202 | }
1203 |
1204 | ///
1205 | /// نمایش تاریخ به فرمتی مشابه زیر
1206 | ///
1207 | /// ج 14 آذر 93
1208 | ///
1209 | public string ToShortDate1String()
1210 | {
1211 | var result = $"{GetShortDayOfWeekName} {Day:00} {GetLongMonthName} {GetShortYear}";
1212 | if (!PersianNumber) return result;
1213 | return ToPersianNumber(result);
1214 | }
1215 |
1216 | ///
1217 | /// نمایش تاریخ به صورت عدد و در فرمتی مشابه زیر
1218 | ///
1219 | /// 13930914
1220 | ///
1221 | public int ToShortDateInt()
1222 | {
1223 | return int.Parse($"{Year:0000}{Month:00}{Day:00}");
1224 | }
1225 |
1226 | ///
1227 | /// نمایش تاریخ و ساعت تا دقت میلی ثانیه به صورت عدد
1228 | ///
1229 | /// 1396122310324655
1230 | ///
1231 | public long ToLongDateTimeInt()
1232 | {
1233 | return long.Parse($"{Year:0000}{Month:00}{Day:00}{Hour:00}{Minute:00}{Second:00}{Millisecond:000}");
1234 | }
1235 |
1236 | ///
1237 | /// در این فرمت نمایش ساعت و دقیقه و ثانیه در کنار هم با حذف علامت : تبدیل به عدد می شوند و نمایش داده می شود
1238 | ///
1239 | /// مثال: 123452
1240 | ///
1241 | /// که به معنای ساعت 12 و 34 دقیقه و 52 ثانیه می باشد
1242 | ///
1243 | public int ToTimeInt()
1244 | {
1245 | return int.Parse($"{Hour:00}{Minute:00}{Second:00}");
1246 | }
1247 |
1248 | ///
1249 | /// در این فرمت نمایش ساعت و دقیقه در کنار هم با حذف علامت : تبدیل به عدد می شوند و نمایش داده می شود
1250 | ///
1251 | /// مثال: 1234
1252 | ///
1253 | /// که به معنای ساعت 12 و 34 دقیقه می باشد
1254 | ///
1255 | public short ToTimeShort()
1256 | {
1257 | return short.Parse($"{Hour:00}{Minute:00}");
1258 | }
1259 |
1260 | ///
1261 | /// نمایش تاریخ به فرمتی مشابه زیر
1262 | ///
1263 | /// جمعه، 14 آذر 1393
1264 | ///
1265 | public string ToLongDateString()
1266 | {
1267 | var result = $"{GetLongDayOfWeekName}، {Day:00} {GetLongMonthName} {Year:0000}";
1268 | if (!PersianNumber) return result;
1269 | return ToPersianNumber(result);
1270 | }
1271 |
1272 | ///
1273 | /// نمایش تاریخ و زمان به فرمتی مشابه زیر
1274 | ///
1275 | /// جمعه، 14 آذر 1393 ساعت 13:50:27
1276 | ///
1277 | public string ToLongDateTimeString()
1278 | {
1279 | var result =
1280 | $"{GetLongDayOfWeekName}، {Day:00} {GetLongMonthName} {Year:0000} ساعت {Hour:00}:{Minute:00}:{Second:00}";
1281 | if (!PersianNumber) return result;
1282 | return ToPersianNumber(result);
1283 | }
1284 |
1285 | ///
1286 | /// نمایش تاریخ و زمان به فرمتی مشابه زیر
1287 | ///
1288 | /// جمعه، 14 آذر 1393 13:50
1289 | ///
1290 | public string ToShortDateTimeString()
1291 | {
1292 | var result = $"{GetLongDayOfWeekName}، {Day:00} {GetLongMonthName} {Year:0000} {Hour:00}:{Minute:00}";
1293 | if (!PersianNumber) return result;
1294 | return ToPersianNumber(result);
1295 | }
1296 |
1297 | ///
1298 | /// نمایش زمان به فرمتی مشابه زیر
1299 | ///
1300 | /// 01:50 ب.ظ
1301 | ///
1302 | public string ToShortTimeString()
1303 | {
1304 | var result = $"{ShortHour:00}:{Minute:00} {GetPersianAmPm}";
1305 | if (!PersianNumber) return result;
1306 | return ToPersianNumber(result);
1307 | }
1308 |
1309 | ///
1310 | /// نمایش زمان به فرمتی مشابه زیر
1311 | ///
1312 | /// 13:50:20
1313 | ///
1314 | public string ToLongTimeString()
1315 | {
1316 | var result = $"{Hour:00}:{Minute:00}:{Second:00}";
1317 | if (!PersianNumber) return result;
1318 | return ToPersianNumber(result);
1319 | }
1320 |
1321 | ///
1322 | /// نمایش زمان به فرمتی مشابه زیر
1323 | ///
1324 | /// 1 دقیقه قبل
1325 | ///
1326 | public string ElapsedTime()
1327 | {
1328 | var persianDateTimeNow = new PersianDateTime(DateTime.Now);
1329 | var timeSpan = persianDateTimeNow - _dateTime;
1330 | if (timeSpan.TotalDays > 90)
1331 | return ToShortDateTimeString();
1332 |
1333 | var result = string.Empty;
1334 | if (timeSpan.TotalDays > 30)
1335 | {
1336 | var month = timeSpan.TotalDays / 30;
1337 | if (month > 0)
1338 | result = $"{month:0} ماه قبل";
1339 | }
1340 | else if (timeSpan.TotalDays >= 1)
1341 | {
1342 | result = $"{timeSpan.TotalDays:0} روز قبل";
1343 | }
1344 | else if (timeSpan.TotalHours >= 1)
1345 | {
1346 | result = $"{timeSpan.TotalHours:0} ساعت قبل";
1347 | }
1348 | else
1349 | {
1350 | var minute = timeSpan.TotalMinutes;
1351 | if (minute <= 1) minute = 1;
1352 | result = $"{minute:0} دقیقه قبل";
1353 | }
1354 | if (!PersianNumber) return result;
1355 | return ToPersianNumber(result);
1356 | }
1357 |
1358 | ///
1359 | /// گرفتن فقط زمان
1360 | ///
1361 | public TimeSpan GetTime()
1362 | {
1363 | return new TimeSpan(0, _dateTime.Hour, _dateTime.Minute, _dateTime.Second, _dateTime.Millisecond);
1364 | }
1365 |
1366 | ///
1367 | /// تنظیم کردن زمان
1368 | ///
1369 | public PersianDateTime SetTime(int hour, int minute, int second = 0, int millisecond = 0)
1370 | {
1371 | return new PersianDateTime(Year, Month, Day, hour, minute, second, millisecond);
1372 | }
1373 |
1374 | ///
1375 | /// تبدیل به تاریخ میلادی
1376 | ///
1377 | public DateTime ToDateTime()
1378 | {
1379 | return _dateTime;
1380 | }
1381 |
1382 | ///
1383 | /// تبدیل به تاریخ هجری قمری
1384 | ///
1385 | public HijriDateTime ToHijri(int hijriAdjustment = 0)
1386 | {
1387 | var hijriCalendar = new HijriCalendar
1388 | {
1389 | HijriAdjustment = hijriAdjustment
1390 | };
1391 | var month = hijriCalendar.GetMonth(_dateTime);
1392 | var monthName = "";
1393 | switch (month)
1394 | {
1395 | case 1:
1396 | monthName = "محرم";
1397 | break;
1398 | case 2:
1399 | monthName = "صفر";
1400 | break;
1401 | case 3:
1402 | monthName = "ربیع الاول";
1403 | break;
1404 | case 4:
1405 | monthName = "ربیع الثانی";
1406 | break;
1407 | case 5:
1408 | monthName = "جمادل الاولی";
1409 | break;
1410 | case 6:
1411 | monthName = "جمادی الاخره";
1412 | break;
1413 | case 7:
1414 | monthName = "رجب";
1415 | break;
1416 | case 8:
1417 | monthName = "شعبان";
1418 | break;
1419 | case 9:
1420 | monthName = "رمضان";
1421 | break;
1422 | case 10:
1423 | monthName = "شوال";
1424 | break;
1425 | case 11:
1426 | monthName = "ذوالقعده";
1427 | break;
1428 | case 12:
1429 | monthName = "ذوالحجه";
1430 | break;
1431 | }
1432 | return new HijriDateTime
1433 | {
1434 | Day = hijriCalendar.GetDayOfMonth(_dateTime),
1435 | Month = month,
1436 | Year = hijriCalendar.GetYear(_dateTime),
1437 | MonthName = monthName
1438 | };
1439 | }
1440 |
1441 | ///
1442 | /// کم کردن دو تاریخ از هم
1443 | ///
1444 | public TimeSpan Subtract(PersianDateTime persianDateTime)
1445 | {
1446 | return _dateTime - persianDateTime.ToDateTime();
1447 | }
1448 |
1449 | ///
1450 | /// تعداد ماه اختلافی با تاریخ دیگری را بر میگرداند
1451 | ///
1452 | /// تعداد ماه
1453 | public int MonthDifference(DateTime dateTime)
1454 | {
1455 | return Math.Abs(dateTime.Month - _dateTime.Month + 12 * (dateTime.Year - _dateTime.Year));
1456 | }
1457 |
1458 | ///
1459 | /// اضافه کردن مدت زمانی به تاریخ
1460 | ///
1461 | public PersianDateTime Add(TimeSpan timeSpan)
1462 | {
1463 | return new PersianDateTime(_dateTime.Add(timeSpan), PersianNumber);
1464 | }
1465 |
1466 | ///
1467 | /// اضافه کردن سال به تاریخ
1468 | ///
1469 | public PersianDateTime AddYears(int years)
1470 | {
1471 | return new PersianDateTime(PersianCalendar.AddYears(_dateTime, years), PersianNumber);
1472 | }
1473 |
1474 | ///
1475 | /// اضافه کردن روز به تاریخ
1476 | ///
1477 | public PersianDateTime AddDays(int days)
1478 | {
1479 | return new PersianDateTime(PersianCalendar.AddDays(_dateTime, days), PersianNumber);
1480 | }
1481 |
1482 | ///
1483 | /// اضافه کردن ماه به تاریخ
1484 | ///
1485 | public PersianDateTime AddMonths(int months)
1486 | {
1487 | return new PersianDateTime(PersianCalendar.AddMonths(_dateTime, months), PersianNumber);
1488 | }
1489 |
1490 | ///
1491 | /// اضافه کردن ساعت به تاریخ
1492 | ///
1493 | public PersianDateTime AddHours(int hours)
1494 | {
1495 | return new PersianDateTime(_dateTime.AddHours(hours), PersianNumber);
1496 | }
1497 |
1498 | ///
1499 | /// اضافه کردن دقیقه به تاریخ
1500 | ///
1501 | public PersianDateTime AddMinutes(int minutes)
1502 | {
1503 | return new PersianDateTime(_dateTime.AddMinutes(minutes), PersianNumber);
1504 | }
1505 |
1506 | ///
1507 | /// اضافه کردن ثانیه به تاریخ
1508 | ///
1509 | public PersianDateTime AddSeconds(int seconds)
1510 | {
1511 | return new PersianDateTime(_dateTime.AddSeconds(seconds), PersianNumber);
1512 | }
1513 |
1514 | ///
1515 | /// اضافه کردن میلی ثانیه به تاریخ
1516 | ///
1517 | public PersianDateTime AddMilliseconds(int milliseconds)
1518 | {
1519 | return new PersianDateTime(_dateTime.AddMilliseconds(milliseconds), PersianNumber);
1520 | }
1521 |
1522 | ///
1523 | /// بدست آوردن تاریخ شمسی اولین روز هفته
1524 | ///
1525 | public PersianDateTime GetFirstDayOfWeek()
1526 | {
1527 | var persianDateTime = new PersianDateTime(_dateTime).Date;
1528 | return persianDateTime.AddDays(PersianDayOfWeek.Saturday - persianDateTime.PersianDayOfWeek);
1529 | }
1530 |
1531 | ///
1532 | /// بدست آوردن تاریخ شمسی آخرین روز هفته
1533 | ///
1534 | public PersianDateTime GetPersianWeekend()
1535 | {
1536 | var persianDateTime = new PersianDateTime(_dateTime).Date;
1537 | return persianDateTime.AddDays(PersianDayOfWeek.Friday - persianDateTime.PersianDayOfWeek);
1538 | }
1539 |
1540 | ///
1541 | /// نام فارسی ماه بر اساس شماره ماه
1542 | ///
1543 | /// نام فارسی ماه
1544 | public static string GetPersianMonthName(int monthNumber)
1545 | {
1546 | return GetPersianMonthNamePrivate(monthNumber);
1547 | }
1548 |
1549 | private static string ToPersianNumber(string input)
1550 | {
1551 | if (string.IsNullOrEmpty(input)) return null;
1552 | input = input.Replace("ي", "ی").Replace("ك", "ک");
1553 |
1554 | //۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹
1555 | return
1556 | input
1557 | .Replace("0", "۰")
1558 | .Replace("1", "۱")
1559 | .Replace("2", "۲")
1560 | .Replace("3", "۳")
1561 | .Replace("4", "۴")
1562 | .Replace("5", "۵")
1563 | .Replace("6", "۶")
1564 | .Replace("7", "۷")
1565 | .Replace("8", "۸")
1566 | .Replace("9", "۹");
1567 | }
1568 |
1569 | private static string ToEnglishNumber(string input)
1570 | {
1571 | if (string.IsNullOrEmpty(input)) return null;
1572 | input = input.Replace("ي", "ی").Replace("ك", "ک");
1573 |
1574 | //۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹
1575 | return input
1576 | .Replace(",", "")
1577 | .Replace("۰", "0")
1578 | .Replace("۱", "1")
1579 | .Replace("۲", "2")
1580 | .Replace("۳", "3")
1581 | .Replace("۴", "4")
1582 | .Replace("۵", "5")
1583 | .Replace("۶", "6")
1584 | .Replace("۷", "7")
1585 | .Replace("۸", "8")
1586 | .Replace("۹", "9");
1587 | }
1588 |
1589 | private static string GetPersianMonthNamePrivate(int monthNumber)
1590 | {
1591 | var monthName = "";
1592 | switch (monthNumber)
1593 | {
1594 | case 1:
1595 | monthName = "فروردین";
1596 | break;
1597 |
1598 | case 2:
1599 | monthName = "اردیبهشت";
1600 | break;
1601 |
1602 | case 3:
1603 | monthName = "خرداد";
1604 | break;
1605 |
1606 | case 4:
1607 | monthName = "تیر";
1608 | break;
1609 |
1610 | case 5:
1611 | monthName = "مرداد";
1612 | break;
1613 |
1614 | case 6:
1615 | monthName = "شهریور";
1616 | break;
1617 |
1618 | case 7:
1619 | monthName = "مهر";
1620 | break;
1621 |
1622 | case 8:
1623 | monthName = "آبان";
1624 | break;
1625 |
1626 | case 9:
1627 | monthName = "آذر";
1628 | break;
1629 |
1630 | case 10:
1631 | monthName = "دی";
1632 | break;
1633 |
1634 | case 11:
1635 | monthName = "بهمن";
1636 | break;
1637 |
1638 | case 12:
1639 | monthName = "اسفند";
1640 | break;
1641 | }
1642 | return monthName;
1643 | }
1644 |
1645 | #endregion
1646 |
1647 | #region GetDifferentMonths Base On Seasons
1648 |
1649 | ///
1650 | /// ماه های مرتبط با یک فصل را برمی گرداند
1651 | ///
1652 | private static int[] GetSeasonMonths(int month)
1653 | {
1654 | switch (month)
1655 | {
1656 | case 1:
1657 | case 2:
1658 | case 3:
1659 | return [1, 2, 3];
1660 | case 4:
1661 | case 5:
1662 | case 6:
1663 | return [4, 5, 6];
1664 | case 7:
1665 | case 8:
1666 | case 9:
1667 | return [7, 8, 9];
1668 | case 10:
1669 | case 11:
1670 | case 12:
1671 | return [10, 11, 12];
1672 | }
1673 | throw new Exception($"month {month} is not valid to GetFirstQuarterMonths");
1674 | }
1675 | private static Dictionary GetSeasons(int[] firstSeasonMonths)
1676 | {
1677 | var quarter = 1;
1678 | var quarterDictionary = new Dictionary { { quarter, firstSeasonMonths } };
1679 | var li = firstSeasonMonths;
1680 | var dd = firstSeasonMonths[0];
1681 | while (dd != 10)
1682 | {
1683 | var temp = firstSeasonMonths.Select(du => du + 3).ToArray();
1684 | quarter += 1;
1685 | quarterDictionary.Add(quarter, temp);
1686 | firstSeasonMonths = temp;
1687 | dd = firstSeasonMonths[0];
1688 | }
1689 | dd = 1;
1690 | while (dd != li[0])
1691 | {
1692 | var temp = new[] { dd, dd + 1, dd + 2 };
1693 | quarter += 1;
1694 | quarterDictionary.Add(quarter, temp);
1695 | firstSeasonMonths = temp;
1696 | dd = firstSeasonMonths.Last() + 1;
1697 | }
1698 |
1699 | return quarterDictionary;
1700 | }
1701 |
1702 | ///
1703 | /// اختلاف بین دو تاریخ بر حسب فصول
1704 | ///
1705 | public int GetDifferenceQuarter(DateTime targetDateTime)
1706 | {
1707 | var biggerDateTime = targetDateTime;
1708 | var lesserDateTime = _dateTime;
1709 | if (_dateTime > targetDateTime)
1710 | {
1711 | var tmp = biggerDateTime;
1712 | biggerDateTime = _dateTime;
1713 | lesserDateTime = tmp;
1714 | }
1715 | var diffMonth = (biggerDateTime.Year - lesserDateTime.Year) * 12 + biggerDateTime.Month - lesserDateTime.Month;
1716 | var firstQuarter = GetSeasonMonths(lesserDateTime.Month);
1717 | var seasons = GetSeasons(firstQuarter);
1718 | if (diffMonth < 12) return seasons.First(p => p.Value.Contains(biggerDateTime.Month)).Key;
1719 | var diffYear = diffMonth / 12;
1720 | var diffQuarter = diffMonth - diffYear * 12;
1721 | return diffYear * 4 + diffQuarter / 3 + 1;
1722 | }
1723 |
1724 | #endregion
1725 |
1726 | #region IConvertible
1727 |
1728 | ///
1729 | public TypeCode GetTypeCode()
1730 | {
1731 | return TypeCode.DateTime;
1732 | }
1733 |
1734 | ///
1735 | public bool ToBoolean(IFormatProvider provider)
1736 | {
1737 | return _dateTime > DateTime.MinValue;
1738 | }
1739 |
1740 | ///
1741 | public byte ToByte(IFormatProvider provider)
1742 | {
1743 | throw new InvalidCastException();
1744 | }
1745 |
1746 | ///
1747 | public char ToChar(IFormatProvider provider)
1748 | {
1749 | throw new InvalidCastException();
1750 | }
1751 |
1752 | ///
1753 | public DateTime ToDateTime(IFormatProvider provider)
1754 | {
1755 | return _dateTime;
1756 | }
1757 |
1758 | ///
1759 | public decimal ToDecimal(IFormatProvider provider)
1760 | {
1761 | return ToLongDateTimeInt();
1762 | }
1763 |
1764 | ///
1765 | public double ToDouble(IFormatProvider provider)
1766 | {
1767 | return ToLongDateTimeInt();
1768 | }
1769 |
1770 | ///
1771 | public short ToInt16(IFormatProvider provider)
1772 | {
1773 | throw new InvalidCastException();
1774 | }
1775 |
1776 | ///
1777 | public int ToInt32(IFormatProvider provider)
1778 | {
1779 | return ToShortDateInt();
1780 | }
1781 |
1782 | ///
1783 | public long ToInt64(IFormatProvider provider)
1784 | {
1785 | return ToLongDateTimeInt();
1786 | }
1787 |
1788 | ///
1789 | public sbyte ToSByte(IFormatProvider provider)
1790 | {
1791 | throw new InvalidCastException();
1792 | }
1793 |
1794 | ///
1795 | public float ToSingle(IFormatProvider provider)
1796 | {
1797 | throw new InvalidCastException();
1798 | }
1799 |
1800 | ///
1801 | public string ToString(IFormatProvider provider)
1802 | {
1803 | return ToString("", provider);
1804 | }
1805 |
1806 | ///
1807 | public object ToType(Type conversionType, IFormatProvider provider)
1808 | {
1809 | switch (Type.GetTypeCode(conversionType))
1810 | {
1811 | case TypeCode.Boolean:
1812 | return ToBoolean(provider);
1813 | case TypeCode.Byte:
1814 | return ToByte(provider);
1815 | case TypeCode.Char:
1816 | return ToChar(provider);
1817 | case TypeCode.DateTime:
1818 | return ToDateTime(provider);
1819 | case TypeCode.Decimal:
1820 | return ToDecimal(provider);
1821 | case TypeCode.Double:
1822 | return ToDouble(provider);
1823 | case TypeCode.Int16:
1824 | return ToInt16(provider);
1825 | case TypeCode.Int32:
1826 | return ToInt32(provider);
1827 | case TypeCode.Int64:
1828 | return ToInt64(provider);
1829 | case TypeCode.Object:
1830 | if (typeof(PersianDateTime) == conversionType)
1831 | return this;
1832 | if (typeof(DateTime) == conversionType)
1833 | return ToDateTime();
1834 | throw new InvalidCastException($"Conversion to a {conversionType.Name} is not supported.");
1835 | case TypeCode.SByte:
1836 | return ToSByte(provider);
1837 | case TypeCode.Single:
1838 | return ToSingle(provider);
1839 | case TypeCode.String:
1840 | return ToString(provider);
1841 | case TypeCode.UInt16:
1842 | return ToUInt16(provider);
1843 | case TypeCode.UInt32:
1844 | return ToUInt32(provider);
1845 | case TypeCode.UInt64:
1846 | return ToUInt64(provider);
1847 | case TypeCode.DBNull:
1848 | break;
1849 | case TypeCode.Empty:
1850 | break;
1851 | default:
1852 | throw new InvalidCastException($"Conversion to {conversionType.Name} is not supported.");
1853 | }
1854 | throw new InvalidCastException();
1855 | }
1856 |
1857 | ///
1858 | public ushort ToUInt16(IFormatProvider provider)
1859 | {
1860 | throw new InvalidCastException();
1861 | }
1862 |
1863 | ///
1864 | public uint ToUInt32(IFormatProvider provider)
1865 | {
1866 | return (uint)ToShortDateInt();
1867 | }
1868 |
1869 | ///
1870 | public ulong ToUInt64(IFormatProvider provider)
1871 | {
1872 | return (ulong)ToLongDateTimeInt();
1873 | }
1874 |
1875 | #endregion
1876 | }
--------------------------------------------------------------------------------
/MD.PersianDateTime/PersianDateTime.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Runtime.Serialization;
5 | using System.Text.RegularExpressions;
6 |
7 | // ReSharper disable UnusedMember.Local
8 |
9 | namespace MD.PersianDateTime
10 | {
11 | ///
12 | /// Created By Mohammad Dayyan, @mdssoft, mds_soft@yahoo.com
13 | /// 1393/09/14
14 | ///
15 | [Serializable]
16 | public struct PersianDateTime :
17 | ISerializable, IFormattable, IConvertible,
18 | IComparable, IComparable,
19 | IEquatable, IEquatable
20 | {
21 | #region properties and fields
22 |
23 | private static PersianCalendar _persianCalendar;
24 | private static PersianCalendar PersianCalendar
25 | {
26 | get
27 | {
28 | if (_persianCalendar != null) return _persianCalendar;
29 | _persianCalendar = new PersianCalendar();
30 | return _persianCalendar;
31 | }
32 | }
33 | private readonly DateTime _dateTime;
34 |
35 | ///
36 | /// آیا اعداد در خروجی به صورت فارسی نمایش داده شوند؟
37 | ///
38 | public bool PersianNumber { get; set; }
39 |
40 | ///
41 | /// سال شمسی
42 | ///
43 | public int Year
44 | {
45 | get
46 | {
47 | if (_dateTime <= DateTime.MinValue) return DateTime.MinValue.Year;
48 | return PersianCalendar.GetYear(_dateTime);
49 | }
50 | }
51 |
52 | ///
53 | /// ماه شمسی
54 | ///
55 | public int Month
56 | {
57 | get
58 | {
59 | if (_dateTime <= DateTime.MinValue) return DateTime.MinValue.Month;
60 | return PersianCalendar.GetMonth(_dateTime);
61 | }
62 | }
63 |
64 | ///
65 | /// نام فارسی ماه
66 | ///
67 | public string MonthName => ((PersianDateTimeMonthEnum)Month).ToString();
68 |
69 | ///
70 | /// روز ماه
71 | ///
72 | public int Day
73 | {
74 | get
75 | {
76 | if (_dateTime <= DateTime.MinValue) return DateTime.MinValue.Day;
77 | return PersianCalendar.GetDayOfMonth(_dateTime);
78 | }
79 | }
80 |
81 | ///
82 | /// روز هفته
83 | ///
84 | public DayOfWeek DayOfWeek
85 | {
86 | get
87 | {
88 | if (_dateTime <= DateTime.MinValue) return DateTime.MinValue.DayOfWeek;
89 | return PersianCalendar.GetDayOfWeek(_dateTime);
90 | }
91 | }
92 |
93 | ///
94 | /// روز هفته یا ایندکس شمسی
95 | ///
96 | /// شنبه دارای ایندکس صفر است
97 | ///
98 | public PersianDayOfWeek PersianDayOfWeek
99 | {
100 | get
101 | {
102 | var dayOfWeek = PersianCalendar.GetDayOfWeek(_dateTime);
103 | PersianDayOfWeek persianDayOfWeek;
104 | switch (dayOfWeek)
105 | {
106 | case DayOfWeek.Sunday:
107 | persianDayOfWeek = PersianDayOfWeek.Sunday;
108 | break;
109 | case DayOfWeek.Monday:
110 | persianDayOfWeek = PersianDayOfWeek.Monday;
111 | break;
112 | case DayOfWeek.Tuesday:
113 | persianDayOfWeek = PersianDayOfWeek.Tuesday;
114 | break;
115 | case DayOfWeek.Wednesday:
116 | persianDayOfWeek = PersianDayOfWeek.Wednesday;
117 | break;
118 | case DayOfWeek.Thursday:
119 | persianDayOfWeek = PersianDayOfWeek.Thursday;
120 | break;
121 | case DayOfWeek.Friday:
122 | persianDayOfWeek = PersianDayOfWeek.Friday;
123 | break;
124 | case DayOfWeek.Saturday:
125 | persianDayOfWeek = PersianDayOfWeek.Saturday;
126 | break;
127 | default:
128 | throw new ArgumentOutOfRangeException();
129 | }
130 | return persianDayOfWeek;
131 | }
132 | }
133 |
134 | ///
135 | /// ساعت
136 | ///
137 | public int Hour
138 | {
139 | get
140 | {
141 | if (_dateTime <= DateTime.MinValue) return 12;
142 | return PersianCalendar.GetHour(_dateTime);
143 | }
144 | }
145 |
146 | ///
147 | /// ساعت دو رقمی
148 | ///
149 | public int ShortHour
150 | {
151 | get
152 | {
153 | int shortHour;
154 | if (Hour > 12)
155 | shortHour = Hour - 12;
156 | else
157 | shortHour = Hour;
158 | return shortHour;
159 | }
160 | }
161 |
162 | ///
163 | /// دقیقه
164 | ///
165 | public int Minute
166 | {
167 | get
168 | {
169 | if (_dateTime <= DateTime.MinValue) return 0;
170 | return PersianCalendar.GetMinute(_dateTime);
171 | }
172 | }
173 |
174 | ///
175 | /// ثانیه
176 | ///
177 | public int Second
178 | {
179 | get
180 | {
181 | if (_dateTime <= DateTime.MinValue) return 0;
182 | return PersianCalendar.GetSecond(_dateTime);
183 | }
184 | }
185 |
186 | ///
187 | /// میلی ثانیه
188 | ///
189 | public int Millisecond
190 | {
191 | get
192 | {
193 | if (_dateTime <= DateTime.MinValue) return 0;
194 | return (int)PersianCalendar.GetMilliseconds(_dateTime);
195 | }
196 | }
197 |
198 | ///
199 | /// تعداد روز در ماه
200 | ///
201 | public int GetMonthDays
202 | {
203 | get
204 | {
205 | int days;
206 | switch (Month)
207 | {
208 | case 1:
209 | case 2:
210 | case 3:
211 | case 4:
212 | case 5:
213 | case 6:
214 | days = 31;
215 | break;
216 |
217 | case 7:
218 | case 8:
219 | case 9:
220 | case 10:
221 | case 11:
222 | days = 30;
223 | break;
224 |
225 | case 12:
226 | {
227 | if (IsLeapYear) days = 30;
228 | else days = 29;
229 | break;
230 | }
231 |
232 | default:
233 | throw new Exception("Month number is wrong !!!");
234 | }
235 | return days;
236 | }
237 | }
238 |
239 | ///
240 | /// هفته چندم سال
241 | ///
242 | public int GetWeekOfYear
243 | {
244 | get
245 | {
246 | if (_dateTime <= DateTime.MinValue) return 0;
247 | return PersianCalendar.GetWeekOfYear(_dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Saturday);
248 | }
249 | }
250 |
251 | ///
252 | /// هفته چندم ماه
253 | ///
254 | public int GetWeekOfMonth
255 | {
256 | get
257 | {
258 | if (_dateTime <= DateTime.MinValue) return 0;
259 | var persianDateTime = AddDays(1 - Day);
260 | return GetWeekOfYear - persianDateTime.GetWeekOfYear + 1;
261 | }
262 | }
263 |
264 | ///
265 | /// روز چندم سال
266 | ///
267 | public int GetDayOfYear
268 | {
269 | get
270 | {
271 | if (_dateTime <= DateTime.MinValue) return 0;
272 | return PersianCalendar.GetDayOfYear(_dateTime);
273 | }
274 | }
275 |
276 | ///
277 | /// آیا سال کبیسه است؟
278 | ///
279 | public bool IsLeapYear
280 | {
281 | get
282 | {
283 | if (_dateTime <= DateTime.MinValue) return false;
284 | return PersianCalendar.IsLeapYear(Year);
285 | }
286 | }
287 |
288 | ///
289 | /// قبل از ظهر، بعد از ظهر
290 | ///
291 | private AmPmEnum PersianAmPm => _dateTime.ToString("tt", CultureInfo.InvariantCulture) == "PM" ? AmPmEnum.PM : AmPmEnum.AM;
292 |
293 | ///
294 | /// قبل از ظهر، بعد از ظهر به شکل مخفف . کوتاه
295 | ///
296 | public string GetPersianAmPm
297 | {
298 | get
299 | {
300 | var result = string.Empty;
301 | switch (PersianAmPm)
302 | {
303 | case AmPmEnum.AM:
304 | result = "ق.ظ";
305 | break;
306 |
307 | case AmPmEnum.PM:
308 | result = "ب.ظ";
309 | break;
310 | }
311 | return result;
312 | }
313 | }
314 |
315 | ///
316 | /// نام کامل ماه
317 | ///
318 | public string GetLongMonthName => GetPersianMonthNamePrivate(Month);
319 |
320 | ///
321 | /// سال دو رقمی
322 | ///
323 | public int GetShortYear => Year % 100;
324 |
325 | ///
326 | /// نام کامل روز
327 | ///
328 | public string GetLongDayOfWeekName
329 | {
330 | get
331 | {
332 | string weekDayName = null;
333 | switch (DayOfWeek)
334 | {
335 | case DayOfWeek.Sunday:
336 | weekDayName = PersianWeekDaysStruct.یکشنبه.Value;
337 | break;
338 |
339 | case DayOfWeek.Monday:
340 | weekDayName = PersianWeekDaysStruct.دوشنبه.Value;
341 | break;
342 |
343 | case DayOfWeek.Tuesday:
344 | weekDayName = PersianWeekDaysStruct.سه_شنبه.Value;
345 | break;
346 |
347 | case DayOfWeek.Wednesday:
348 | weekDayName = PersianWeekDaysStruct.چهارشنبه.Value;
349 | break;
350 |
351 | case DayOfWeek.Thursday:
352 | weekDayName = PersianWeekDaysStruct.پنجشنبه.Value;
353 | break;
354 |
355 | case DayOfWeek.Friday:
356 | weekDayName = PersianWeekDaysStruct.جمعه.Value;
357 | break;
358 |
359 | case DayOfWeek.Saturday:
360 | weekDayName = PersianWeekDaysStruct.شنبه.Value;
361 | break;
362 | }
363 | return weekDayName;
364 | }
365 | }
366 |
367 | ///
368 | /// نام یک حرفی روز، حرف اول روز
369 | ///
370 | public string GetShortDayOfWeekName
371 | {
372 | get
373 | {
374 | string weekDayName = null;
375 | switch (DayOfWeek)
376 | {
377 | case DayOfWeek.Sunday:
378 | weekDayName = "ی";
379 | break;
380 |
381 | case DayOfWeek.Monday:
382 | weekDayName = "د";
383 | break;
384 |
385 | case DayOfWeek.Tuesday:
386 | weekDayName = "س";
387 | break;
388 |
389 | case DayOfWeek.Wednesday:
390 | weekDayName = "چ";
391 | break;
392 |
393 | case DayOfWeek.Thursday:
394 | weekDayName = "پ";
395 | break;
396 |
397 | case DayOfWeek.Friday:
398 | weekDayName = "ج";
399 | break;
400 |
401 | case DayOfWeek.Saturday:
402 | weekDayName = "ش";
403 | break;
404 | }
405 |
406 | return weekDayName;
407 | }
408 | }
409 |
410 | ///
411 | /// تاریخ و زمان همین الان
412 | ///
413 | public static PersianDateTime Now => new PersianDateTime(DateTime.Now);
414 |
415 | ///
416 | /// تاریخ امروز
417 | ///
418 | public static PersianDateTime Today => new PersianDateTime(DateTime.Today);
419 |
420 | ///
421 | /// زمان به فرمتی مشابه
422 | ///
423 | /// 13:47:40:530
424 | ///
425 | public string TimeOfDay
426 | {
427 | get
428 | {
429 | var result = $"{Hour:00}:{Minute:00}:{Second:00}:{Millisecond:000}";
430 | if (!PersianNumber) return result;
431 | return ToPersianNumber(result);
432 | }
433 | }
434 |
435 | ///
436 | /// زمان به فرمتی مشابه زیر
437 | ///
438 | /// ساعت 01:47:40:530 ب.ظ
439 | ///
440 | public string LongTimeOfDay
441 | {
442 | get
443 | {
444 | var result = $"ساعت {ShortHour:00}:{Minute:00}:{Second:00}:{Millisecond:000} {GetPersianAmPm}";
445 | if (!PersianNumber) return result;
446 | return ToPersianNumber(result);
447 | }
448 | }
449 |
450 | ///
451 | /// زمان به فرمتی مشابه زیر
452 | ///
453 | /// 01:47:40 ب.ظ
454 | ///
455 | public string ShortTimeOfDay
456 | {
457 | get
458 | {
459 | var result = $"{ShortHour:00}:{Minute:00}:{Second:00} {GetPersianAmPm}";
460 | if (!PersianNumber) return result;
461 | return ToPersianNumber(result);
462 | }
463 | }
464 |
465 | ///
466 | /// تاریخ بدون احتساب زمان
467 | ///
468 | public PersianDateTime Date
469 | {
470 | get
471 | {
472 | var persianDateTime = new PersianDateTime(Year, Month, Day)
473 | {
474 | PersianNumber = PersianNumber
475 | };
476 | return persianDateTime;
477 | }
478 | }
479 |
480 | ///
481 | /// حداقل مقدار
482 | ///
483 | public static PersianDateTime MinValue => new PersianDateTime(DateTime.MinValue);
484 |
485 | ///
486 | /// حداکثر مقدار
487 | ///
488 | public static PersianDateTime MaxValue => new PersianDateTime(DateTime.MaxValue);
489 |
490 | #endregion
491 |
492 | #region ctor
493 |
494 | ///
495 | /// متد سازنده برای دی سریالایز شدن
496 | ///
497 | private PersianDateTime(SerializationInfo info, StreamingContext context)
498 | : this()
499 | {
500 | _dateTime = info.GetDateTime("DateTime");
501 | PersianNumber = info.GetBoolean("PersianNumber");
502 | }
503 |
504 | ///
505 | /// مقدار دهی اولیه با استفاده از دیت تایم میلادی
506 | ///
507 | /// DateTime
508 | /// آیا اعداد در خروجی های این آبجکت به صورت فارسی نمایش داده شوند یا فارسی؟
509 | private PersianDateTime(DateTime dateTime, bool persianNumber)
510 | : this()
511 | {
512 | _dateTime = dateTime;
513 | PersianNumber = persianNumber;
514 | }
515 |
516 | ///
517 | /// مقدار دهی اولیه با استفاده از دیت تایم میلادی
518 | ///
519 | public PersianDateTime(DateTime dateTime)
520 | : this()
521 | {
522 | _dateTime = dateTime;
523 | }
524 |
525 | ///
526 | /// مقدار دهی اولیه با استفاده از دیت تایم قابل نال میلادی
527 | ///
528 | public PersianDateTime(DateTime? nullableDateTime)
529 | : this()
530 | {
531 | if (!nullableDateTime.HasValue)
532 | {
533 | _dateTime = DateTime.MinValue;
534 | return;
535 | }
536 | _dateTime = nullableDateTime.Value;
537 | }
538 |
539 | ///
540 | /// مقدار دهی اولیه
541 | ///
542 | /// سال شمسی
543 | /// ماه شمسی
544 | /// روز شمسی
545 | public PersianDateTime(int persianYear, int persianMonth, int persianDay)
546 | : this()
547 | {
548 | _dateTime = PersianCalendar.ToDateTime(persianYear, persianMonth, persianDay, 0, 0, 0, 0);
549 | }
550 |
551 | ///
552 | /// مقدار دهی اولیه
553 | ///
554 | /// سال شمسی
555 | /// ماه شمسی
556 | /// روز شمسی
557 | /// ساعت
558 | /// دقیقه
559 | /// ثانیه
560 | public PersianDateTime(int persianYear, int persianMonth, int persianDay, int hour, int minute, int second)
561 | : this()
562 | {
563 | _dateTime = PersianCalendar.ToDateTime(persianYear, persianMonth, persianDay, hour, minute, second, 0);
564 | }
565 |
566 | ///
567 | /// مقدار دهی اولیه
568 | ///
569 | /// سال شمسی
570 | /// ماه شمسی
571 | /// روز شمسی
572 | /// سال
573 | /// دقیقه
574 | /// ثانیه
575 | /// میلی ثانیه
576 | public PersianDateTime(int persianYear, int persianMonth, int persianDay, int hour, int minute, int second, int millisecond)
577 | : this()
578 | {
579 | _dateTime = PersianCalendar.ToDateTime(persianYear, persianMonth, persianDay, hour, minute, second, millisecond);
580 | }
581 |
582 | #endregion
583 |
584 | #region Types
585 |
586 | private enum AmPmEnum
587 | {
588 | AM = 0,
589 | PM = 1,
590 | None = 2
591 | }
592 |
593 | private enum PersianDateTimeMonthEnum
594 | {
595 | فروردین = 1,
596 | اردیبهشت = 2,
597 | خرداد = 3,
598 | تیر = 4,
599 | مرداد = 5,
600 | شهریور = 6,
601 | مهر = 7,
602 | آبان = 8,
603 | آذر = 9,
604 | دی = 10,
605 | بهمن = 11,
606 | اسفند = 12
607 | }
608 |
609 | private struct PersianWeekDaysStruct
610 | {
611 | public static KeyValuePair شنبه => new KeyValuePair((int)DayOfWeek.Saturday, "شنبه");
612 | public static KeyValuePair یکشنبه => new KeyValuePair((int)DayOfWeek.Sunday, "یکشنبه");
613 | public static KeyValuePair دوشنبه => new KeyValuePair((int)DayOfWeek.Monday, "دوشنبه");
614 | public static KeyValuePair سه_شنبه => new KeyValuePair((int)DayOfWeek.Tuesday, "سه شنبه");
615 | public static KeyValuePair چهارشنبه => new KeyValuePair((int)DayOfWeek.Thursday, "چهارشنبه");
616 | public static KeyValuePair پنجشنبه => new KeyValuePair((int)DayOfWeek.Wednesday, "پنج شنبه");
617 | public static KeyValuePair جمعه => new KeyValuePair((int)DayOfWeek.Friday, "جمعه");
618 | }
619 |
620 | #endregion
621 |
622 | #region override
623 |
624 | ///
625 | /// تبدیل تاریخ به رشته با فرمت مشابه زیر
626 | ///
627 | /// 1393/09/14 13:49:40
628 | ///
629 | public override string ToString()
630 | {
631 | return ToString("");
632 | }
633 |
634 | ///
635 | public override bool Equals(object obj)
636 | {
637 | if (!(obj is PersianDateTime)) return false;
638 | var persianDateTime = (PersianDateTime)obj;
639 | return _dateTime == persianDateTime.ToDateTime();
640 | }
641 |
642 | ///
643 | public override int GetHashCode()
644 | {
645 | return _dateTime.GetHashCode();
646 | }
647 |
648 | ///
649 | /// مقایسه با تاریخ دیگر
650 | ///
651 | /// مقدار بازگشتی همانند مقدار بازگشتی متد کامپیر در دیت تایم دات نت است
652 | public int CompareTo(PersianDateTime otherPersianDateTime)
653 | {
654 | return _dateTime.CompareTo(otherPersianDateTime.ToDateTime());
655 | }
656 |
657 | ///
658 | /// مقایسه با تاریخ دیگر
659 | ///
660 | /// مقدار بازگشتی همانند مقدار بازگشتی متد کامپیر در دیت تایم دات نت است
661 | public int CompareTo(DateTime otherDateTime)
662 | {
663 | return _dateTime.CompareTo(otherDateTime);
664 | }
665 |
666 | #region operators
667 |
668 | ///
669 | /// تبدیل خودکار به دیت تایم میلادی
670 | ///
671 | public static implicit operator DateTime(PersianDateTime persianDateTime)
672 | {
673 | return persianDateTime.ToDateTime();
674 | }
675 |
676 | ///
677 | /// اپراتور برابر
678 | ///
679 | public static bool operator ==(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
680 | {
681 | return persianDateTime1.Equals(persianDateTime2);
682 | }
683 |
684 | ///
685 | /// اپراتور نامساوی
686 | ///
687 | public static bool operator !=(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
688 | {
689 | return !persianDateTime1.Equals(persianDateTime2);
690 | }
691 |
692 | ///
693 | /// اپراتور بزرگتری
694 | ///
695 | public static bool operator >(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
696 | {
697 | return persianDateTime1.ToDateTime() > persianDateTime2.ToDateTime();
698 | }
699 |
700 | ///
701 | /// اپراتور کوچکتری
702 | ///
703 | public static bool operator <(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
704 | {
705 | return persianDateTime1.ToDateTime() < persianDateTime2.ToDateTime();
706 | }
707 |
708 | ///
709 | /// اپراتور بزرگتر مساوی
710 | ///
711 | public static bool operator >=(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
712 | {
713 | return persianDateTime1.ToDateTime() >= persianDateTime2.ToDateTime();
714 | }
715 |
716 | ///
717 | /// اپراتور کوچکتر مساوی
718 | ///
719 | public static bool operator <=(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
720 | {
721 | return persianDateTime1.ToDateTime() <= persianDateTime2.ToDateTime();
722 | }
723 |
724 | ///
725 | /// اپراتور جمع تو زمان
726 | ///
727 | public static PersianDateTime operator +(PersianDateTime persianDateTime1, TimeSpan timeSpanToAdd)
728 | {
729 | DateTime dateTime1 = persianDateTime1;
730 | return new PersianDateTime(dateTime1.Add(timeSpanToAdd));
731 | }
732 |
733 | ///
734 | /// اپراتور کم کردن دو زمان از هم
735 | ///
736 | public static TimeSpan operator -(PersianDateTime persianDateTime1, PersianDateTime persianDateTime2)
737 | {
738 | DateTime dateTime1 = persianDateTime1;
739 | DateTime dateTime2 = persianDateTime2;
740 | return dateTime1 - dateTime2;
741 | }
742 |
743 | #endregion
744 |
745 | #endregion
746 |
747 | #region ISerializable
748 |
749 | ///
750 | public void GetObjectData(SerializationInfo info, StreamingContext context)
751 | {
752 | info.AddValue("DateTime", ToDateTime());
753 | info.AddValue("PersianNumber", PersianNumber);
754 | }
755 |
756 | #endregion
757 |
758 | #region IComparable
759 |
760 | ///
761 | public bool Equals(PersianDateTime other)
762 | {
763 | return Year == other.Year && Month == other.Month && Day == other.Day &&
764 | Hour == other.Hour && Minute == other.Minute && Second == other.Second && Millisecond == other.Millisecond;
765 | }
766 |
767 | ///
768 | public bool Equals(DateTime other)
769 | {
770 | return _dateTime == other;
771 | }
772 |
773 | #endregion
774 |
775 | #region Methods
776 |
777 | ///
778 | /// تاریخ شروع ماه رمضان
779 | ///
780 | /// چون ممکن است در یک سال شمسی دو شروع ماه رمضان داشته باشیم
781 | ///
782 | /// مقدار بازگشتی آرایه است که حداکثر دو آیتم دارد
783 | ///
784 | public PersianDateTime[] GetStartDayOfRamadan(int hijriAdjustment)
785 | {
786 | var result = new List();
787 | var hijriCalendar = new HijriCalendar { HijriAdjustment = hijriAdjustment };
788 |
789 | var currentHijriYear = hijriCalendar.GetYear(_dateTime);
790 |
791 | var startDayOfRamadan1 = new PersianDateTime(hijriCalendar.ToDateTime(currentHijriYear, 9, 1, 0, 0, 0, 0));
792 | result.Add(startDayOfRamadan1);
793 |
794 | var startDayOfRamadan2 = new PersianDateTime(hijriCalendar.ToDateTime(++currentHijriYear, 9, 1, 0, 0, 0, 0));
795 | if (startDayOfRamadan1.Year == startDayOfRamadan2.Year)
796 | result.Add(startDayOfRamadan2);
797 |
798 | return result.ToArray();
799 | }
800 |
801 | ///
802 | /// تاریخ آخرین روز ماه شمسی
803 | ///
804 | public PersianDateTime GetPersianDateOfLastDayOfMonth()
805 | {
806 | return new PersianDateTime(Year, Month, GetMonthDays);
807 | }
808 |
809 | ///
810 | /// تاریخ آخرین روز سال شمسی
811 | ///
812 | public PersianDateTime GetPersianDateOfLastDayOfYear()
813 | {
814 | return new PersianDateTime(Year, 12, IsLeapYear ? 30 : 29);
815 | }
816 |
817 | ///
818 | /// پارس کردن رشته و تبدیل به نوع PersianDateTime
819 | ///
820 | /// متنی که باید پارس شود
821 | /// کاراکتری که جدا کننده تاریخ ها است
822 | public static PersianDateTime Parse(string persianDateTimeInString, string dateSeparatorPattern = @"\/|-")
823 | {
824 | //Convert persian and arabic digit to english to avoid throwing exception in Parse method
825 | persianDateTimeInString = ExtensionsHelper.ConvertDigitsToLatin(persianDateTimeInString);
826 |
827 | string month = "", year, day,
828 | hour = "0",
829 | minute = "0",
830 | second = "0",
831 | milliseconds = "0";
832 | var amPmEnum = AmPmEnum.None;
833 | var containMonthSeparator = Regex.IsMatch(persianDateTimeInString, dateSeparatorPattern);
834 |
835 | persianDateTimeInString = ToEnglishNumber(persianDateTimeInString.Replace(" ", " ").Replace(" ", "-").Replace("\\", "-"));
836 | persianDateTimeInString = Regex.Replace(persianDateTimeInString, dateSeparatorPattern, "-");
837 | persianDateTimeInString = persianDateTimeInString.Replace("ك", "ک").Replace("ي", "ی");
838 |
839 | persianDateTimeInString = $"-{persianDateTimeInString}-";
840 |
841 | // بدست آوردن ب.ظ یا ق.ظ
842 | if (persianDateTimeInString.IndexOf("ق.ظ", StringComparison.InvariantCultureIgnoreCase) > -1)
843 | amPmEnum = AmPmEnum.AM;
844 | else if (persianDateTimeInString.IndexOf("ب.ظ", StringComparison.InvariantCultureIgnoreCase) > -1)
845 | amPmEnum = AmPmEnum.PM;
846 |
847 | if (persianDateTimeInString.IndexOf(":", StringComparison.InvariantCultureIgnoreCase) > -1) // رشته ورودی شامل ساعت نیز هست
848 | {
849 | persianDateTimeInString = Regex.Replace(persianDateTimeInString, @"-*:-*", ":");
850 | hour = Regex.Match(persianDateTimeInString, @"(?<=-)\d{1,2}(?=:)", RegexOptions.IgnoreCase).Value;
851 | minute = Regex.Match(persianDateTimeInString, @"(?<=-\d{1,2}:)\d{1,2}(?=:?)", RegexOptions.IgnoreCase).Value;
852 | if (persianDateTimeInString.IndexOf(':') != persianDateTimeInString.LastIndexOf(':'))
853 | {
854 | second = Regex.Match(persianDateTimeInString, @"(?<=-\d{1,2}:\d{1,2}:)\d{1,2}(?=(\d{1,2})?)", RegexOptions.IgnoreCase).Value;
855 | milliseconds = Regex.Match(persianDateTimeInString, @"(?<=-\d{1,2}:\d{1,2}:\d{1,2}:)\d{1,4}(?=(\d{1,2})?)", RegexOptions.IgnoreCase).Value;
856 | if (string.IsNullOrEmpty(milliseconds)) milliseconds = "0";
857 | }
858 | }
859 |
860 | if (containMonthSeparator)
861 | {
862 | // بدست آوردن ماه
863 | month = Regex.Match(persianDateTimeInString, @"(?<=\d{2,4}-)\d{1,2}(?=-\d{1,2}-\d{1,2}(?!-\d{1,2}:))", RegexOptions.IgnoreCase).Value;
864 | if (string.IsNullOrEmpty(month))
865 | month = Regex.Match(persianDateTimeInString, @"(?<=\d{2,4}-)\d{1,2}(?=-\d{1,2}[^:])", RegexOptions.IgnoreCase).Value;
866 |
867 | // بدست آوردن روز
868 | day = Regex.Match(persianDateTimeInString, @"(?<=\d{2,4}-\d{1,2}-)\d{1,2}(?=-)", RegexOptions.IgnoreCase).Value;
869 |
870 | // بدست آوردن سال
871 | year = Regex.Match(persianDateTimeInString, @"(?<=-)\d{2,4}(?=-\d{1,2}-\d{1,2})", RegexOptions.IgnoreCase).Value;
872 | }
873 | else
874 | {
875 | foreach (PersianDateTimeMonthEnum item in Enum.GetValues(typeof(PersianDateTimeMonthEnum)))
876 | {
877 | var itemValueInString = item.ToString();
878 | if (!persianDateTimeInString.Contains(itemValueInString)) continue;
879 | month = ((int)item).ToString(CultureInfo.InvariantCulture);
880 | break;
881 | }
882 |
883 | if (string.IsNullOrEmpty(month))
884 | throw new Exception("عدد یا حرف ماه در رشته ورودی وجود ندارد");
885 |
886 | // بدست آوردن روز
887 | var dayMatch = Regex.Match(persianDateTimeInString, @"(?<=-)\d{1,2}(?=-)", RegexOptions.IgnoreCase);
888 | if (dayMatch.Success)
889 | {
890 | day = dayMatch.Value;
891 | persianDateTimeInString = Regex.Replace(persianDateTimeInString, $"(?<=-){day}(?=-)", "");
892 | }
893 | else
894 | throw new Exception("عدد روز در رشته ورودی وجود ندارد");
895 |
896 | // بدست آوردن سال
897 | var yearMatch = Regex.Match(persianDateTimeInString, @"(?<=-)\d{4}(?=-)", RegexOptions.IgnoreCase);
898 | if (yearMatch.Success)
899 | year = yearMatch.Value;
900 | else
901 | {
902 | yearMatch = Regex.Match(persianDateTimeInString, @"(?<=-)\d{2,4}(?=-)", RegexOptions.IgnoreCase);
903 | if (yearMatch.Success)
904 | year = yearMatch.Value;
905 | else
906 | throw new Exception("عدد سال در رشته ورودی وجود ندارد");
907 | }
908 | }
909 |
910 | //if (year.Length <= 2 && year[0] == '9') year = string.Format("13{0}", year);
911 | //else if (year.Length <= 2) year = string.Format("14{0}", year);
912 |
913 | var numericYear = int.Parse(year);
914 | var numericMonth = int.Parse(month);
915 | var numericDay = int.Parse(day);
916 | var numericHour = int.Parse(hour);
917 | var numericMinute = int.Parse(minute);
918 | var numericSecond = int.Parse(second);
919 | var numericMilliseconds = int.Parse(milliseconds);
920 |
921 | if (numericYear < 100)
922 | numericYear += 1300;
923 |
924 | switch (amPmEnum)
925 | {
926 | case AmPmEnum.PM:
927 | if (numericHour < 12)
928 | numericHour = numericHour + 12;
929 | break;
930 | case AmPmEnum.AM:
931 | case AmPmEnum.None:
932 | break;
933 | }
934 |
935 | return new PersianDateTime(numericYear, numericMonth, numericDay, numericHour, numericMinute, numericSecond, numericMilliseconds);
936 | }
937 |
938 | ///
939 | /// پارس کردن یک رشته برای یافتن تاریخ شمسی
940 | ///
941 | public static bool TryParse(string persianDateTimeInString, out PersianDateTime result, string dateSeparatorPattern = @"\/|-")
942 | {
943 | if (string.IsNullOrEmpty(persianDateTimeInString))
944 | {
945 | result = MinValue;
946 | return false;
947 | }
948 | try
949 | {
950 | result = Parse(persianDateTimeInString, dateSeparatorPattern);
951 | return true;
952 | }
953 | catch
954 | {
955 | result = MinValue;
956 | return false;
957 | }
958 | }
959 |
960 | ///
961 | /// پارس کردن عددی در فرمت تاریخ شمسی
962 | ///
963 | /// همانند 13920305
964 | ///
965 | public static PersianDateTime Parse(int numericPersianDate)
966 | {
967 | if (numericPersianDate.ToString(CultureInfo.InvariantCulture).Length != 8)
968 | throw new InvalidCastException("Numeric persian date must have a format like 13920101.");
969 | var year = numericPersianDate / 10000;
970 | var day = numericPersianDate % 100;
971 | var month = numericPersianDate / 100 % 100;
972 | return new PersianDateTime(year, month, day);
973 | }
974 | ///
975 | /// پارس کردن عددی در فرمت تاریخ شمسی
976 | ///
977 | /// همانند 13920305
978 | ///
979 | public static bool TryParse(int numericPersianDate, out PersianDateTime result)
980 | {
981 | try
982 | {
983 | result = Parse(numericPersianDate);
984 | return true;
985 | }
986 | catch
987 | {
988 | result = MinValue;
989 | return false;
990 | }
991 | }
992 |
993 | ///
994 | /// پارس کردن عددی در فرمت تاریخ و زمان شمسی
995 | ///
996 | /// همانند 13961223072132004
997 | ///
998 | public static PersianDateTime Parse(long numericPersianDateTime)
999 | {
1000 | if (numericPersianDateTime.ToString(CultureInfo.InvariantCulture).Length != 17)
1001 | throw new InvalidCastException("Numeric persian date time must have a format like 1396122310223246.");
1002 | var year = numericPersianDateTime / 10000000000000;
1003 | var month = numericPersianDateTime / 100000000000 % 100;
1004 | var day = numericPersianDateTime / 1000000000 % 100;
1005 | var hour = numericPersianDateTime / 10000000 % 100;
1006 | var minute = numericPersianDateTime / 100000 % 100;
1007 | var second = numericPersianDateTime / 1000 % 100;
1008 | var millisecond = numericPersianDateTime % 1000;
1009 | return new PersianDateTime((int)year, (int)month, (int)day, (int)hour, (int)minute, (int)second, (int)millisecond);
1010 | }
1011 | ///
1012 | /// پارس کردن عددی در فرمت تاریخ و زمان شمسی
1013 | ///
1014 | /// همانند 13961223102232461
1015 | ///
1016 | public static bool TryParse(long numericPersianDateTime, out PersianDateTime result)
1017 | {
1018 | try
1019 | {
1020 | result = Parse(numericPersianDateTime);
1021 | return true;
1022 | }
1023 | catch
1024 | {
1025 | result = MinValue;
1026 | return false;
1027 | }
1028 | }
1029 |
1030 | private static readonly List GregorianWeekDayNames = new List { "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" };
1031 | private static readonly List GregorianMonthNames = new List { "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december" };
1032 | private static readonly List PmAm = new List { "pm", "am" };
1033 |
1034 | ///
1035 | /// فرمت های که پشتیبانی می شوند
1036 | ///
1037 | /// yyyy: سال چهار رقمی
1038 | ///
1039 | /// yy: سال دو رقمی
1040 | ///
1041 | /// MMMM: نام فارسی ماه
1042 | ///
1043 | /// MM: عدد دو رقمی ماه
1044 | ///
1045 | /// M: عدد یک رقمی ماه
1046 | ///
1047 | /// dddd: نام فارسی روز هفته
1048 | ///
1049 | /// dd: عدد دو رقمی روز ماه
1050 | ///
1051 | /// d: عدد یک رقمی روز ماه
1052 | ///
1053 | /// HH: ساعت دو رقمی با فرمت 00 تا 24
1054 | ///
1055 | /// H: ساعت یک رقمی با فرمت 0 تا 24
1056 | ///
1057 | /// hh: ساعت دو رقمی با فرمت 00 تا 12
1058 | ///
1059 | /// h: ساعت یک رقمی با فرمت 0 تا 12
1060 | ///
1061 | /// mm: عدد دو رقمی دقیقه
1062 | ///
1063 | /// m: عدد یک رقمی دقیقه
1064 | ///
1065 | /// ss: ثانیه دو رقمی
1066 | ///
1067 | /// s: ثانیه یک رقمی
1068 | ///
1069 | /// fff: میلی ثانیه 3 رقمی
1070 | ///
1071 | /// ff: میلی ثانیه 2 رقمی
1072 | ///
1073 | /// f: میلی ثانیه یک رقمی
1074 | ///
1075 | /// tt: ب.ظ یا ق.ظ
1076 | ///
1077 | /// t: حرف اول از ب.ظ یا ق.ظ
1078 | ///
1079 | public string ToString(string format, IFormatProvider fp = null)
1080 | {
1081 | if (string.IsNullOrEmpty(format)) format = "yyyy/MM/dd HH:mm:ss";
1082 | var dateTimeString = format.Trim();
1083 |
1084 | dateTimeString = dateTimeString.Replace("yyyy", Year.ToString(CultureInfo.InvariantCulture));
1085 | dateTimeString = dateTimeString.Replace("yy", GetShortYear.ToString("00", CultureInfo.InvariantCulture));
1086 | dateTimeString = dateTimeString.Replace("MMMM", MonthName);
1087 | dateTimeString = dateTimeString.Replace("MM", Month.ToString("00", CultureInfo.InvariantCulture));
1088 | dateTimeString = dateTimeString.Replace("M", Month.ToString(CultureInfo.InvariantCulture));
1089 | dateTimeString = dateTimeString.Replace("dddd", GetLongDayOfWeekName);
1090 | dateTimeString = dateTimeString.Replace("dd", Day.ToString("00", CultureInfo.InvariantCulture));
1091 | dateTimeString = dateTimeString.Replace("d", Day.ToString(CultureInfo.InvariantCulture));
1092 | dateTimeString = dateTimeString.Replace("HH", Hour.ToString("00", CultureInfo.InvariantCulture));
1093 | dateTimeString = dateTimeString.Replace("H", Hour.ToString(CultureInfo.InvariantCulture));
1094 | dateTimeString = dateTimeString.Replace("hh", ShortHour.ToString("00", CultureInfo.InvariantCulture));
1095 | dateTimeString = dateTimeString.Replace("h", ShortHour.ToString(CultureInfo.InvariantCulture));
1096 | dateTimeString = dateTimeString.Replace("mm", Minute.ToString("00", CultureInfo.InvariantCulture));
1097 | dateTimeString = dateTimeString.Replace("m", Minute.ToString(CultureInfo.InvariantCulture));
1098 | dateTimeString = dateTimeString.Replace("ss", Second.ToString("00", CultureInfo.InvariantCulture));
1099 | dateTimeString = dateTimeString.Replace("s", Second.ToString(CultureInfo.InvariantCulture));
1100 | dateTimeString = dateTimeString.Replace("fff", Millisecond.ToString("000", CultureInfo.InvariantCulture));
1101 | dateTimeString = dateTimeString.Replace("ff", (Millisecond / 10).ToString("00", CultureInfo.InvariantCulture));
1102 | dateTimeString = dateTimeString.Replace("f", (Millisecond / 100).ToString(CultureInfo.InvariantCulture));
1103 | dateTimeString = dateTimeString.Replace("tt", GetPersianAmPm);
1104 | dateTimeString = dateTimeString.Replace("t", GetPersianAmPm[0].ToString(CultureInfo.InvariantCulture));
1105 |
1106 | if (PersianNumber)
1107 | dateTimeString = ToPersianNumber(dateTimeString);
1108 |
1109 | return dateTimeString;
1110 | }
1111 |
1112 | ///
1113 | /// بررسی میکند آیا تاریخ ورودی تاریخ میلادی است یا نه
1114 | ///
1115 | public static bool IsChristianDate(string inputString)
1116 | {
1117 | inputString = inputString.ToLower();
1118 | bool result;
1119 |
1120 | foreach (var gregorianWeekDayName in GregorianWeekDayNames)
1121 | {
1122 | result = inputString.Contains(gregorianWeekDayName);
1123 | if (result) return true;
1124 | }
1125 |
1126 | foreach (var gregorianMonthName in GregorianMonthNames)
1127 | {
1128 | result = inputString.Contains(gregorianMonthName);
1129 | if (result) return true;
1130 | }
1131 |
1132 | foreach (var item in PmAm)
1133 | {
1134 | result = inputString.Contains(item);
1135 | if (result) return true;
1136 | }
1137 |
1138 | result = Regex.IsMatch(inputString, @"(1[8-9]|[2-9][0-9])\d{2}", RegexOptions.IgnoreCase);
1139 |
1140 | return result;
1141 | }
1142 |
1143 | ///
1144 | /// بررسی میکند آیا تاریخ ورودی مطابق تاریخ اس کسو ال سرور می باشد یا نه
1145 | ///
1146 | public static bool IsSqlDateTime(DateTime dateTime)
1147 | {
1148 | var minSqlDateTimeValue = new DateTime(1753, 1, 1);
1149 | return dateTime >= minSqlDateTimeValue;
1150 | }
1151 |
1152 | ///
1153 | /// تبدیل نام ماه شمسی به عدد معادل آن
1154 | ///
1155 | /// به طور مثال آذر را به 9 تبدیل می کند
1156 | ///
1157 | public int GetMonthEnum(string longMonthName)
1158 | {
1159 | var monthEnum = (PersianDateTimeMonthEnum)Enum.Parse(typeof(PersianDateTimeMonthEnum), longMonthName);
1160 | return (int)monthEnum;
1161 | }
1162 |
1163 | ///
1164 | /// نمایش تاریخ به فرمتی مشابه زیر
1165 | ///
1166 | /// 1393/09/14
1167 | ///
1168 | public string ToShortDateString()
1169 | {
1170 | var result = $"{Year:0000}/{Month:00}/{Day:00}";
1171 | if (!PersianNumber) return result;
1172 | return ToPersianNumber(result);
1173 | }
1174 |
1175 | ///
1176 | /// نمایش تاریخ به فرمتی مشابه زیر
1177 | ///
1178 | /// ج 14 آذر 93
1179 | ///
1180 | public string ToShortDate1String()
1181 | {
1182 | var result = $"{GetShortDayOfWeekName} {Day:00} {GetLongMonthName} {GetShortYear}";
1183 | if (!PersianNumber) return result;
1184 | return ToPersianNumber(result);
1185 | }
1186 |
1187 | ///
1188 | /// نمایش تاریخ به صورت عدد و در فرمتی مشابه زیر
1189 | ///
1190 | /// 13930914
1191 | ///
1192 | public int ToShortDateInt()
1193 | {
1194 | return int.Parse($"{Year:0000}{Month:00}{Day:00}");
1195 | }
1196 |
1197 | ///
1198 | /// نمایش تاریخ و ساعت تا دقت میلی ثانیه به صورت عدد
1199 | ///
1200 | /// 1396122310324655
1201 | ///
1202 | public long ToLongDateTimeInt()
1203 | {
1204 | return long.Parse($"{Year:0000}{Month:00}{Day:00}{Hour:00}{Minute:00}{Second:00}{Millisecond:000}");
1205 | }
1206 |
1207 | ///
1208 | /// در این فرمت نمایش ساعت و دقیقه و ثانیه در کنار هم با حذف علامت : تبدیل به عدد می شوند و نمایش داده می شود
1209 | ///
1210 | /// مثال: 123452
1211 | ///
1212 | /// که به معنای ساعت 12 و 34 دقیقه و 52 ثانیه می باشد
1213 | ///
1214 | public int ToTimeInt()
1215 | {
1216 | return int.Parse($"{Hour:00}{Minute:00}{Second:00}");
1217 | }
1218 |
1219 | ///
1220 | /// در این فرمت نمایش ساعت و دقیقه در کنار هم با حذف علامت : تبدیل به عدد می شوند و نمایش داده می شود
1221 | ///
1222 | /// مثال: 1234
1223 | ///
1224 | /// که به معنای ساعت 12 و 34 دقیقه می باشد
1225 | ///
1226 | public short ToTimeShort()
1227 | {
1228 | return short.Parse($"{Hour:00}{Minute:00}");
1229 | }
1230 |
1231 | ///
1232 | /// نمایش تاریخ به فرمتی مشابه زیر
1233 | ///
1234 | /// جمعه، 14 آذر 1393
1235 | ///
1236 | public string ToLongDateString()
1237 | {
1238 | var result = $"{GetLongDayOfWeekName}، {Day:00} {GetLongMonthName} {Year:0000}";
1239 | if (!PersianNumber) return result;
1240 | return ToPersianNumber(result);
1241 | }
1242 |
1243 | ///
1244 | /// نمایش تاریخ و زمان به فرمتی مشابه زیر
1245 | ///
1246 | /// جمعه، 14 آذر 1393 ساعت 13:50:27
1247 | ///
1248 | public string ToLongDateTimeString()
1249 | {
1250 | var result = $"{GetLongDayOfWeekName}، {Day:00} {GetLongMonthName} {Year:0000} ساعت {Hour:00}:{Minute:00}:{Second:00}";
1251 | if (!PersianNumber) return result;
1252 | return ToPersianNumber(result);
1253 | }
1254 |
1255 | ///
1256 | /// نمایش تاریخ و زمان به فرمتی مشابه زیر
1257 | ///
1258 | /// جمعه، 14 آذر 1393 13:50
1259 | ///
1260 | public string ToShortDateTimeString()
1261 | {
1262 | var result = $"{GetLongDayOfWeekName}، {Day:00} {GetLongMonthName} {Year:0000} {Hour:00}:{Minute:00}";
1263 | if (!PersianNumber) return result;
1264 | return ToPersianNumber(result);
1265 | }
1266 |
1267 | ///
1268 | /// نمایش زمان به فرمتی مشابه زیر
1269 | ///
1270 | /// 01:50 ب.ظ
1271 | ///
1272 | public string ToShortTimeString()
1273 | {
1274 | var result = $"{ShortHour:00}:{Minute:00} {GetPersianAmPm}";
1275 | if (!PersianNumber) return result;
1276 | return ToPersianNumber(result);
1277 | }
1278 |
1279 | ///
1280 | /// نمایش زمان به فرمتی مشابه زیر
1281 | ///
1282 | /// 13:50:20
1283 | ///
1284 | public string ToLongTimeString()
1285 | {
1286 | var result = $"{Hour:00}:{Minute:00}:{Second:00}";
1287 | if (!PersianNumber) return result;
1288 | return ToPersianNumber(result);
1289 | }
1290 |
1291 | ///
1292 | /// نمایش زمان به فرمتی مشابه زیر
1293 | ///
1294 | /// 1 دقیقه قبل
1295 | ///
1296 | public string ElapsedTime()
1297 | {
1298 | var persianDateTimeNow = new PersianDateTime(DateTime.Now);
1299 | var timeSpan = persianDateTimeNow - _dateTime;
1300 | if (timeSpan.TotalDays > 90)
1301 | return ToShortDateTimeString();
1302 |
1303 | var result = string.Empty;
1304 | if (timeSpan.TotalDays > 30)
1305 | {
1306 | var month = timeSpan.TotalDays / 30;
1307 | if (month > 0)
1308 | result = $"{month:0} ماه قبل";
1309 | }
1310 | else if (timeSpan.TotalDays >= 1)
1311 | {
1312 | result = $"{timeSpan.TotalDays:0} روز قبل";
1313 | }
1314 | else if (timeSpan.TotalHours >= 1)
1315 | {
1316 | result = $"{timeSpan.TotalHours:0} ساعت قبل";
1317 | }
1318 | else
1319 | {
1320 | var minute = timeSpan.TotalMinutes;
1321 | if (minute <= 1) minute = 1;
1322 | result = $"{minute:0} دقیقه قبل";
1323 | }
1324 | if (!PersianNumber) return result;
1325 | return ToPersianNumber(result);
1326 | }
1327 |
1328 | ///
1329 | /// گرفتن فقط زمان
1330 | ///
1331 | public TimeSpan GetTime()
1332 | {
1333 | return new TimeSpan(0, _dateTime.Hour, _dateTime.Minute, _dateTime.Second, _dateTime.Millisecond);
1334 | }
1335 |
1336 | ///
1337 | /// تنظیم کردن زمان
1338 | ///
1339 | public PersianDateTime SetTime(int hour, int minute, int second = 0, int milliseconds = 0)
1340 | {
1341 | return new PersianDateTime(Year, Month, Day, hour, minute, second, milliseconds);
1342 | }
1343 |
1344 | ///
1345 | /// تبدیل به تاریخ میلادی
1346 | ///
1347 | public DateTime ToDateTime()
1348 | {
1349 | return _dateTime;
1350 | }
1351 |
1352 | ///
1353 | /// تبدیل به تاریخ هجری قمری
1354 | ///
1355 | public HijriDateTime ToHijri(int hijriAdjustment = 0)
1356 | {
1357 | var hijriCalendar = new HijriCalendar
1358 | {
1359 | HijriAdjustment = hijriAdjustment
1360 | };
1361 | var month = hijriCalendar.GetMonth(_dateTime);
1362 | var monthName = "";
1363 | switch (month)
1364 | {
1365 | case 1:
1366 | monthName = "محرم";
1367 | break;
1368 | case 2:
1369 | monthName = "صفر";
1370 | break;
1371 | case 3:
1372 | monthName = "ربیع الاول";
1373 | break;
1374 | case 4:
1375 | monthName = "ربیع الثانی";
1376 | break;
1377 | case 5:
1378 | monthName = "جمادل الاولی";
1379 | break;
1380 | case 6:
1381 | monthName = "جمادی الاخره";
1382 | break;
1383 | case 7:
1384 | monthName = "رجب";
1385 | break;
1386 | case 8:
1387 | monthName = "شعبان";
1388 | break;
1389 | case 9:
1390 | monthName = "رمضان";
1391 | break;
1392 | case 10:
1393 | monthName = "شوال";
1394 | break;
1395 | case 11:
1396 | monthName = "ذوالقعده";
1397 | break;
1398 | case 12:
1399 | monthName = "ذوالحجه";
1400 | break;
1401 | }
1402 | return new HijriDateTime
1403 | {
1404 | Day = hijriCalendar.GetDayOfMonth(_dateTime),
1405 | Month = month,
1406 | Year = hijriCalendar.GetYear(_dateTime),
1407 | MonthName = monthName
1408 | };
1409 | }
1410 |
1411 | ///
1412 | /// کم کردن دو تاریخ از هم
1413 | ///
1414 | public TimeSpan Subtract(PersianDateTime persianDateTime)
1415 | {
1416 | return _dateTime - persianDateTime.ToDateTime();
1417 | }
1418 |
1419 | ///
1420 | /// تعداد ماه اختلافی با تاریخ دیگری را بر میگرداند
1421 | ///
1422 | /// تعداد ماه
1423 | public int MonthDifference(DateTime dateTime)
1424 | {
1425 | return Math.Abs(dateTime.Month - _dateTime.Month + 12 * (dateTime.Year - _dateTime.Year));
1426 | }
1427 |
1428 | ///
1429 | /// اضافه کردن مدت زمانی به تاریخ
1430 | ///
1431 | public PersianDateTime Add(TimeSpan timeSpan)
1432 | {
1433 | return new PersianDateTime(_dateTime.Add(timeSpan), PersianNumber);
1434 | }
1435 |
1436 | ///
1437 | /// اضافه کردن سال به تاریخ
1438 | ///
1439 | public PersianDateTime AddYears(int years)
1440 | {
1441 | return new PersianDateTime(PersianCalendar.AddYears(_dateTime, years), PersianNumber);
1442 | }
1443 |
1444 | ///
1445 | /// اضافه کردن روز به تاریخ
1446 | ///
1447 | public PersianDateTime AddDays(int days)
1448 | {
1449 | return new PersianDateTime(PersianCalendar.AddDays(_dateTime, days), PersianNumber);
1450 | }
1451 |
1452 | ///
1453 | /// اضافه کردن ماه به تاریخ
1454 | ///
1455 | public PersianDateTime AddMonths(int months)
1456 | {
1457 | return new PersianDateTime(PersianCalendar.AddMonths(_dateTime, months), PersianNumber);
1458 | }
1459 |
1460 | ///
1461 | /// اضافه کردن ساعت به تاریخ
1462 | ///
1463 | public PersianDateTime AddHours(int hours)
1464 | {
1465 | return new PersianDateTime(_dateTime.AddHours(hours), PersianNumber);
1466 | }
1467 |
1468 | ///
1469 | /// اضافه کردن دقیقه به تاریخ
1470 | ///
1471 | public PersianDateTime AddMinutes(int minutes)
1472 | {
1473 | return new PersianDateTime(_dateTime.AddMinutes(minutes), PersianNumber);
1474 | }
1475 |
1476 | ///
1477 | /// اضافه کردن ثانیه به تاریخ
1478 | ///
1479 | public PersianDateTime AddSeconds(int seconds)
1480 | {
1481 | return new PersianDateTime(_dateTime.AddSeconds(seconds), PersianNumber);
1482 | }
1483 |
1484 | ///
1485 | /// اضافه کردن میلی ثانیه به تاریخ
1486 | ///
1487 | public PersianDateTime AddMilliseconds(int milliseconds)
1488 | {
1489 | return new PersianDateTime(_dateTime.AddMilliseconds(milliseconds), PersianNumber);
1490 | }
1491 |
1492 | ///
1493 | /// بدست آوردن تاریخ شمسی اولین روز هفته
1494 | ///
1495 | public PersianDateTime GetFirstDayOfWeek()
1496 | {
1497 | var persianDateTime = new PersianDateTime(_dateTime).Date;
1498 | return persianDateTime.AddDays(PersianDayOfWeek.Saturday - persianDateTime.PersianDayOfWeek);
1499 | }
1500 |
1501 | ///
1502 | /// بدست آوردن تاریخ شمسی آخرین روز هفته
1503 | ///
1504 | public PersianDateTime GetPersianWeekend()
1505 | {
1506 | var persianDateTime = new PersianDateTime(_dateTime).Date;
1507 | return persianDateTime.AddDays(PersianDayOfWeek.Friday - persianDateTime.PersianDayOfWeek);
1508 | }
1509 |
1510 | ///
1511 | /// نام فارسی ماه بر اساس شماره ماه
1512 | ///
1513 | /// نام فارسی ماه
1514 | public static string GetPersianMonthName(int monthNumber)
1515 | {
1516 | return GetPersianMonthNamePrivate(monthNumber);
1517 | }
1518 |
1519 | private static string ToPersianNumber(string input)
1520 | {
1521 | if (string.IsNullOrEmpty(input)) return null;
1522 | input = input.Replace("ي", "ی").Replace("ك", "ک");
1523 |
1524 | //۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹
1525 | return
1526 | input
1527 | .Replace("0", "۰")
1528 | .Replace("1", "۱")
1529 | .Replace("2", "۲")
1530 | .Replace("3", "۳")
1531 | .Replace("4", "۴")
1532 | .Replace("5", "۵")
1533 | .Replace("6", "۶")
1534 | .Replace("7", "۷")
1535 | .Replace("8", "۸")
1536 | .Replace("9", "۹");
1537 | }
1538 |
1539 | private static string ToEnglishNumber(string input)
1540 | {
1541 | if (string.IsNullOrEmpty(input)) return null;
1542 | input = input.Replace("ي", "ی").Replace("ك", "ک");
1543 |
1544 | //۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹
1545 | return input
1546 | .Replace(",", "")
1547 | .Replace("۰", "0")
1548 | .Replace("۱", "1")
1549 | .Replace("۲", "2")
1550 | .Replace("۳", "3")
1551 | .Replace("۴", "4")
1552 | .Replace("۵", "5")
1553 | .Replace("۶", "6")
1554 | .Replace("۷", "7")
1555 | .Replace("۸", "8")
1556 | .Replace("۹", "9");
1557 | }
1558 |
1559 | private static string GetPersianMonthNamePrivate(int monthNumber)
1560 | {
1561 | var monthName = "";
1562 | switch (monthNumber)
1563 | {
1564 | case 1:
1565 | monthName = "فروردین";
1566 | break;
1567 |
1568 | case 2:
1569 | monthName = "اردیبهشت";
1570 | break;
1571 |
1572 | case 3:
1573 | monthName = "خرداد";
1574 | break;
1575 |
1576 | case 4:
1577 | monthName = "تیر";
1578 | break;
1579 |
1580 | case 5:
1581 | monthName = "مرداد";
1582 | break;
1583 |
1584 | case 6:
1585 | monthName = "شهریور";
1586 | break;
1587 |
1588 | case 7:
1589 | monthName = "مهر";
1590 | break;
1591 |
1592 | case 8:
1593 | monthName = "آبان";
1594 | break;
1595 |
1596 | case 9:
1597 | monthName = "آذر";
1598 | break;
1599 |
1600 | case 10:
1601 | monthName = "دی";
1602 | break;
1603 |
1604 | case 11:
1605 | monthName = "بهمن";
1606 | break;
1607 |
1608 | case 12:
1609 | monthName = "اسفند";
1610 | break;
1611 | }
1612 | return monthName;
1613 | }
1614 |
1615 | #endregion
1616 |
1617 | #region IConvertible
1618 |
1619 | ///
1620 | public TypeCode GetTypeCode()
1621 | {
1622 | return TypeCode.DateTime;
1623 | }
1624 |
1625 | ///
1626 | public bool ToBoolean(IFormatProvider provider)
1627 | {
1628 | return _dateTime > DateTime.MinValue;
1629 | }
1630 |
1631 | ///
1632 | public byte ToByte(IFormatProvider provider)
1633 | {
1634 | throw new InvalidCastException();
1635 | }
1636 |
1637 | ///
1638 | public char ToChar(IFormatProvider provider)
1639 | {
1640 | throw new InvalidCastException();
1641 | }
1642 |
1643 | ///
1644 | public DateTime ToDateTime(IFormatProvider provider)
1645 | {
1646 | return _dateTime;
1647 | }
1648 |
1649 | ///
1650 | public decimal ToDecimal(IFormatProvider provider)
1651 | {
1652 | return ToLongDateTimeInt();
1653 | }
1654 |
1655 | ///
1656 | public double ToDouble(IFormatProvider provider)
1657 | {
1658 | return ToLongDateTimeInt();
1659 | }
1660 |
1661 | ///
1662 | public short ToInt16(IFormatProvider provider)
1663 | {
1664 | throw new InvalidCastException();
1665 | }
1666 |
1667 | ///
1668 | public int ToInt32(IFormatProvider provider)
1669 | {
1670 | return ToShortDateInt();
1671 | }
1672 |
1673 | ///
1674 | public long ToInt64(IFormatProvider provider)
1675 | {
1676 | return ToLongDateTimeInt();
1677 | }
1678 |
1679 | ///
1680 | public sbyte ToSByte(IFormatProvider provider)
1681 | {
1682 | throw new InvalidCastException();
1683 | }
1684 |
1685 | ///
1686 | public float ToSingle(IFormatProvider provider)
1687 | {
1688 | throw new InvalidCastException();
1689 | }
1690 |
1691 | ///
1692 | public string ToString(IFormatProvider provider)
1693 | {
1694 | return ToString("", provider);
1695 | }
1696 |
1697 | ///
1698 | public object ToType(Type conversionType, IFormatProvider provider)
1699 | {
1700 | switch (Type.GetTypeCode(conversionType))
1701 | {
1702 | case TypeCode.Boolean:
1703 | return ToBoolean(provider);
1704 | case TypeCode.Byte:
1705 | return ToByte(provider);
1706 | case TypeCode.Char:
1707 | return ToChar(provider);
1708 | case TypeCode.DateTime:
1709 | return ToDateTime(provider);
1710 | case TypeCode.Decimal:
1711 | return ToDecimal(provider);
1712 | case TypeCode.Double:
1713 | return ToDouble(provider);
1714 | case TypeCode.Int16:
1715 | return ToInt16(provider);
1716 | case TypeCode.Int32:
1717 | return ToInt32(provider);
1718 | case TypeCode.Int64:
1719 | return ToInt64(provider);
1720 | case TypeCode.Object:
1721 | if (typeof(PersianDateTime) == conversionType)
1722 | return this;
1723 | if (typeof(DateTime) == conversionType)
1724 | return ToDateTime();
1725 | throw new InvalidCastException($"Conversion to a {conversionType.Name} is not supported.");
1726 | case TypeCode.SByte:
1727 | return ToSByte(provider);
1728 | case TypeCode.Single:
1729 | return ToSingle(provider);
1730 | case TypeCode.String:
1731 | return ToString(provider);
1732 | case TypeCode.UInt16:
1733 | return ToUInt16(provider);
1734 | case TypeCode.UInt32:
1735 | return ToUInt32(provider);
1736 | case TypeCode.UInt64:
1737 | return ToUInt64(provider);
1738 | case TypeCode.DBNull:
1739 | break;
1740 | case TypeCode.Empty:
1741 | break;
1742 | default:
1743 | throw new InvalidCastException($"Conversion to {conversionType.Name} is not supported.");
1744 | }
1745 | throw new InvalidCastException();
1746 | }
1747 |
1748 | ///
1749 | public ushort ToUInt16(IFormatProvider provider)
1750 | {
1751 | throw new InvalidCastException();
1752 | }
1753 |
1754 | ///
1755 | public uint ToUInt32(IFormatProvider provider)
1756 | {
1757 | return (uint)ToShortDateInt();
1758 | }
1759 |
1760 | ///
1761 | public ulong ToUInt64(IFormatProvider provider)
1762 | {
1763 | return (ulong)ToLongDateTimeInt();
1764 | }
1765 |
1766 | #endregion
1767 | }
1768 | }
--------------------------------------------------------------------------------