Witaj na Zine.net online Zaloguj się | Rejestracja | Pomoc

String.Format() w .NET i JavaScript (ASP.NET AJAX)

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:

  • String.format(format, args) - formatuje tekst,
  • String.localeFormat - formatuje tekst używając bieżącej kultury UI (w ScriptManager należy dać EnableScriptGlobalization="true" oraz wybrać odpowiednią kulturę na poziomie strony lub aplikacji).

Innymi słowy pisząc w BLOCKED SCRIPT

String.formatLocale("Aktualny miesiąc to {0:MMMM yyyy}", new Date())

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:

Format .NET JavaScript
d 2009-02-22 2009-02-22
D 22 lutego 2009 22 luty 2009
f 22 lutego 2009 22:07 -
F 22 lutego 2009 22:07:19 22 luty 2009 22:07:20
g 2009-02-22 22:07 -
G 2009-02-22 22:07:19 -
M 22 lutego 22 luty
O 2009-02-22T22:07:19.9917540+01:00 -
R Sun, 22 Feb 2009 22:07:19 GMT -
s 2009-02-22T22:07:19 2009-02-22T22:07:20
t 22:07 22:07
T 22:07:19 22:07:20
u 2009-02-22 22:07:19Z -
U 22 lutego 2009 21:07:19 -
Y luty 2009 luty 2009
MMMM luty luty
d MMMM yyyy 22 lutego 2009 22 luty 2009
MMMM yyyy luty 2009 luty 2009

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.

Opublikowane 22 lutego 2009 23:07 przez jakubin
Filed under: , , ,

Komentarze:

# re: String.Format() w .NET i JavaScript (ASP.NET AJAX)

Wszystko wskazuje na to, że faktycznie doszło do pomyłki programistów. Moim zdaniem warto to zgłosić jako buga na Connect, a niechaj narodowie wżdy postronni znają...

P.S. "BLOCKED SCRIPT" zaatakował ponownie.

22 lutego 2009 23:53 by apl

# re: String.Format() w .NET i JavaScript (ASP.NET AJAX)

23 lutego 2009 20:56 by jakubin

# re: String.Format() w .NET i JavaScript (ASP.NET AJAX)

Ajax jest dobrym narzędziem. Jestem w nim początkującym. Pociągnąłem moduł do obsługi MySQL i PHP. Mam zamiar do niego zasiąść.

9 marca 2009 22:44 by kaminskp
Komentarze anonimowe wyłączone

About jakubin

MVP w kategorii C#, MCP. Aktualnie pracuje w Webstruments.pl jako programista C#.