Swojego czasu z wielką radością odkryłem, iż biblioteka ASP.NET AJAX dostarcza genialne funkcje w JavaScript, działające dokładnie tak samo jak String.Format w .NET:
uzyskujemy oczekiwany tekst - np. "Aktualny miesiąc to luty 2009". Genialne, prawda?
Niestety, wersja JavaScript jest lekko upośledzonym odpowiednikiem swojego .NETowego brata :(. Po pierwsze, nie obsługuje wszystkich ciągów formatujących - to akurat można przeżyć. Po drugie, w języku polskim w przypadku dat popełnia błędy gramatyczne, co już jest większym problemem... Jakie błędy? Oto proste zestawienie:
Jak widać różnica dotyczy przypadku, w którym wyświetlany jest dzień i nazwa miesiąca. Poprawna jest wersja generowana przez metodę w .NET - "22 lutego 2009", czyli miesiąc powinien być w dopełniaczu. JavaScript używa niepoprawnego przypadku - mianownika ("22 luty 2009"). Najdziwniejsze w tym wszystkim jest to, że nic nie stało na przeszkodzie, aby formatowanie było poprawne. Dane dotyczące kultury zawierają nazwy miesięcy w dopełniaczu:
var __cultureInfo = '{"name":"pl-PL",
"numberFormat":{"CurrencyDecimalDigits":2,"CurrencyDecimalSeparator":",","IsReadOnly":true,"CurrencyGroupSizes":[3],"NumberGroupSizes":[3],"PercentGroupSizes":[3],"CurrencyGroupSeparator":" ","CurrencySymbol":"zł","NaNSymbol":"nie jest liczbą","CurrencyNegativePattern":8,"NumberNegativePattern":1,"PercentPositivePattern":1,"PercentNegativePattern":1,"NegativeInfinitySymbol":"-nieskończoność","NegativeSign":"-","NumberDecimalDigits":2,"NumberDecimalSeparator":",","NumberGroupSeparator":" ","CurrencyPositivePattern":3,"PositiveInfinitySymbol":"+nieskończoność","PositiveSign":"+","PercentDecimalDigits":2,"PercentDecimalSeparator":",","PercentGroupSeparator":" ","PercentSymbol":"%","PerMilleSymbol":"‰","NativeDigits":["0","1","2","3","4","5","6","7","8","9"],"DigitSubstitution":1},
"dateTimeFormat":{
"AMDesignator":"","Calendar":{"MinSupportedDateTime":"\/Date(-62135596800000)\/","MaxSupportedDateTime":"\/Date(253402297199999)\/","AlgorithmType":1,"CalendarType":1,"Eras":[1],"TwoDigitYearMax":2029,"IsReadOnly":true},"DateSeparator":"-","FirstDayOfWeek":1,"CalendarWeekRule":2,"FullDateTimePattern":"d MMMM yyyy HH:mm:ss","LongDatePattern":"d MMMM yyyy","LongTimePattern":"HH:mm:ss","MonthDayPattern":"d MMMM","PMDesignator":"","RFC1123Pattern":"ddd, dd MMM yyyy HH\u0027:\u0027mm\u0027:\u0027ss \u0027GMT\u0027","ShortDatePattern":"yyyy-MM-dd","ShortTimePattern":"HH:mm","SortableDateTimePattern":"yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss","TimeSeparator":":","UniversalSortableDateTimePattern":"yyyy\u0027-\u0027MM\u0027-\u0027dd HH\u0027:\u0027mm\u0027:\u0027ss\u0027Z\u0027","YearMonthPattern":"MMMM yyyy",
"AbbreviatedDayNames":["N","Pn","Wt","Śr","Cz","Pt","So"],
"ShortestDayNames":["N","Pn","Wt","Śr","Cz","Pt","So"],
"DayNames":["niedziela","poniedziałek","wtorek","środa","czwartek","piątek","sobota"],
"AbbreviatedMonthNames":["sty","lut","mar","kwi","maj","cze","lip","sie","wrz","paź","lis","gru",""],
"MonthNames":["styczeń","luty","marzec","kwiecień","maj","czerwiec","lipiec","sierpień","wrzesień","październik","listopad","grudzień",""],
"IsReadOnly":true,"NativeCalendarName":"Kalendarz gregoriański",
"AbbreviatedMonthGenitiveNames":["sty","lut","mar","kwi","maj","cze","lip","sie","wrz","paź","lis","gru",""],
"MonthGenitiveNames":["stycznia","lutego","marca","kwietnia","maja","czerwca","lipca","sierpnia","września","października","listopada","grudnia",""]}}';
Niestety, wartości z pola MonthGenitiveNames nie są nigdzie potem wykorzystywane w kodzie JavaScipt ASP.NET AJAX, co świadczy o pewnym niechlujstwie twórców biblioteki.