Как преобразовать строку даты персидского календаря в DateTime?

Я использую эти коды для преобразования текущей даты и времени, минус его с датой, которую пользователи вводят в текстовое поле. Но при конвертации выдает ошибку.

PersianCalendar p = new System.Globalization.PersianCalendar();
DateTime date = new DateTime();
date = DateTime.Parse(DateTime.Now.ToShortDateString());
int year = p.GetYear(date);
int month = p.GetMonth(date);
int day = p.GetDayOfMonth(date);
string str = string.Format("{0}/{1}/{2}", year, month, day);
DateTime d1 = DateTime.Parse(str);
DateTime d2 = DateTime.Parse(textBox9.Text);
string s = (d2 - d1).ToString().Replace(".00:00:00", "");
textBox10.Text = (d2 - d1).ToString().Replace(".00:00:00","");

Эта строка будет содержать ошибку при преобразовании даты и времени из строки в дату и время: DateTime d1 = DateTime.Parse(str);

Пожалуйста, помогите мне решить эту проблему.

заранее спасибо

Ответы

Ответ 1

Я решил эту проблему. это было из-за исключения в некоторые месяцы, поэтому, если вы хотите минус два раза времени друг от друга, вы должны преобразовать их в григорианский календарь, тогда вы можете минус их и увидеть результат.

вот коды:

PersianCalendar p = new PersianCalendar();
        string PersianDate1 = textBox1.Text;
        string[] parts = PersianDate1.Split('/', '-');
        DateTime dta1 = p.ToDateTime(Convert.ToInt32(parts[0]), Convert.ToInt32(parts[1]), Convert.ToInt32(parts[2]), 0, 0, 0, 0);
        string PersianDate2 = textBox2.Text;
        string[] parts2 = PersianDate2.Split('/', '-');
        DateTime dta2 = p.ToDateTime(Convert.ToInt32(parts2[0]), Convert.ToInt32(parts2[1]), Convert.ToInt32(parts2[2]), 0, 0, 0, 0);
        string s = (dta2 - dta1).ToString().Replace(".00:00:00", "");
        textBox3.Text = s; // Show the result into the textbox 

Ответ 2

Нет необходимости анализировать дату здесь.

EDIT:

Первоначально я только хотел указать на ошибку в обработке OP с этим ответом. Но я думаю, что полный ответ будет лучше (несмотря на задержку:)) И да, я знаю, что промежуточное представление даты не похоже на персидскую дату. Но это не то, что нужно. Этот код дает правильную разницу между текущей датой и датой, которую пользователь вводит.

string userInput = "1394/02/31";
System.DateTime date = System.DateTime.Today;
System.Globalization.PersianCalendar p = new System.Globalization.PersianCalendar();

int year = p.GetYear(date);
int month = p.GetMonth(date);
int day = p.GetDayOfMonth(date);
System.DateTime currentDate = new System.DateTime(year, month, 1);
currentDate = currentDate.AddDays(day - 1);

// validation omitted
System.String[] userDateParts = userInput.Split(new[] { "/" }, System.StringSplitOptions.None);
int userYear = int.Parse(userDateParts[0]);
int userMonth = int.Parse(userDateParts[1]);
int userDay = int.Parse(userDateParts[2]);
System.DateTime userDate = new System.DateTime(userYear, userMonth, 1);
userDate = userDate.AddDays(userDay - 1);

System.TimeSpan difference = currentDate.Subtract(userDate);

Ответ 3

Просто используйте метод ToDateTime в классе PersianCalendar:

PersianCalendar p = new PersianCalendar();
DateTime now = DateTime.Now;
DateTime dateT = p.ToDateTime(now.Year, now.Month, now.Day, 0, 0, 0, 0);

Затем, чтобы получить строку в этом формате, просто выполните:

string str = dateT.ToShortDateString();

Ответ 4

Фактическая проблема, похоже, заключается в анализе даты ввода пользователя в формате персидского календаря. Итак, если пользователь ввел 1391/2/31, вы хотите проанализировать это. Сегодня (19 мая 2012 г.) 1391/2/30, поэтому вы, наконец, хотите отобразить что-то вроде 1 day remaining.

Этот вопрос задан до. Однако принятый ответ там просто пытается использовать

string persianDate = "1390/02/07";
CultureInfo persianCulture = new CultureInfo("fa-IR");
DateTime persianDateTime = DateTime.ParseExact(persianDate, 
    "yyyy/MM/dd", persianCulture);

Что не будет работать для даты типа 1391/2/31. Поэтому я думаю, что вам придется реализовать синтаксический анализ.

Без выполнения какой-либо проверки ошибок и при условии, что пользователь всегда использует формат yyyy/mm/dd, вы можете использовать:

// Convert Persian Calendar date to regular DateTime
var persianDateMatch = System.Text.RegularExpressions.Regex.Match(
    persianTargetTextBox.Text, @"^(\d+)/(\d+)/(\d+)$");
var year = int.Parse(persianDateMatch.Groups[1].Value);
var month = int.Parse(persianDateMatch.Groups[2].Value);
var day = int.Parse(persianDateMatch.Groups[3].Value);
var pc = new System.Globalization.PersianCalendar();
var target = pc.ToDateTime(year, month, day, 0, 0, 0, 0);

var difference = target - DateTime.Today;
differenceLabel.Text = difference.TotalDays.ToString("0");

Вам нужно будет проверить, действительно ли регулярное выражение найдено совпадений. Вы также должны проверить, не вызывает ли ошибка pc.ToDateTime ошибку. К сожалению, для персидского календаря, похоже, нет ничего подобного DateTime.TryParse.

В любом случае, вам не нужно сегодня разбираться в персидском календаре, вам нужно всего лишь проанализировать ввод пользователя.

Вас также может заинтересовать Библиотека Farsi - работа с датами, календарями и DatePickers, хотя статья очень старая (2007).

Ответ 5

Вот где документация - ваш друг:

Класс PersianCalendar

DateTime Constructor (Int32, Int32, Int32, Календарь)

Это точный код, который вам нужен:

PersianCalendar p = new System.Globalization.PersianCalendar();
DateTime today = DateTime.Today;
DateTime pDate = new DateTime(p.GetYear(today), p.GetMonth(today), p.GetDayOfMonth(today), p);
DateTime d2 = DateTime.Parse(textBox9.Text);
// THIS NEEDS TO BE EXPLAINED
textBox10.Text = (d2 - pDate).ToString().Replace(".00:00:00","");

В конечном счете, что вы пытаетесь сделать? Какие результаты вы ожидаете в textBox10? Если вы хотите количество дней между двумя датами, просто сделайте (d2 - pDate).ToString("d"), и вы получите разницу в днях. Возможно, если вы объясните немного больше, ЧТО вы пытаетесь сделать, вместо того, КАК вы пытаетесь это сделать, мы можем помочь вам дальше.

Править: Просто понял, что говорила comecme. Строка, которая вызовет проблему, находится здесь:

DateTime d2 = DateTime.Parse(textBox9.Text);

Вместо этого нам нужно будет изменить его, чтобы также использовать информацию о культуре:

CultureInfo persianCulture = new CultureInfo("fa-IR");
DateTime d2 = DateTime.Parse(textBox9.Text, persianCulture)

Правка: вы правы, это разрешает синтаксический анализ даты в персидском формате, но не проверяется в соответствии с определенным календарем. Чтобы это нормально работало, вам придется вручную разобрать дату и создать новую дату DateTime с предоставленным PersianCalendar:

DateTime d2;
if(Regex.IsMatch(textBox9.Text, "^dddd/dd/dd$"))
{
    d2 = new DateTime(
        int.Parse(textBox9.Substring(0,4)), 
        int.Parse(textBox9.Substring(5, 2)), 
        int.Parse(textBox9.Substring(8, 2)),
        p);
}

Вам нужно только убедиться, что вход определенно соответствует указанному вами формату, иначе нет возможности последовательно анализировать DateTime.

Ответ 6

Вы можете использовать этот код:

  DateTime today = DateTime.Today; // excludes h/m/s

  DateTime userdate = DateTime.Parse(textBox9.Text);

Если вы выложите один из другого, вы получите TimeSpan.

  TimeSpan diff = today - userDate;

Вы можете использовать эти свойства временного интервала, чтобы показать их так, как вам нравится.

Чтобы управлять формой конверсии/в персидском календаре, у вас есть хорошее решение здесь:

.NET. Как проанализировать строку даты для персидского (календарь Jalali) в объект DateTime?

Литература:

DateTime.Today

TimeSpan

Ответ 7

Вот код, который я использую:

  public DateTime ConvertPersianToEnglish(string persianDate)
        {
            string[] formats = { "yyyy/MM/dd", "yyyy/M/d", "yyyy/MM/d", "yyyy/M/dd" };
            DateTime d1 = DateTime.ParseExact(persianDate, formats,
                                              CultureInfo.CurrentCulture, DateTimeStyles.None);
            PersianCalendar persian_date = new PersianCalendar();
            DateTime dt = persian_date.ToDateTime(d1.Year, d1.Month, d1.Day, 0, 0, 0, 0, 0);
            return dt;
        }

Ответ 8

Вы также можете использовать следующую библиотеку .net, чтобы использовать PersianCalendar так же просто, как DateTime:

Персидский календарь (PersianDateTime) в С#

var persianDateTime = PersianDateTime.Now;
persianDateTime.EnglishNumber = true;
Console.Write(persianDateTime.ToString());

Ответ 9

Это можно сделать намного проще, используя Noda Time:

using System.Globalization;
using NodaTime;
using NodaTime.Text;

...

CultureInfo culture = CultureInfo.CreateSpecificCulture("fa-IR");
CalendarSystem calendar = CalendarSystem.GetPersianCalendar();
LocalDate template = new LocalDate(1, 1, 1, calendar);
LocalDatePattern pattern = LocalDatePattern.Create("yyyy/M/d", culture, template);
LocalDate result = pattern.Parse("1391/2/30").Value;

// if you need a DateTime, then:
DateTime dt = result.AtMidnight().ToDateTimeUnspecified();

Ответ 10

попробуйте этот код: этот код является отредактированным кодом, опубликованным "grzegorz W", но его код генерирует ошибку, например, когда пользователь вводит дату = "1394/06/31", а ошибка: "Параметры Year, Month и Day описывают не представимую DateTime"

ниже код в порядке:

string userInput = "1394/02/31";
System.DateTime date = System.DateTime.Today;
System.Globalization.PersianCalendar p = new System.Globalization.PersianCalendar();

int year = p.GetYear(date);
int month = p.GetMonth(date);
int day = p.GetDayOfMonth(date);
System.DateTime currentDate = new System.DateTime(year, month, day,p);


System.String[] userDateParts = userInput.Split(new[] { "/" },      System.StringSplitOptions.None);
int userYear = int.Parse(userDateParts[0]);
int userMonth = int.Parse(userDateParts[1]);
int userDay = int.Parse(userDateParts[2]);
System.DateTime userDate = new System.DateTime(userYear, userMonth, userDay,p);


System.TimeSpan difference = currentDate.Subtract(userDate);