60

How can I convert Persian date to Gregorian date using System.globalization.PersianCalendar? Please note that I want to convert my Persian Date (e.g. today is 1391/04/07) and get the Gregorian Date result which will be 06/27/2012 in this case. I'm counting seconds for an answer ...

Mahdi Tahsildari
  • 13,065
  • 14
  • 55
  • 94
  • 2
    Persian or *Gregorian* seconds? ;-) – Jon Jun 27 '12 at 08:44
  • http://stackoverflow.com/questions/5811170/net-how-to-parse-a-date-string-for-persian-jalali-calendar-into-a-datetime-ob – Habib Jun 27 '12 at 08:47
  • my working answer to similar question http://stackoverflow.com/a/26543563/184572 – Iman Oct 24 '14 at 07:47
  • 1
    To Help Persians I have Added some updated library Here. 1. [PersianDateTime for .Net and .Net Core](https://github.com/Mds92/MD.PersianDateTime) 2. [Bootstrap PersianDateTimePicker](https://github.com/Mds92/MD.BootstrapPersianDateTimePicker) – Ali reza Soleimani Asl Dec 24 '22 at 15:16

8 Answers8

111

It's pretty simple actually:

// I'm assuming that 1391 is the year, 4 is the month and 7 is the day
DateTime dt = new DateTime(1391, 4, 7, persianCalendar);
// Now use DateTime, which is always in the Gregorian calendar

When you call the DateTime constructor and pass in a Calendar, it converts it for you - so dt.Year would be 2012 in this case. If you want to go the other way, you need to construct the appropriate DateTime then use Calendar.GetYear(DateTime) etc.

Short but complete program:

using System;
using System.Globalization;

class Test
{
    static void Main()
    {
        PersianCalendar pc = new PersianCalendar();
        DateTime dt = new DateTime(1391, 4, 7, pc);
        Console.WriteLine(dt.ToString(CultureInfo.InvariantCulture));
    }
}

That prints 06/27/2012 00:00:00.

M.R.T
  • 746
  • 8
  • 20
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • +1 Great ! ! Didn't know about the `Calender` provision in `DateTime`, thought `GetYear`, `GetMonth` were the ways to go – V4Vendetta Jun 27 '12 at 08:51
  • what about [`ToDateTime`](http://msdn.microsoft.com/en-us/library/3c1445e1%28v=vs.110%29.aspx) method of [`PersianCalendar`](http://msdn.microsoft.com/en-us/library/system.globalization.persiancalendar%28v=vs.110%29.aspx) class?? – AminM Mar 19 '14 at 11:43
  • How to we can get with dash? mean "201-06-27 00:00:00" – Saeed Rahmani Sep 10 '16 at 09:25
  • @Saeed: Just specify a custom format in the ToString call. – Jon Skeet Sep 10 '16 at 09:34
  • @Jon: `DateTime dateEC = new DateTime(datePersian.Year,datePersian.Month,datePersian.Day, new PersianCalendar());` I used this Code. – Saeed Rahmani Sep 10 '16 at 09:39
  • @Saeed: I've already explained, you need to specify the format in the ToString call. There are lots of questions on SO about formatting. – Jon Skeet Sep 10 '16 at 09:40
  • 1
    @Jon: Thank you. I specified `ToString("yyyy-MM-dd hh:mm:ss")` It's correct. – Saeed Rahmani Sep 10 '16 at 09:44
  • @SaeedRahmani: You almost certainly want `HH` instead of `hh`, and I'd recommend explicitly specifying `CultureInfo.InvariantCulture` as well... – Jon Skeet Sep 10 '16 at 18:07
21

You can use this code to convert Persian Date to Gregorian.

// Persian Date
var value = "1396/11/27";
// Convert to Miladi
DateTime dt = DateTime.Parse(value, new CultureInfo("fa-IR"));
// Get Utc Date
var dt_utc = dt.ToUniversalTime();
MohammadSoori
  • 2,120
  • 1
  • 15
  • 17
3

you can use this code

return new DateTime(dt.Year,dt.Month,dt.Day,new System.Globalization.PersianCalendar());
Robabeh Ghasemi
  • 422
  • 1
  • 3
  • 11
Mahdi
  • 31
  • 3
  • 2
    Welcome to Stack Overflow. Code only answers can almost always be improved by adding some explanation of how and why they work. When answering an older question with existing answers it is very important to point out what new aspect of the question your answer addresses. If the question is very old it can be useful to mention if the techniques you use were added sometime since the question was asked or if they rely upon a particular version of a language or program. – Jason Aller Jun 03 '20 at 19:34
  • Also, so far as I can tell, while you're pulling your variables differently, this is in essence the same guidance as the accepted answer from eight years ago—but with far less explanation and a spelling error. When answering to old questions with accepted answers, please consider whether your answer is adding anything new—and, if it is, offer an explanation to readers of why your formulation might be preferable to the existing contributions. Do you mind updating your answer? – Jeremy Caney Jun 04 '20 at 00:22
0

I have an extension method for this:

 public static DateTime PersianDateStringToDateTime(this string persianDate)
 {
        PersianCalendar pc = new PersianCalendar();

        var persianDateSplitedParts = persianDate.Split('/');
        DateTime dateTime = new DateTime(int.Parse(persianDateSplitedParts[0]), int.Parse(persianDateSplitedParts[1]), int.Parse(persianDateSplitedParts[2]), pc);
        return DateTime.Parse(dateTime.ToString(CultureInfo.CreateSpecificCulture("en-US")));
 }

For more formats and culture-specific formats

Example: Convert 1391/04/07 to 06/27/2012

fbarikzehy
  • 4,885
  • 2
  • 33
  • 39
0

i test this code on windows 7 & 10 and run nicely without any problem

    /// <summary>
    /// Converts a Shamsi Date To Milady Date
    /// </summary>
    /// <param name="shamsiDate">string value in format "yyyy/mm/dd" or "yyyy-mm-dd"                     
     ///as shamsi date </param>
    /// <returns>return a DateTime in standard date format </returns>
public static DateTime? ShamsiToMilady(string shamsiDate)
    {
        if (string.IsNullOrEmpty(shamsiDate))
            return null;

        string[] datepart = shamsiDate.Split(new char[] { '/', '-' });
        if (datepart.Length != 3)
            return null;
        // 139p/k/b validation
        int year = 0, month = 0, day = 0;
        DateTime miladyDate;
        try
        {
            year = datepart[0].Length == 4 ? int.Parse(datepart[0]) : 
                                    int.Parse(datepart[2]);
            month = int.Parse(datepart[1]);
            day = datepart[0].Length == 4 ? int.Parse(datepart[2]) : 
                               int.Parse(datepart[0]);
            var currentCulture = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            miladyDate = new DateTime(year, month, day, new PersianCalendar());
            Thread.CurrentThread.CurrentCulture = currentCulture;
        }
        catch
        {
            return null;
        }

        return miladyDate;
    }
  • 1
    This code neither complements/enhances the previous answers nor does it uses `System.globalization.PersianCalendar` that has been intended by the question. Please refer to comments on https://stackoverflow.com/a/62176697/6045793 to learn more about how to answer an old topic. – Mahdad Baghani Dec 04 '20 at 16:53
  • 1
    thank you for attention me,but I use System.globalization.PersianCalendar in line miladyDate = new DateTime(year, month, day, new PersianCalendar()); and my code work for all conditions & win os. please see again https://stackoverflow.com/users/6045793/mahdad-baghani – hamid reza shahshahani Dec 10 '20 at 08:22
  • Yep, you are right about that. I must have missed the part you used System.globalization.PersianCalender. However, your answer still lacks enhancement to previous ones. Do not take this as a discouragement. I think that by applying a better naming (Shamsi -> Persian, Milady -> Gregorian) your answer can be upvoted. Moreover, it seems that you are using your own convention to parse the string date into the year, month and day variables, which may not be working in all cases. – Mahdad Baghani Dec 10 '20 at 11:17
0
To convert from Gregorian date to Persian(Iranian) date:

    string GetPersianDateYear(string PersianDate)
    {
       return PersianDate.Substring(0, 4);
    }
    
    string GetPersianDateMonth(string PersianDate)
    {
        if (PersianDate.Trim().Length > 8 || PersianDate.IndexOf('/') > 0 || PersianDate.IndexOf('-') > 0)
        {
            return PersianDate.Substring(5, 2);
        }
        else
        {
            return PersianDate.Substring(4, 2);
        }
    }
    
    string GetPersianDateDay(string PersianDate)
    {
         if (PersianDate.Trim().Length > 8 || PersianDate.IndexOf('/') > 0 || PersianDate.IndexOf('-') > 0)
         {
             return PersianDate.Substring(8, 2);
         }
         else
         {
             return PersianDate.Substring(6, 2);
         }
     }
    
     var PersianDate = "1348/10/01";
     var perDate = new System.Globalization.PersianCalendar();
     var dt = perDate.ToDateTime(GetPersianDateYear(PersianDate))
                                            , int.Parse(GetPersianDateMonth(PersianDate))
                                            , int.Parse(GetPersianDateDay(PersianDate)), 0, 0, 0, 0);
gyousefi
  • 306
  • 3
  • 9
0

install Nuget Package: Persian_Extention and use like this:

DateTime StartDate= StartDateStr.ToGregorianDateTime();
Or
String StartDateStr = StartDate.ToShamsiDate();
0

Because of unknown reason, none of solution worked for me. So I found a solution that worked.

Public Function ShamsiToMiladi(GDay As Long, GMonth As Long, GYear As Long) As Date
    Dim PDay As Integer = New Date(GYear, GMonth, GDay, New System.Globalization.PersianCalendar).Day
    Dim PMonth As Integer = New Date(GYear, GMonth, GDay, New System.Globalization.PersianCalendar).Month
    Dim PYear As Integer = New Date(GYear, GMonth, GDay, New System.Globalization.PersianCalendar).Year
    Return DateSerial(PYear, PMonth, PDay)
End Function
  • this is obviously not C#, it is VB.Net language. VB.Net also uses .Net, so you definitely can use Jon's solution, you just need to write the code in VB. Good luck. – Mahdi Tahsildari Jun 16 '23 at 12:55