2012-05-18 91 views
14

我使用这些代码来转换当前日期时间并减去用户在文本框中键入的日期时间。但它在转换时出现错误。如何将Persian Calendar日期字符串转换为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

什么是你的错误? – Tejs

+5

为什么要格式化DateTime.Now然后再解析它?为什么你给'date'赋值,然后立即给它赋一个不同的值?你为什么要将波斯年/月/日解析为不在波斯日历中?它*非常*不清楚你想要做什么,以及波斯日历适合什么地方。 –

+0

你不会对'字符串s'做任何事情。 – comecme

回答

6

我解决了这个问题。这是因为在几个月内例外,所以如果你想减去两个彼此的日期时间,你应该将两者都转换成公历,然后你可以减去它们并查看结果。

这里是代码:

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 
14

不需要在这里解析日期。

编辑:

本来我只是想指出在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); 
+0

这仍然是相同的'DateTime d1 = DateTime.Now.Date'。 – comecme

+0

不,它不是:) –

+0

@GrzegorzWilczura它说:年,月和日参数描述了一个不可表示的日期时间。 – aliboy38

10

只需使用上PersianCalendarToDateTime方法:

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

这种方法从波斯日历转换为我们的日期。所以实际上,你会在遥远的将来得到一些东西。我怀疑这是他想要的。 –

+0

@GrzegorzWilczura它使用波斯历来转换为我们的一天,这将给你什么在未来? – mattytommo

+1

因为今天这段代码产生2633-08-12 –

5

这里就是文档是你的朋友:

PersianCalendar Class

DateTime Constructor (Int32, Int32, Int32, Calendar)

这是确切的代码你需要:

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) 

编辑:你是正确的,它只允许以波斯语格式解析日期,但不根据特定的日历进行验证。为了得到这个工作正常,你得手动解析出的日期和实例与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); 
} 

你一定要确保输入您的格式一致肯定指定,否则无法准确解析出DateTime。如果你一个。减去从另一个你会得到一个时间跨度

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

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

+0

我不认为你可以从每个可能的波斯日期创建DateTime。波斯第二个月有31天,但公历不是。所以它会失败,像'新日期时间(1391,2,31);'。 – comecme

+0

它显示负数减号结果花花公子 – aliboy38

+0

@comecme:这是有效的,因为您也提供日历,这意味着它根据特定日历验证日期。 @ aliboy38:当然是的,因为时间跨度是负的(意思是用户输入的日期是在今天的日期之前)。如果用户提供的日期将小于今天的日期,则逆转日期时间减法的顺序('(pDate-d2).ToString(“d”)')。但是,这又取决于你想要完成什么。如果你只想要天的一部分(绝对值),那么只要'Math.Abs​​((pDate - d2).TotalDays)''。 – SPFiredrake

8

您的实际问题似乎在于解析用户在波斯语calenda中输入的日期r格式。因此,如果用户输入1391/2/31,您希望能够解析该问题。今天(2012年5月19日)是1391/2/30,所以你最终想要显示一些像1 day remaining

这个问题有been asked before。然而,接受的答案那里只是尝试使用

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

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

无论如何,你不需要今天解析一个波斯日历,你只需要解析用户输入。

尽管文章很旧(2007),您可能也有兴趣Farsi Library - Working with Dates, Calendars, and DatePickers

1

下面是我使用的是代码:

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

您还可以使用以下.NET库使用PersianCalendar那么容易,因为日期时间:

Persian Calendar(PersianDateTime) in C#

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

这可以使用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(); 
0

试试这个代码: 这段代码编辑者个人意见,“格热戈日W”的代码,但他的代码生成例如错误,当用户输入日期=“1394/06/31" 和错误的‘年,月和日参数描述一个未表示的日期时间’

下面的代码就可以了:

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); 
相关问题