2012-05-18 9 views
14

Uso questi codici per la conversione di datetime corrente e meno la data in cui gli utenti digitano una casella di testo. Ma dà un errore durante la conversione.Come convertire la stringa di data del calendario persiano in 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",""); 

Questa linea accorderà un errore durante la conversione datetime da stringa a data e ora: DateTime d1 = DateTime.Parse(str);

Ti prego, aiutami a risolvere questo problema.

Grazie in anticipo

+1

Qual è l'errore che si ottiene? – Tejs

+5

Perché stai formattando DateTime.Ora quindi analizzandolo di nuovo? Perché assegni un valore a 'date' e poi assegna immediatamente un valore diverso? Perché stai analizzando un anno/mese/giorno persiano come se non fosse nel calendario persiano? È * molto * poco chiaro cosa stai cercando di fare, e dove si adatta il calendario persiano. –

+0

Non fai niente con il tuo 'string s'. – comecme

risposta

6

Ho risolto il problema. è stato a causa di un'eccezione in alcuni mesi, quindi se si desidera meno due date l'una dall'altra è necessario convertire entrambi nel calendario gregoriano, quindi è possibile ridurli e vedere il risultato.

Ecco i codici:

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

Non c'è bisogno di analizzare la data qui.

EDIT:

Inizialmente ho solo voluto sottolineare di errore nel trattamento OP con questa risposta. Ma penso che una risposta completa sarebbe meglio (nonostante il ritardo :)) E sì, so che la rappresentazione della data intermedia non assomiglia alla data persiana. Ma non è ciò che è necessario. Questo codice dà una corretta differenza tra la data attuale e la data che l'utente mette 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); 
+0

Che è ancora lo stesso di 'DateTime d1 = DateTime.Now.Date'. – comecme

+0

No, non lo è :) –

+0

@GrzegorzWilczura Ha detto: I parametri Anno, Mese e Giorno descrivono un DateTime non rappresentabile. – aliboy38

10

Basta utilizzare il metodo ToDateTime sulla classe PersianCalendar:.

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

Quindi per ottenere la stringa in quel formato, basta fare:

string str = dateT.ToShortDateString(); 
+2

Questo metodo converte dal calendario persiano alla nostra data. Quindi, in realtà, otterrai qualcosa in un lontano futuro. Dubito che è ciò che vuole. –

+0

@GrzegorzWilczura Si converte ai nostri giorni, usando il calendario persiano, come ti darebbe qualcosa in futuro? – mattytommo

+1

Perché oggi questo codice produce 2633-08-12 –

5

Qui è dove la documentazione è tuo amico:

PersianCalendar Class

DateTime Constructor (Int32, Int32, Int32, Calendar)

Questo è il codice esatto avresti bisogno:

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

In definitiva, che cosa stai cercando di fare? Quali sono i risultati che ti aspetti da textBox10? Se vuoi il numero di giorni tra le due date, fai semplicemente (d2 - pDate).ToString("d") e otterrai la differenza in giorni. Forse se hai spiegato un po 'di più COSA stai cercando di fare, invece di COME stai provando a farlo, possiamo forse aiutarti ulteriormente.

Modifica: ho appena realizzato ciò che diceva. La linea che potrebbe causare il problema è qui:

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

Invece, avremmo bisogno di cambiarlo utilizzare anche le informazioni cultura:

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

Edit: Lei ha ragione, in quanto consente solo analizzando la data nel formato persiano, ma non convalida in base a un calendario particolare.Al fine di ottenere questo funziona correttamente, dovrai per analizzare manualmente la data e istanziare un nuovo DateTime con la PersianCalendar in dotazione:

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

Devi solo fare in modo che l'ingresso corrisponde sicuramente il formato specificare, altrimenti non c'è modo di analizzare accuratamente DateTime in modo preciso.

+0

Non penso che sia possibile creare un DateTime da ogni possibile data persiana. Il secondo mese persiano ha 31 giorni, ma la data gregoriana no. Quindi fallirà con qualcosa come 'new DateTime (1391,2,31);'. – comecme

+0

Mostra risultato negativo meno amico – aliboy38

+0

@comecme: valido perché si fornisce anche il calendario, il che significa che convalida la data in base al calendario specifico. @ aliboy38: Ovviamente lo fa, perché l'intervallo è negativo (ovvero la data in cui l'utente immesso arriva prima della data odierna). Se la data che l'utente fornisce sarà inferiore alla data odierna, invertire l'ordine della sottrazione datetime ('(pDate-d2) .ToString (" d ")'). Ancora una volta, dipende solo da ciò che stai cercando di realizzare. Se vuoi sempre solo la parte dei giorni (valore assoluto), fai semplicemente 'Math.Abs ​​((pDate - d2) .TotalDays)'. – SPFiredrake

1

È possibile utilizzare questo codice:

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

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

Se sottrarre l'uno dall'altro si ottiene un periodo.

TimeSpan diff = today - userDate; 

È possibile utilizzare le proprietà di questo intervallo di tempo per mostrarle nel modo desiderato.

Per gestire il modulo di conversione/a calendario persiano, si ha una buona soluzione qui:

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

Riferimenti:

DateTime.Today

TimeSpan

8

È vero problema sembra mentire nell'analisi della data in cui l'utente è entrato nella calenda persiana formato r. Quindi, se l'utente ha inserito 1391/2/31, si vuole essere in grado di analizzarlo. Oggi (19 maggio 2012) è 1391/2/30, quindi alla fine vuoi visualizzare qualcosa come 1 day remaining.

Questa domanda ha been asked before. Tuttavia, la risposta accettata non cerca solo di utilizzare

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

che non funziona per una data come 1391/2/31. Quindi penso che dovresti implementare l'analisi da solo.

Senza mettere in atto qualsiasi controllo degli errori, e supponendo che l'utente utilizza sempre il formato yyyy/mm/dd si potrebbe usare:

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

Si avrebbe bisogno di controllare se l'espressione regolare acually trovata alcuna corrispondenza. Dovresti anche controllare se pc.ToDateTime non genera un errore. Sfortunatamente, non sembra esistere nulla come DateTime.TryParse per il Calendario Persiano.

In ogni caso, non è necessario analizzare in un calendario persiano, è necessario solo analizzare l'input dell'utente.

Potresti anche essere interessato a Farsi Library - Working with Dates, Calendars, and DatePickers, anche se l'articolo è molto vecchio (2007).

1

Qui è un codice che sto usando:

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

È anche possibile utilizzare la seguente libreria .NET di usare PersianCalendar facile come DateTime:

Persian Calendar(PersianDateTime) in C#

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

Questo può essere fatto molto più facile usando 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

provare questo codice: questo codice viene modificato il codice che inviato "da Grzegorz W", ma il suo codice generare errore per esempio quando la data input dell'utente = "1394/06/31" e l'errore è 'anno, mese, giorno e parametri descrivono una non-rappresentabile DateTime'

sottostante codice è 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); 
Problemi correlati