Inledning
Det spelar ingen roll hur avancerade utvecklingsverktyg man har, det underlättar alltid att kunna formatera sin data korrekt. Oberoende om du utvecklar program i WPF, Silverlight, WinForms eller ASP så kommer du att ha nytta av att kunna styra formateringen av data.
ToString()
Alla objekt i .NET har metoden ToString(). Denna metod används när ett objekt skall konverteras till text. Tillsammans med en del grundläggande metoder i klassen string börjar vi med ett kort exempel som grund.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
int helTal = 7;
double flytTal = 3.1415;
string text = "En liten text";
string merText = "Tal: " + helTal + " Decimaltal: " + flytTal + " och: " + text;
Console.WriteLine(merText);
Console.WriteLine("Tal: {0} Decimaltal: {1} och: {2}", helTal, flytTal, text);
string formateradText = string.Format("Tal: {0} Decimaltal: {1} och: {2}",
helTal, flytTal, text);
Console.WriteLine(formateradText);
Console.ReadLine();
}
}
}
Mycket av detta är ren repetition från artikeln Stränghantering . Alla anrop till WriteLine() resulterar i samma utskrift.
På rad 16 bygger vi en sträng så som nybörjare oftast gör. Kompilatorn uppfattar det som +operation mellan strängar så variabler översätts automatiskt till text via ToString(). På rad 19 skriver vi ut igen fast denna gång med en formatsträng. WriteLine() kan användas direkt tillsammans med formatsträngar. {0} i strängen anger var första parametern efter formatsträngen skall in i utskriften. Detta är ett något "renare" sätt att styra utskrifter. Till sist, på rad 21, konstruerar vi en formaterad text på samma sätt som vi gjorde på rad 19. Skillnaden är att string.Format() används. Det är alltså så Console.WriteLine() fungerar på rad 19.
Denna artikel ska alltså göra en djupdykning i formateringen av strängar via string.Format() samt en beskrivning över hur de vanligaste datatyperna, t.ex. int, double, string och DateTime kan formateras via ToString(). Till sist också hur man kombinerar string.Format() och objektens ToString(). Jag lovar att du kommer ha nytta av detta inom alla inriktningar i .NET.
Formatering av DateTime
Datum och tider är oftast populära att formatera efter ett visst mönster. Vissa utskrifter är kulturellt beroende t.ex. "måndag" som på engelska/amerikanska skrivs ut som "Monday". Här följer en lång rad med exempel på formatering som kan användas på ToString() för DateTime. Resultaten (i kommentarerna) är på svenska.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
// skapa datum tid 2008-03-09 16:05:07.123
DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 123);
Console.WriteLine(dt.ToString("y yy yyy yyyy")); // "8 08 008 2008" år
Console.WriteLine(dt.ToString("M MM MMM MMMM")); // "3 03 Mar Mars" månad
Console.WriteLine(dt.ToString("d dd ddd dddd")); // "9 09 sö söndag" dag
Console.WriteLine(dt.ToString("h hh H HH")); // "4 04 16 16" timme 12/24
Console.WriteLine(dt.ToString("m mm")); // "5 05" minut
Console.WriteLine(dt.ToString("s ss")); // "7 07" sekund
Console.WriteLine(dt.ToString("f ff fff ffff")); // "1 12 123 1230" delar av sekund
Console.WriteLine(dt.ToString("F FF FFF FFFF")); // "1 12 123 123" utan nollor
Console.WriteLine(dt.ToString("z zz zzz")); // "+1 +01 +01:00" tidszon
Console.ReadLine();
}
}
}
Utöver dessa exempel på formatering så finns det även en lång rad med standardiserade format som har speciella kort-format tecken.
Tecken | DateTimeFormatInfo property | Mönster (för svensk kultur) |
---|---|---|
t | ShortTimePattern | HH:mm |
d | ShortDatePattern | yyyy-MM-dd |
T | LongTimePattern | HH:mm:ss |
D | LongDatePattern | den d MMMM, yyyy |
f | (combination of D and t) | den d MMMM, yyyy HH:mm |
F | FullDateTimePattern | den d MMMM, yyyy HH:mm:ss |
g | (combination of d and t) | yyyy-MM-dd HH:mm |
G | (combination of d and T) | yyyy-MM-dd HH:mm:ss |
m, M | MonthDayPattern | den d MMMM |
y, Y | YearMonthPattern | MMMM yyyy |
r, R | RFC1123Pattern | ddd, dd MMM yyyy HH':'mm':'ss 'GMT' (*) |
s | SortableDateTimePattern | yyyy'-'MM'-'dd'T'HH':'mm':'ss (*) |
u | UniversalSortableDateTimePattern | yyyy'-'MM'-'dd HH':'mm':'ss'Z' (*) |
(*) är kulturellt oberoende. Alla andra varianter är kulturellt beroende.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
// skapa datum tid 2008-03-09 16:05:07.123
DateTime dt = new DateTime(2008, 3, 9, 16, 5, 7, 123);
Console.WriteLine(dt.ToString("t")); // "16:05" ShortTime
Console.WriteLine(dt.ToString("d")); // "2008-03-09" ShortDate
Console.WriteLine(dt.ToString("T")); // "16:05:07" LongTime
Console.WriteLine(dt.ToString("D")); // "den 9 mars, 2008" LongDate
Console.WriteLine(dt.ToString("f")); // "den 9 mars, 2008 16:05" LongDate+ShortTime
Console.WriteLine(dt.ToString("F")); // "den 9 mars, 2008 16:05:07" FullDateTime
Console.WriteLine(dt.ToString("g")); // "2008-03-09 16:05" ShortDate+ShortTime
Console.WriteLine(dt.ToString("G")); // "2008-03-09 16:05:07" ShortDate+LongTime
Console.WriteLine(dt.ToString("m")); // "den 9 mars" MonthDay
Console.WriteLine(dt.ToString("y")); // "mars 2008" YearMonth
Console.WriteLine(dt.ToString("r")); // "Sun, 09 Mar 2008 16:05:07 GMT" RFC1123
Console.WriteLine(dt.ToString("s")); // "2008-03-09T16:05:07" SortableDateTime
Console.WriteLine(dt.ToString("u")); // "2008-03-09 16:05:07Z" UniversalSortableDateTime
Console.ReadLine();
}
}
}
Formatering av Tal
Vi börjar med formateringen av double, float och Decimal. Det går t.ex. att bestämma hur många siffror som skall visas före eller efter decimaltecknet. Kod säger mer än ord, vi tittar på följande exempel:
// följande:
Console.WriteLine(123.4567.ToString("0.00"));
// ger samma utskrift som:
Console.WriteLine("{0:0.00}", 123.4567);
// visa två decimaler
Console.WriteLine("{0:0.00}", 123.4567); // "123,46"
Console.WriteLine("{0:0.00}", 123.4); // "123,40"
Console.WriteLine("{0:0.00}", 123.0); // "123,00"
// minst två siffror före decimalpunkten
Console.WriteLine("{0:00.0}", 123.4567); // "123,5"
Console.WriteLine("{0:00.0}", 23.4567); // "23,5"
Console.WriteLine("{0:00.0}", 3.4567); // "03,5"
Console.WriteLine("{0:00.0}", -3.4567); // "-03,5"
// max. två decimaler
Console.WriteLine("{0:0.##}", 123.4567); // "123,46"
Console.WriteLine("{0:0.##}", 123.4); // "123,4"
Console.WriteLine("{0:0.##}", 123.0); // "123"
// formatering av tusental
Console.WriteLine("{0:0,0.0}", 12345.67); // "12 345,7"
Console.WriteLine("{0:0,0}", 12345.67); // "12 346"
Tidigare exempel har använt ToString() tillsammans med en formatsträng. Nu använder vi Console.WriteLine() med {0:format} där format är samma sträng som kan användas direkt med ToString(). Notera att vi får en automatisk avrundning om vi begränsar decimalerna via formatsträngen, 123.4567 blir 123.46 med endast två decimaler.
Vi kan även ta en till på hur decimaltal kring 0 kan formateras:
// exempel kring 0
Console.WriteLine("{0:0.0}", 0.0); // "0,0"
Console.WriteLine("{0:0.#}", 0.0); // "0"
Console.WriteLine("{0:#.0}", 0.0); // ",0"
Console.WriteLine("{0:#.#}", 0.0); // ""
// speciell hantering för negativa tal och 0
Console.WriteLine("{0:0.00;minus 0.00;zero}", 123.4567); // "123,46"
Console.WriteLine("{0:0.00;minus 0.00;zero}", -123.4567); // "minus 123,46"
Console.WriteLine("{0:0.00;minus 0.00;zero}", 0.0); // "zero"
I det sista exemplet så kan formateringen styras in i tre olika delar; över 0, under 0 och exakt 0. Detta görs genom att ange ; i formatsträngen.
För heltal, int, gäller samma formatregler förutom att heltal givetvis inte har några decimaler. Vi kan ta några exempel med heltal också:
// lägg till nollor före
Console.WriteLine("{0:00000}", 15); // "00015"
Console.WriteLine("{0:00000}", -15); // "-00015"
// hantering av minus och noll
Console.WriteLine("{0:#;minus #}", 15); // "15"
Console.WriteLine("{0:#;minus #}", -15); // "minus 15"
Console.WriteLine("{0:#;minus #;zero}", 0); // "zero"
// specialformatering
Console.WriteLine("{0:+## ### ### ###}", 467900123456); // "+46 900 123 456"
Console.WriteLine("{0:##-####-####}", 8958712551); // "89-5871-2551"
Anpassa texter
Via string.Format() eller Console.WriteLine() kan vi även styra höger/vänsterjustering vid formatering. På så vis kan vi enkelt skriva ut i prydliga kolumner.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
const string format = "{0,-10} | {1,-10} | {2,5}";
Console.WriteLine("-------------------------------");
Console.WriteLine("Förnamn | Efternamn | Ålder");
Console.WriteLine("-------------------------------");
Console.WriteLine(String.Format(format, "Oskar", "Svensson", 51));
Console.WriteLine(String.Format(format, "Kalle", "Karlsson", 9));
Console.WriteLine(String.Format(format, "Johnny", "Bråttom", 44));
Console.WriteLine("-------------------------------");
Console.WriteLine("Utskrivet: {0,20:g}", DateTime.Now);
Console.ReadLine();
}
}
}
Resultatet blir:
På rad 12 definierar vi en formatsträng som anger höger- och vänsterjusteringar. {0,-10} betyder att parameter 0 skall fyllas på med mellanslag (höger om) så att bredden blir 10, dvs. vänsterjustering. {2,5} anger parameter 2 med högerjustering, bredd 5 tecken. Sen kan man diskutera om - känns logiskt för normal vänsterjustering.
Ett komplett exempel på en formatsträng syns på rad 21. Förutom en vänsterjustering på 20 tecken så anges även en formatsträng (g) som skall användas på parameter 0. Tillsammans blir det en kraftfull formatering.
Underskatta inte nyttan av formatering för du vet inte när du kommer att ha nytta av den. Inom .NET är det samma format som hela tiden återkommer, t.ex. i ett Console Application eller i samband med "Databinding" i WPF. Det är även så att viss formatering återfinns i produkter som Microsoft Excel.