Search code examples
c#datedatetimelocalizationglobalization

String was not recognized as a valid datetime in shamsi date fa-ir


I use shamsi date in my program and save it in sqllite date table. I use LINQ to save before save convert my date.

db.savechek(Convert.ToDateTime(datenow.Value.ToString("yyyy-MM-dd")),
            txt_sh_ch.Text.ToString(),
            Convert.ToDouble(txt_price.Text.ToString()),             
            Convert.ToDateTime(chekdate.Value.ToString("yyyy-MM-dd")), 
            txt_bank_name.Text.ToString(),
            Convert.ToDouble(txt_price.Text.ToString()),
            Guid.Parse(txtid.Text),
            Guid.Parse(txtid.Text),
            txttozihat.Text.ToString());

This code working good but I have this error in only 3 tome 1393-02-29 and 1393-02-30 and 1393-02-31.

I try use ParseExact but not work in my 3 date.


Solution

  • Currently I suspect you're parsing the date as a Gregorian date - which will fail if you try to input a date with a month of 2 but a day of 30 or 31 (or a day of 28 in a non-leap year).

    DateTime itself assumes the Gregorian calendar, but .NET does support non-Gregorian calendars. To parse a value in a non-Gregorian calendar, you'd probably need to use a CultureInfo which uses that calendar as its default. (Or pass in a DateTimeFormatInfo specifically into the TryParseExact method - that's an IFormatProvider as well.)

    Alternatively, if the "shamsi" calendar you're talking about is what I know as the Persian calendar, you could use the latest - not-quite-released - version of my Noda Time library. You'd do something like:

    using System;
    using NodaTime;
    using NodaTime.Text;
    
    class Test
    {
        static void Main()
        {
            var persianCalendar = CalendarSystem.GetPersianCalendar();
            var pattern = LocalDatePattern.CreateWithInvariantCulture("yyyy-MM-dd")
                .WithTemplateValue(new LocalDate(1393, 1, 1, persianCalendar));
            LocalDate result = pattern.Parse("1393-02-29").Value;
            DateTime dateTime = result.AtMidnight().ToDateTimeUnspecified();
            Console.WriteLine(dateTime); // 19th May 2014 (Gregorian)
        }
    }
    

    You can then save the DateTime to the database, and convert it back later as:

    var persianDate = LocalDateTime.FromDateTime(dateTime)
                                   .WithCalendar(persianCalendar)
                                   .Date;
    

    Unfortunately we've only introduced the Persian calendar with Noda Time 1.3, but we're hoping to do a release reasonably soon...