简体   繁体   English

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

[英]How to convert Persian Calendar date string to DateTime?

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提前致谢

No need to parse the date here.无需在这里解析日期。

EDIT:编辑:

Originally I only wanted to point out error in OP processing with this answer.最初我只想用这个答案指出 OP 处理中的错误。 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.此代码给出了当前日期和用户输入的日期之间的适当差异。

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

You actual problem seems to lie in parsing the date the user entered in Persian calendar format.您的实际问题似乎在于解析用户以波斯历格式输入的日期。 So, if the user entered 1391/2/31 you want to be able to parse that.因此,如果用户输入1391/2/31您希望能够解析它。 Today (May 19th 2012) is 1391/2/30 so you finally want to display something like 1 day remaining .今天(2012 年 5 月 19 日)是1391/2/30所以您最终想要显示诸如1 day remaining 1391/2/30之类的内容。

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 .这不适用于像1391/2/31这样的日期。 So I think you'd have to implement the parsing yourself.所以我认为你必须自己实现解析。

Without implementing any error checking, and assuming the user always uses the format yyyy/mm/dd you 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.ToDateTime doesn't throw an error.您还必须检查pc.ToDateTime是否不会引发错误。 Unfortunately, there doesn't seem to exist anything like DateTime.TryParse for the Persian Calendar.不幸的是,波斯日历似乎不存在像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 年)。

Just use the ToDateTime method on the PersianCalendar class:只需使用ToDateTime的方法PersianCalendar类:

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

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 

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 ?您在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.如果您想要两个日期之间的天数,那么只需执行(d2 - pDate).ToString("d")即可获得天数差异。 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.也许如果您进一步解释了您要做什么,而不是您要如何做,我们可能会进一步帮助您。

Edit: Just realized what comecme was saying.编辑:刚刚意识到comemme在说什么。 The line that would cause the issue is here:导致问题的行在这里:

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。

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

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时间跨度

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

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

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

You can use this simple code to convert persian calendar values to Datetime object in C# and make your calculations.您可以使用这个简单的代码将波斯日历值转换为 C# 中的 Datetime 对象并进行计算。

DateTime dateTime 
      = new DateTime(persianYear, persianMonth, persianDay, new PersianCalendar());

Hello You can use this EXTENTION METHODE :您好,您可以使用此扩展方法:

public static class PersainDateTime
{

    public static DateTime PersianDateToMiladi(this string value)
        {
            string[] d = value.Split('/');
            return new DateTime(int.Parse(d[0]), int.Parse(d[1]), int.Parse(d[2]), new System.Globalization.PersianCalendar());
        }
}

Now where ever you want you can use it like this:现在你可以在任何你想要的地方使用它:

var date=("1395/10/5").PersianDateToMiladi();

or要么

var date= textbox1.text.PersianDateToMiladi();
private void timer1_Tick(object sender, EventArgs e)
{
    labelDataAD.Text = DateTime.Now.ToString("dd/MM/yyyy");
    PersianCalendar persianCalendar = new PersianCalendar();
    string Full = persianCalendar.GetYear(DateTime.Now) + "/" + 
    persianCalendar.GetMonth(DateTime.Now)+"/"+ 
    persianCalendar.GetDayOfMonth(DateTime.Now);
    labelDataSolar.Text = string.Format("{0:yyyy\\:MM\\:dd}", Full);
}

private void FormCalendar_Load(object sender, EventArgs e)
{           
    timer1.Start();
}

The output is:输出是:

日期输出

对于我的情况,这个解决方案对我有帮助:我在我的项目中创建工具文件夹然后我把类 ExtensionsHelper.cs 和 HijriDateTime.cs 和 PersianDateTime.cs 和 PersianDayOfWeek.cs 放在这个链接中你可以找到上面的类:< https:// github.com/Mds92/MD.PersianDateTime > 然后我使用 PersianDateTime 而不是 DateTime:

DateTime datetime = new DateTime(PersianDateTime.Now.Year, PersianDateTime.Now.Month, PersianDateTime.Now.Day, 0, 0, 0);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM