C# 如何将波斯历日期字符串转换为 DateTime?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10655116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 14:41:03  来源:igfitidea点击:

How to convert Persian Calendar date string to DateTime?

c#datetime

提问by ALI VOJDANIANARDAKANI

I use these codes for converting current datetime and minus it with the date time which users type in a textbox. But it gives an error while converting.

我使用这些代码来转换当前日期时间并将其减去用户在文本框中键入的日期时间。但是转换的时候报错。

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","");

This line will accord an error while converting datetime from string to date time :DateTime d1 = DateTime.Parse(str);

在将日期时间从字符串转换为日期时间时,此行将给出错误:DateTime d1 = DateTime.Parse(str);

Please help me to solve this problem.

请帮我解决这个问题。

Thanks in advance

提前致谢

采纳答案by ALI VOJDANIANARDAKANI

I solved that problem. it was because of exception in some months so if you want to minus two date times from each other you should convert both to the Gregorian calendar then you can minus them and see the result.

我解决了那个问题。这是因为某些月份的异常,所以如果你想减去两个日期时间,你应该将两者都转换为公历,然后你可以减去它们并查看结果。

here are the codes :

这里是代码:

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 

回答by Grzegorz W

No need to parse the date here.

无需在这里解析日期。

EDIT:

编辑:

Originally I only wanted to point out error in OP processing with this answer. But I think a full answer would be better (despite the delay :) ) And Yes I know that intermediate date representation does not look like Persian Date. But it is not what is needed. This code gives proper difference between current date and the date that user puts in.

最初我只想用这个答案指出 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);

回答by mattytommo

Just use the ToDateTimemethod on the PersianCalendarclass:

只需ToDateTimePersianCalendar类上使用该方法:

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

Then to get your string in that format, just do:

然后要以该格式获取字符串,只需执行以下操作:

string str = dateT.ToShortDateString();

回答by SPFiredrake

Here is where documentation is your friend:

这是文档是您的朋友的地方:

PersianCalendar Class

PersianCalendar 类

DateTime Constructor (Int32, Int32, Int32, Calendar)

日期时间构造函数(Int32、Int32、Int32、日历)

This is the exact code you'd need:

这是您需要的确切代码:

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","");

Ultimately, what are you trying to do? What are the results you're expecting in textBox10? If you want the number of days between the two dates, then just do (d2 - pDate).ToString("d")and you'll get the difference in days. Maybe if you explained a little further WHAT you're trying to do, instead of HOW you're trying to do it, we can possibly help you further.

最后,你想做什么?你期待的结果是textBox10什么?如果您想要两个日期之间的天数,那么只需这样做(d2 - pDate).ToString("d"),您就会得到天数的差异。也许如果您进一步解释了您要做什么,而不是您要如何做,我们可能会进一步帮助您。

Edit: Just realized what comecme was saying. The line that would cause the issue is here:

编辑:刚刚意识到comemme在说什么。导致问题的行在这里:

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

Instead, we would need to change it to also use the culture information as well:

相反,我们需要将其更改为也使用文化信息:

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

Edit: You are correct, it only allows parsing the date in the Persian format, but does not validate according to a particular calendar. In order to get this working properly, you're gonna have to manually parse out the date and instantiate a new DateTime with the PersianCalendar supplied:

编辑:你是对的,它只允许解析波斯格式的日期,但不根据特定的日历进行验证。为了使其正常工作,您必须手动解析日期并使用提供的 PersianCalendar 实例化一个新的 DateTime:

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);
}

You just have to make sure that the input definitely matches the format you specify, otherwise there's no way to consistently parse out the DateTime accurately.

您只需要确保输入与您指定的格式完全匹配,否则无法始终准确地解析出 DateTime。

回答by JotaBe

You can use this code:

您可以使用此代码:

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

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

If you substract one from the other you get a TimeSpan.

如果你从另一个中减去一个,你会得到一个时间跨度。

  TimeSpan diff = today - userDate;

You can use this time span's properties to show them the way you like.

您可以使用此时间跨度的属性以您喜欢的方式显示它们。

To manage the conversion form/to Persian calendar, you have a good solution here:

要管理转换表格/到波斯历,这里有一个很好的解决方案:

.NET How to parse a date string for Persian (Jalali calendar) into a DateTime object?

.NET 如何将波斯语(Jalali 日历)的日期字符串解析为 DateTime 对象?

References:

参考:

DateTime.Today

日期时间.今天

TimeSpan

时间跨度

回答by comecme

You actual problem seems to lie in parsing the date the user entered in Persian calendar format. So, if the user entered 1391/2/31you want to be able to parse that. Today (May 19th 2012) is 1391/2/30so you finally want to display something like 1 day remaining.

您的实际问题似乎在于解析用户以波斯历格式输入的日期。因此,如果用户输入,1391/2/31您希望能够解析它。今天(2012 年 5 月 19 日)是1391/2/30您终于想要显示类似1 day remaining.

This question has been asked before. However, the accepted answer there just tries to use

这个问题以前有人问过。但是,那里接受的答案只是尝试使用

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

Which won't work for a date like 1391/2/31. So I think you'd have to implement the parsing yourself.

这不适用于像1391/2/31. 所以我认为你必须自己实现解析。

Without implementing any error checking, and assuming the user always uses the format yyyy/mm/ddyou could use:

不执行任何错误检查,并假设用户始终使用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");

You would need to check if the regex acually found any matches. You'd also have to check if pc.ToDateTimedoesn't throw an error. Unfortunately, there doesn't seem to exist anything like DateTime.TryParsefor the Persian Calendar.

您需要检查正则表达式是否能找到任何匹配项。您还必须检查是否pc.ToDateTime不会引发错误。不幸的是,似乎没有像DateTime.TryParse波斯历这样的东西。

Anyway, you don't need to parse today into a Persian Calendar, you only need to parse the user input.

不管怎样,今天不需要解析成波斯历,只需要解析用户输入即可。

You might also be interested in Farsi Library - Working with Dates, Calendars, and DatePickers, even though the article is very old (2007).

您可能还对Farsi Library - Working with Dates, Calendars, and DatePickers感兴趣,尽管这篇文章很旧(2007 年)。

回答by Ehsan Akbar

Here is a code that i am using :

这是我正在使用的代码:

  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;
        }

回答by Mohammad Dayyan

You can also use the following .net library to use PersianCalendar as easy as DateTime:

您还可以使用以下 .net 库来像 DateTime 一样简单地使用 PersianCalendar:

Persian Calendar(PersianDateTime) in C#

C# 中的波斯历(PersianDateTime)

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

回答by Matt Johnson-Pint

This can be done a lot easier using Noda Time:

使用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();

回答by hojjat.mi

try this code: this code is edited code that posted by "grzegorz W" but his code generate Error for example when user input date="1394/06/31" and error is "Year, Month, and Day parameters describe an un-representable DateTime"

试试这个代码:这个代码是由“grzegorz W”发布的编辑代码,但他的代码会产生错误,例如当用户输入日期=“1394/06/31”并且错误是“年、月和日参数描述一个非-可表示的日期时间”

below code is ok:

下面的代码没问题:

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);