Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions snippets/fsharp/System/IFormatProvider/Overview/Provider.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
module Provider

// <Snippet2>
open System
open System.Globalization

type AcctNumberFormat() =
let [<Literal>] ACCT_LENGTH = 12

interface IFormatProvider with
member this.GetFormat(formatType: Type) =
if formatType = typeof<ICustomFormatter> then
this
else
null

interface ICustomFormatter with
member this.Format(fmt: string, arg: obj, formatProvider: IFormatProvider) =
// Provide default formatting if arg is not an Int64.
// Provide default formatting for unsupported format strings.
let ufmt = fmt.ToUpper CultureInfo.InvariantCulture
if arg.GetType() = typeof<Int64> && (ufmt = "H" || ufmt = "I") then
// Convert argument to a string.
let result = string arg

let result =
// If account number is less than 12 characters, pad with leading zeroes.
if result.Length < ACCT_LENGTH then
result.PadLeft(ACCT_LENGTH, '0')
else result

let result =
// If account number is more than 12 characters, truncate to 12 characters.
if result.Length > ACCT_LENGTH then
result.Substring(0, ACCT_LENGTH)
else result

// Integer-only format.
if ufmt = "I" then
result
// Add hyphens for H format specifier.
else // Hyphenated format.
result.Substring(0, 5) + "-" + result.Substring(5, 3) + "-" + result.Substring(8)
else
try
this.HandleOtherFormats(fmt, arg)
with :? FormatException as e ->
raise (FormatException($"The format of '{fmt}' is invalid.", e))

member _.HandleOtherFormats(format: string, arg: obj) =
match arg with
| :? IFormattable as arg ->
arg.ToString(format, CultureInfo.CurrentCulture)
| null ->
string arg
| _ ->
String.Empty
// </Snippet2>


// <Snippet1>
open System
open System.Globalization

type DaysOfWeek = Monday = 1 | Tuesday = 2

[<EntryPoint>]
let main _ =
let acctNumber = 104254567890L
let balance = 16.34
let wday = DaysOfWeek.Monday

let output =
String.Format(AcctNumberFormat(),
"On {2}, the balance of account {0:H} was {1:C2}.",
acctNumber, balance, wday)
printfn $"{output}"

let wday = DaysOfWeek.Tuesday
let output =
String.Format(AcctNumberFormat(),
"On {2}, the balance of account {0:I} was {1:C2}.",
acctNumber, balance, wday)
printfn $"{output}"
0

// The example displays the following output:
// On Monday, the balance of account 10425-456-7890 was $16.34.
// On Tuesday, the balance of account 104254567890 was $16.34.
// </Snippet1>

11 changes: 11 additions & 0 deletions snippets/fsharp/System/IFormatProvider/Overview/fs.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="provider2.fs" />
<Compile Include="Provider.fs" />
</ItemGroup>
</Project>
21 changes: 21 additions & 0 deletions snippets/fsharp/System/IFormatProvider/Overview/provider2.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module provider2

// <Snippet3>
open System
open System.Globalization

let dateValue = DateTime(2009, 6, 1, 16, 37, 0)
let cultures =
[ CultureInfo "en-US"
CultureInfo "fr-FR"
CultureInfo "it-IT"
CultureInfo "de-DE" ]

for culture in cultures do
printfn $"{culture.Name}: {dateValue.ToString culture}"
// The example displays the following output:
// en-US: 6/1/2009 4:37:00 PM
// fr-FR: 01/06/2009 16:37:00
// it-IT: 01/06/2009 16.37.00
// de-DE: 01.06.2009 16:37:00
// </Snippet3>
5 changes: 5 additions & 0 deletions xml/System/IFormatProvider.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,19 @@
The following example illustrates how an <xref:System.IFormatProvider> implementation can change the representation of a date and time value. In this case, a single date is displayed by using <xref:System.Globalization.CultureInfo> objects that represent four different cultures.

:::code language="csharp" source="~/snippets/csharp/System/IFormatProvider/Overview/provider2.cs" interactive="try-dotnet" id="Snippet3":::
:::code language="fsharp" source="~/snippets/fsharp/System/IFormatProvider/Overview/provider2.fs" id="Snippet3":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.IFormatProvider.Class/vb/provider2.vb" id="Snippet3":::

The following example illustrates the use of a class that implements the <xref:System.IFormatProvider> interface and the <xref:System.IFormatProvider.GetFormat%2A> method. The `AcctNumberFormat` class converts an <xref:System.Int64> value that represents an account number to a formatted 12-digit account number. Its `GetFormat` method returns a reference to the current `AcctNumberFormat` instance if the `formatType` parameter refers to a class that implements <xref:System.ICustomFormatter>; otherwise, `GetFormat` returns `null`.

:::code language="csharp" source="~/snippets/csharp/System/IFormatProvider/Overview/Provider.cs" id="Snippet2":::
:::code language="fsharp" source="~/snippets/fsharp/System/IFormatProvider/Overview/Provider.fs" id="Snippet2":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.IFormatProvider.Class/vb/Provider.vb" id="Snippet2":::

The class that implements <xref:System.IFormatProvider> can then be used in a call to a formatting and parsing operation. For example, the following code calls the <xref:System.String.Format%28System.IFormatProvider%2CSystem.String%2CSystem.Object%5B%5D%29?displayProperty=nameWithType> method to generate a string that contains a formatted 12-digit account number.

:::code language="csharp" source="~/snippets/csharp/System/IFormatProvider/Overview/Provider.cs" id="Snippet1":::
:::code language="fsharp" source="~/snippets/fsharp/System/IFormatProvider/Overview/Provider.fs" id="Snippet1":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.IFormatProvider.Class/vb/Provider.vb" id="Snippet1":::

]]></format>
Expand Down Expand Up @@ -148,11 +151,13 @@
The following example illustrates the use of a class that implements the <xref:System.IFormatProvider> interface and the <xref:System.IFormatProvider.GetFormat%2A> method. The `AcctNumberFormat` class converts an <xref:System.Int64> value that represents an account number to a formatted 12-digit account number. Its `GetFormat` method returns a reference to itself if the `formatType` parameter refers to a class that implements <xref:System.ICustomFormatter>; otherwise, `GetFormat` returns `null`.

:::code language="csharp" source="~/snippets/csharp/System/IFormatProvider/Overview/Provider.cs" id="Snippet2":::
:::code language="fsharp" source="~/snippets/fsharp/System/IFormatProvider/Overview/Provider.fs" id="Snippet2":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.IFormatProvider.Class/vb/Provider.vb" id="Snippet2":::

An instance of the `AcctNumberFormat` class can then be passed as an argument to a method that provides formatting or parsing services. For example, the following code passes an `AcctNumberFormat` class to the <xref:System.String.Format%28System.IFormatProvider%2CSystem.String%2CSystem.Object%5B%5D%29?displayProperty=nameWithType> method to generate a formatted 12-digit account number.

:::code language="csharp" source="~/snippets/csharp/System/IFormatProvider/Overview/Provider.cs" id="Snippet1":::
:::code language="fsharp" source="~/snippets/fsharp/System/IFormatProvider/Overview/Provider.fs" id="Snippet1":::
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.IFormatProvider.Class/vb/Provider.vb" id="Snippet1":::

]]></format>
Expand Down