Windows PowerShell Tip of the Week

Here’s a quick tip on working with Windows PowerShell. These are published every week for as long as we can come up with new tips. If you have a tip you’d like us to share or a question about how to do something, let us know.

Find more tips in the Windows PowerShell Tip of the Week archive.

Formatting Numbers and Dates Using the CultureInfo Object

You know, lately the topic of globalization and internationalization has been foremost in the Scripting Guys’ minds. (Why has the topic of globalization and internationalization been foremost in the Scripting Guys’ minds? It’s probably best that we don’t get into that.) Believe it or not, the Scripting Guys have always made an effort to reach an international audience; as a matter of fact, right around 60 percent of all the Script Center traffic comes from outside the US. But could we do even better than that? Heck no.

Wait, wait. Sorry; we meant to say, “Heck yes.” We can’t do much about translating Script Center articles into other languages; Scripting Guy Jean Ross does know a modest amount of Spanish, but Scripting Guy Greg Stemp can barely speak English. Still, we can show you how to format dates and numbers using standard formats found in various cultures.

Great moments in Scripting Guys history. When the Scripting Guys were in Barcelona for TechEd IT Forum, they stopped at a local pastry shop. As they paid for their purchase, the clerk asked (in Spanish) if they wanted to eat in the shop or take the order with them. Scripting Guy Jean Ross not only understood what the clerk was saying, but managed to answer back in Spanish. To this day that remains her crowning achievement as a Scripting Guy.

Come to think of it, that might be her only achievement as a Scripting Guy!

So what do we mean by “formatting dates and numbers using standard formats found in various cultures?” Let’s take a very simple example. Suppose we have the number 100 and we multiply it by 10.167. In the U.S., the resulting value might be expressed like this, with the comma serving as the thousands separator and the period functioning as the decimal point:

1,016.70

In Denmark, however, that same number would be formatted like so:

1.016,70

In other words, the period would serve as the thousands separator and the comma would act as the decimal point. Ay carumba!

The same thing holds true for dates. In the U.S., June 8, 2008 might be expressed like this, with the month listed before the day:

6/8/2008

In other countries, though, that same date might be listed with the day coming before the month:

8/6/2008

Ay carum – oh, right; we already said that, didn’t we?

Of course, as a script writer you have no control over that sort of stuff, do you? For example, suppose your script does some sort of calculation using American dollars. In turn, you use standard currency formatting to display that value, a value that’s going to look something like this:

$100

Unless you hard-code the dollar sign into the equation, however, there’s no guarantee that the value $100 will appear on every computer that runs your script; that’s because currency formatting is applied using the language and regional settings for each individual computer. Consequently, some computers will display the value like this:

-100

For better or worse (way worse, if you happen to be an American) 100 U.S. dollars and 100 euros are definitely not the same.

But, like we said, short of hard-coding in currency symbols and the like, what are you supposed to do about these different number and date formats? Well, here’s a suggestion: use Windows PowerShell and its ability to tap into the .NET Framework.

What do we mean by that? Well, we’ll show you. For starters, let’s use the following line of code to create an instance of the System.Globalization.CultureInfo class. But not just any instance of the System.Globalization.CultureInfo class; this class uses the language and regional settings for Danish (da-DK):

$a = New-Object System.Globalization.CultureInfo("da-DK")

Note. How did we know that da-DK represented Danish (Denmark Danish, to be specific)? Well, to tell you the truth, we didn’t. But that’s OK; we just looked it up.

So what does that do for us? Well, at the moment nothing. But now try this. Assign a value to another variable:

$b = 13.45

Now use the ToString method and the currency formatter (c) to display the value of $b as currency:

$b.ToString("c")

On a machine running U.S. English you should get the following:

$13.45

Nothing too surprising there, huh?

And that’s fine, unless that value isn’t supposed to be 13 American dollars (and 45 cents); for example, what if it’s supposed 13.45 in Danish krones? How the heck are you supposed to format your currency in Danish krones?

Beats us; we have no idea. But Windows PowerShell can do that for us:

$b.ToString("c", $a)

Notice what we’ve done here. We’re still using the ToString method, and we’re still asking PowerShell to display the value as currency. This time, however, we’ve added an optional second parameter: we’ve tacked on $a, the object reference to our Danish CultureInfo object. And now look at the output we get:

kr 13,45

Pretty nice, huh? Suppose these were British pounds, and $a referred to an English United Kingdom CultureInfo object (en-GB). In that case we’d get this output:

£13.45

Is that cool or what?

Not dealing with currency? That’s fine; here are some of the other formatting codes you can use, assuming we’re using the number 1329.78 and formatting the output to two decimal places:

Code

Description

US English Output

Danish Output

c

Currency

$1,329.78

kr 1.329,78

f

Floating point (decimal) values. Optionally, you can append a “precision specifier” after the f; the value f3 will display the value to 3 decimal places.

1329.78

1329,78

n

Standard numeric notation, including a thousands separator. Again, use the optional precision specifier to indicate the decimal places.

1,329.78

1.329,78

p

Percent. As usual, use the precision specifier to control the number of decimal places.

132,978.00 %

132.978,00 %

Note. For a more complete list of numeric formats, see the .NET Framework SDK.

Did we mention that this works with dates, too? Try running this little script and see what happens:

$a = New-Object System.Globalization.CultureInfo("da-DK")
$b = Get-Date
$b.ToString("d", $a)

You should get back the following, assuming the date is June 5, 2008:

05-06-2008

For your reading enjoyment here’s a list of date formats and the type of output you can expect to see under both U.S. English and Danish:

Code

Description

U.S. English Output

Danish Output

d

Short date pattern

6/5/2008

05-06-2008

D

Long date pattern

Thursday, June 05, 2008

5. juni 2008

f

Full date/time pattern (short time)

Thursday, June 05, 2008 4:40 PM

5. juni 2008 16:40

F

Full date/time pattern (long time)

Thursday, June 05, 2008 4:40:37 PM

5. juni 2008 16:40:37

g

General date/time pattern (short time)

6/5/2008 4:40 PM

05-06-2008 16:40

G

General date/time pattern (long time)

6/5/2008 4:40:37 PM

05-06-2008 16:40:37

m

Month day pattern

June 05

5. juni

o

Round-trip date/time pattern

2008-06-05T16:40:37.0000000-07:00

2008-06-05T16:40:37.0000000-07:00

r

RFC1123 pattern

Thu, 05 Jun 2008 16:40:37 GMT

Thu, 05 Jun 2008 16:40:37 GMT

s

Sortable date/time pattern; conforms to ISO 8601

2008-06-05T16:40:37

2008-06-05T16:40:37

t

Short time pattern

4:40 PM

16:40

T

Long time pattern

4:40:37 PM

16:40:37

u

Universal sortable date/time pattern

2008-06-05 16:40:37Z

Thursday, June 05, 2008 11:40:37 PM

U

Universal sortable date/time pattern

2008-06-05 16:40:37Z

5. juni 2008 23:40:37

y

Year month pattern

June, 2008

juni 2008

It doesn’t get any better than that, does it?

That’s all we have time for this week, which means we must bid you all adieu. In turn that means … well, to tell you the truth, we’re not sure what that means. We’ll try to find out before next week. See you all then.