2009-07-16 20 views
8

Tengo un datepicker jQuery UI que pretendo usar con un cuadro de texto en ASP.NET MVC. La fecha-pantalla en el cuadro de texto se localiza a través CultureInfo y por supuesto debe ser reconocido por jQuery para seleccionar la fecha correcta en el selector de fechas:Convierte .NET DateTimeFormatInfo a Javascript jQuery formatDate?

<%= Html.TextBox("Date", Model.Date.ToString("d", currentCultureInfo), 
    new { @class = "datepicker" })%> 

Lo que estoy tratando de hacer ahora es inicializar el selector de fechas con un dateformat como

string jsCode = @"$("".datepicker"").datepicker({ 
    dateFormat: '" + currentCultureInfo.DateTimeFormat.ShortDatePattern + @"', 
});"; 

el problema es que el formato de la cadena de formato de DateTimeFormatInfo (ver MSDN Enlace) es completamente diferente a la cadena de formato en jQuery (jQuery formatDate).

https://msdn.microsoft.com/en-us/library/system.globalization.datetimeformatinfo.aspx

muestra (formato de fecha 16.07.2009 alemán como):

.NET: 'dd.MM.yyyy' should be converted to 'dd.mm.yy' in jQuery/Javascript 

¿Existe un método o una biblioteca que hace la transformación necesaria entre los dos formatos?

Respuesta

8

Si solamente ShortDatePattern se debe convertir, el siguiente código proporciona lo que necesito:

public class wxDateTimeConvert 
{ 
    /// <summary> 
    /// Gets the javascript short date pattern. 
    /// </summary> 
    /// <param name="dateTimeFormat">The date time format.</param> 
    /// <returns></returns> 
    public static string GetJavascriptShortDatePattern(DateTimeFormatInfo dateTimeFormat) 
    { 
     return dateTimeFormat.ShortDatePattern 
      .Replace("M", "m") 
      .Replace("yy", "y"); 
    } 
} 

Incluyendo Javascript en la página:

/// <summary> 
    /// Inserts the localized datepicker jquery code 
    /// </summary> 
    private void InsertLocalizedDatepickerScript() 
    { 

     string dateformat = wxDateTimeConvert.GetJavascriptShortDatePattern(Thread.CurrentThread.CurrentUICulture.DateTimeFormat); 
     String js = @"$(document).ready(function() { 
$("".datepicker"").datepicker({ 
    changeYear: true, 
    dateFormat: '" + dateformat + @"', 
    maxDate: new Date() 
    }); 
});"; 
     this.Page.Header.Controls.Add(
      new LiteralControl("<script type=\"text/javascript\">" + js + "</script>") 
     ); 
    } 

Sin embargo, esto no controla mes o el día nombres, formato de tiempo u otros casos especiales.

0

Puede que no sea la solución perfecta pero puede ayudarlo a comenzar. jQuery no tiene ningún método para trabajar con fechas, pero JavaScript sí.

de análisis Fecha

En primer lugar, tiene un método Date.parse() que le permite analizar cadenas de fecha para valorar que contiene el número de milisegundos desde el 1 de enero de 1970. A continuación, puede utilizar este valor para crear un nuevo objeto de fecha y extraer todo el datos que necesita de este objeto.

var dateString = "Jun 1 2006"; 
var parsedDate = Date.parse(dateString); 
var date = new Date(parsedDate); 

Desafortunadamente Date.parse() no maneja bien 'salpicado' cuerdas como 2007.03.01 pero no es una solución para eso también. Que sólo puede sustituir a todos los puntos con barras:

var dateString = "2007.03.01".replace(/\./g, '/'); 

embargo esto no hará que Date.parse() comprender cualquier formato de fecha que .NET volverá, pero puede ser útil en algunos casos.

Formating Fecha

Ahora bien, si usted ha Fecha objeto creado ahora puede convertirlo a cualquier formato de fecha que desee. Esto en realidad es bastante fácil. Hay una implementación del método de formato de fecha de PHP para JS. Puede encontrarlo here.

Si agrega eso a sus scripts, puede formatear su fecha usando cualquier token descrito en la documentación y hay muchos. Por ejemplo

date.format('Y-M-d H:i:s'); 
+0

Asker ya tiene una biblioteca de formato de fecha. Asker no necesita uno que entienda el formato de fecha de php. Asker necesita uno que pueda entender/traducir-al formato de .NET. –

+0

No necesita comprender el formato de fecha de php, todos los switches se explican en el formato de fecha para la documentación de JS. No estoy seguro de si el analizador puede manejar todos los formatos de .NET pero seguramente esta solución se puede adaptar para manejarlos. Como mencioné en mi primera oración, esta no es una solución completa, más algo con lo que puedes empezar a trabajar. – RaYell

+0

Gracias por su respuesta, pero como crescentfresh dijo que no es realmente lo que necesito. Pero puede ayudar pensar de otra manera: uno podría preparar un objeto Date de JavaScript con un formato ISO y usar ese objeto para inicializar el datepicker. Lamentablemente, la cadena devuelta por el selector de fechas seguirá en otro formato. Entonces, si no hay una biblioteca de transformación existente, supongo que tendré que escribir la mía ... – mattanja

6

Me acabo de encontrar exactamente con el mismo problema y se me ocurrió el siguiente código. No es perfecto, pero debería abarcar la mayoría de las culturas y fallar con elegancia. ¡Probablemente tampoco sea la versión más corta que se te ocurra!

///======================================================================== 
/// Method : ConvertDateFormat 
/// 
/// <summary> 
/// Takes a culture and returns matching C# and jQuery date format 
/// strings. If possible the C# string will be the ShortDatePattern for 
/// the supplied culture. 
/// </summary> 
///======================================================================== 
private static void GetDateFormats(CultureInfo xiCulture, out string xoCSharpFormat, out string xoJQueryFormat) 
{ 
    //======================================================================= 
    // Start by assigning formats that are hopefully unambiguous in case we 
    // can't do better. 
    //======================================================================= 
    xoCSharpFormat = "yyyy-MM-dd"; 
    xoJQueryFormat = "yy-mm-dd"; 

    if (xiCulture.IsNeutralCulture) 
    { 
    try 
    { 
     xiCulture = CultureInfo.CreateSpecificCulture(xiCulture.Name); 
    } 
    catch 
    { 
     //=================================================================== 
     // Some cultures are neutral and don't have specific cultures. 
     // There's not much we can do here. 
     //=================================================================== 
     return; 
    } 
    } 

    string lCSharpFormat = xiCulture.DateTimeFormat.ShortDatePattern; 

    //======================================================================= 
    // Handle: 
    // C#  jQuery Meaning 
    // d  d  Day of month (no leading 0) 
    // dd  dd  Day of month (leading 0) 
    // M  m  Month of year (no leading 0) 
    // MM  mm  Month of year (leading 0) 
    // yy  y  Two digit year 
    // yyyy yy  Not an exact match but good enough: 
    //     C# means: The year in four or five digits (depending on 
    //     the calendar used), including the century. Pads with 
    //     leading zeros to get four digits. Thai Buddhist and 
    //     Korean calendars have five-digit years. Users 
    //     selecting the "yyyy" pattern see all five digits 
    //     without leading zeros for calendars that have five 
    //     digits. Exception: the Japanese and Taiwan calendars 
    //     always behave as if "yy" is selected. 
    //     jQuery means: four digit year 
    // 
    // Copy '.', '-', ' ', '/' verbatim 
    // Bail out if we find anything else and return standard date format for 
    // both. 
    //======================================================================= 
    StringBuilder lJQueryFormat = new StringBuilder(); 
    bool lError = false; 
    for (int ii = 0; ii < lCSharpFormat.Length; ++ii) 
    { 
    Char lCurrentChar = lCSharpFormat[ii]; 

    switch (lCurrentChar) 
    { 
     case 'd': 
     //================================================================= 
     // d or dd is OK, ddd is not 
     //================================================================= 
     if (ii < (lCSharpFormat.Length - 1) && 
      lCSharpFormat[ii+1] == 'd') 
     { 
      if (ii < (lCSharpFormat.Length - 2) && 
      lCSharpFormat[ii+2] == 'd') 
      { 
      //============================================================= 
      // ddd 
      //============================================================= 
      lError = true; 
      } 
      else 
      { 
      //============================================================= 
      // dd 
      //============================================================= 
      lJQueryFormat.Append("dd"); 
      ii++; 
      } 
     } 
     else 
     { 
      //=============================================================== 
      // d 
      //=============================================================== 
      lJQueryFormat.Append('d'); 
     } 
     break; 
     case 'M': 
     //================================================================= 
     // M or MM is OK, MMM is not 
     //================================================================= 
     if (ii < (lCSharpFormat.Length - 1) && 
      lCSharpFormat[ii + 1] == 'M') 
     { 
      if (ii < (lCSharpFormat.Length - 2) && 
      lCSharpFormat[ii + 2] == 'M') 
      { 
      //============================================================= 
      // MMM 
      //============================================================= 
      lError = true; 
      } 
      else 
      { 
      //============================================================= 
      // MM 
      //============================================================= 
      lJQueryFormat.Append("mm"); 
      ii++; 
      } 
     } 
     else 
     { 
      //=============================================================== 
      // M 
      //=============================================================== 
      lJQueryFormat.Append('m'); 
     } 
     break; 
     case 'y': 
     //================================================================= 
     // yy or yyyy is OK, y, yyy, or yyyyy is not 
     //================================================================= 
     if (ii < (lCSharpFormat.Length - 1) && 
      lCSharpFormat[ii + 1] == 'y') 
     { 
      if (ii < (lCSharpFormat.Length - 2) && 
      lCSharpFormat[ii + 2] == 'y') 
      { 
      if (ii < (lCSharpFormat.Length - 3) && 
       lCSharpFormat[ii + 3] == 'y') 
      { 
       if (ii < (lCSharpFormat.Length - 4) && 
       lCSharpFormat[ii + 4] == 'y') 
       { 
       //========================================================= 
       // yyyyy 
       //========================================================= 
       lError = true; 
       } 
       else 
       { 
       //========================================================= 
       // yyyy 
       //========================================================= 
       lJQueryFormat.Append("yy"); 
       ii = ii + 3; 
       } 
      } 
      else 
      { 
       //=========================================================== 
       // yyy 
       //=========================================================== 
       lError = true; 
      } 
      } 
      else 
      { 
      //============================================================= 
      // yy 
      //============================================================= 
      lJQueryFormat.Append("y"); 
      ii++; 
      } 
     } 
     else 
     { 
      //=============================================================== 
      // y 
      //=============================================================== 
      lError = true; 
     } 
     break; 
     case '.': 
     case '-': 
     case ' ': 
     case '/': 
     lJQueryFormat.Append(lCurrentChar); 
     break; 
     default: 
     lError = true; 
     break; 
    } 

    if (lError) 
    { 
     break; 
    } 
    } 

    //======================================================================= 
    // If we didn't get an error return the culture specific formats 
    //======================================================================= 
    if (!lError) 
    { 
    xoCSharpFormat = lCSharpFormat; 
    xoJQueryFormat = lJQueryFormat.ToString(); 
    } 
} 
+0

Sí, gracias por el código ... He estado pensando en escribir un código de conversión similar, pero por ahora acabo de utilizar el formato de fecha ISO en ambos lados. Supongo que usaré tu clase ahora. – mattanja

+0

Bueno, después de mirar más de cerca el código, me parece demasiado complicado: utilizar un manejo tan complejo solo sería justificable si se manejan TODOS los casos, incluidos los nombres de los meses y los días. Como el código provisto solo maneja ShortDatePattern, el código de reemplazo de cadena provisto en mi respuesta hará lo mismo en 4 líneas. ¿O extrañé el punto de tu código? – mattanja

+0

Es bastante grande porque es bastante defensivo y no quise extenderlo en el futuro (aunque dada la superposición limitada entre las cadenas de formato jQuery y MS que pueden no ser posibles). En el (probablemente poco probable) caso de que Microsoft agregara un formato de fecha corta que usaba ddd o MMM u otro carácter nuevo, el código simple se dejaría en letras extra mientras que el mío utilizaría su formato predeterminado. BTW Creo que podría acortar aún más su código eliminando el reemplazo de MM? – Dan

1

Creo que esta será la forma más fácil ...

string dateFormat = currentCultureInfo.DateTimeFormat.ShortDatePattern.Replace("MM", "mm"); 
string jsCode = @"$("".datepicker"").datepicker({ 
    dateFormat: '" + dateFormat + @"', 
});"; 
+0

¿Qué tal el formato de año diferente? Pero sí, si agrega un reemplazo para el formato del año, esta es una forma mucho más fácil que la respuesta de Dan. – mattanja

2

Lo uso para convertir de un formato de fecha y hora en .net a jQuery. Basada libremente en la respuesta de Dan:

/// <summary> 
/// Convert a .net date format to jQuery 
/// </summary> 
/// <param name="sFormat"></param> 
/// <returns></returns> 
private string ConvertDateFormatToJQuery(string sFormat) 
{ 
    if (string.IsNullOrEmpty(sFormat)) 
    { 
     return null; 
    } 

    StringBuilder sbOutput = new StringBuilder(""); 
    string sDatePartChars = "dDmMyY"; 

    char cLast = sFormat[0]; 
    StringBuilder sbDatePart = new StringBuilder(""); 

    //Loop through char by char, extracting each date part or whitespace/seperator into individual components, and convert each component as we go 
    foreach (char c in sFormat) 
    { 
     //Whitespace, or seperator 
     if (sDatePartChars.IndexOf(c) == -1) 
     { 
      //If there is a currently extracted date part, convert 
      sbOutput.Append(ConvertDatePartToJQuery(sbDatePart.ToString())); 
      sbDatePart.Clear(); 

      //Whitespace or serator, just append to output 
      sbOutput.Append(c.ToString()); 

      cLast = c; 
     } 
     else if (c.Equals(cLast)) 
     { 
      //Same date part, extract it 
      sbDatePart.Append(c.ToString()); 
     } 
     else 
     { 
      //We've come to the beginning of a new date part, convert the currently extracted date part 
      sbOutput.Append(ConvertDatePartToJQuery(sbDatePart.ToString())); 

      sbDatePart.Clear(); 
      sbDatePart.Append(c.ToString()); 
      cLast = c; 
     } 
    } 
    //Convert any remaining date part 
    sbOutput.Append(ConvertDatePartToJQuery(sbDatePart.ToString())); 
    return sbOutput.ToString(); 
} 

/// <summary> 
/// Converts a date part (month,day,year) to JQuery format. Unrecongized formats will just pass through 
/// </summary> 
/// <param name="sDatePart"></param> 
/// <returns></returns> 
private string ConvertDatePartToJQuery(string sDatePart) 
{ 
    //======================================================================= 
    // Handle: 
    // C#  jQuery Meaning 
    // d  d  Day of month (no leading 0) 
    // dd  dd  Day of month (leading 0) 
    // ddd D  Day name short 
    // dddd DD  Day name long 
    // M  m  Month of year (no leading 0) 
    // MM  mm  Month of year (leading 0) 
    // MMM M  Month name short 
    // MMMM MM  Month name long 
    // yy  y  Two digit year 
    // yyyy yy  Four digit year 
    //======================================================================= 

    string sJQueryDatePart = ""; 
    //We've come to the beginning of a new date part, convert the currently extracted date part 
    if (!string.IsNullOrEmpty(sDatePart)) 
    { 
     if (sDatePart[0] == 'M') 
     { 
      if (sDatePart.Length == 1) //Month, no leading 0 
      { 
       sJQueryDatePart = "m"; 
      } 
      else if (sDatePart.Length == 2) //Month, leading 0 
      { 
       sJQueryDatePart = "mm"; 
      } 
      else if (sDatePart.Length == 3) //Month, short name 
      { 
       sJQueryDatePart = "M"; 
      } 
      else if (sDatePart.Length == 4) //Month, long name 
      { 
       sJQueryDatePart = "MM"; 
      } 
      else 
      { 
       //invalid, just leave it 
       sJQueryDatePart = sDatePart; 
      } 
     } 
     else if (sDatePart[0] == 'd') 
     { 
      if (sDatePart.Length == 1) //Day, no leading 0 
      { 
       sJQueryDatePart = "d"; 
      } 
      else if (sDatePart.Length == 2) //Day, leading 0 
      { 
       sJQueryDatePart = "dd"; 
      } 
      else if (sDatePart.Length == 3) //Day, short name 
      { 
       sJQueryDatePart = "D"; 
      } 
      else if (sDatePart.Length == 4) //Day, long name 
      { 
       sJQueryDatePart = "DD"; 
      } 
      else 
      { 
       //invalid, just leave it 
       sJQueryDatePart = sDatePart; 
      } 
     } 
     else if (sDatePart[0] == 'y') 
     { 
      if (sDatePart.Length <= 2) //Year, two digit 
      { 
       sJQueryDatePart = "y"; 
      } 
      else if (sDatePart.Length > 2) //Year four digit 
      { 
       sJQueryDatePart = "yy"; 
      } 
      else 
      { 
       //invalid, just leave it 
       sJQueryDatePart = sDatePart; 
      } 
     } 
     else 
     { 
      //invalid, just leave it 
      sJQueryDatePart = sDatePart; 
     } 
    } 
    return sJQueryDatePart; 
}