diff --git a/docs/fundamentals/runtime-libraries/includes/c-and-posix-cultures.md b/docs/fundamentals/runtime-libraries/includes/c-and-posix-cultures.md
new file mode 100644
index 0000000000000..1f96cbf12117c
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/includes/c-and-posix-cultures.md
@@ -0,0 +1,2 @@
+> [!NOTE]
+> **.NET Core running on Linux and macOS systems only:** The collation behavior for the C and Posix cultures is always case-sensitive because these cultures do not use the expected Unicode collation order. We recommend that you use a culture other than C or Posix for performing culture-sensitive, case-insensitive sorting operations.
diff --git a/docs/fundamentals/runtime-libraries/includes/context.md b/docs/fundamentals/runtime-libraries/includes/context.md
new file mode 100644
index 0000000000000..89814007b303e
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/includes/context.md
@@ -0,0 +1 @@
+This article provides supplementary remarks to the reference documentation for this API.
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/appdomainex1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/appdomainex1.cs
new file mode 100644
index 0000000000000..eac16aea7ba8c
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/appdomainex1.cs
@@ -0,0 +1,77 @@
+//
+using System;
+using System.Globalization;
+
+public class Example
+{
+ public static void Main()
+ {
+ // Set the default culture and display the current date in the current application domain.
+ Info info1 = new Info();
+ SetAppDomainCultures("fr-FR");
+
+ // Create a second application domain.
+ AppDomainSetup setup = new AppDomainSetup();
+ setup.AppDomainInitializer = SetAppDomainCultures;
+ setup.AppDomainInitializerArguments = new string[] { "ru-RU" };
+ AppDomain domain = AppDomain.CreateDomain("Domain2", null, setup);
+ // Create an Info object in the new application domain.
+ Info info2 = (Info)domain.CreateInstanceAndUnwrap(typeof(Example).Assembly.FullName,
+ "Info");
+
+ // Execute methods in the two application domains.
+ info2.DisplayDate();
+ info2.DisplayCultures();
+
+ info1.DisplayDate();
+ info1.DisplayCultures();
+ }
+
+ public static void SetAppDomainCultures(string[] names)
+ {
+ SetAppDomainCultures(names[0]);
+ }
+
+ public static void SetAppDomainCultures(string name)
+ {
+ try
+ {
+ CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture(name);
+ CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture(name);
+ }
+ // If an exception occurs, we'll just fall back to the system default.
+ catch (CultureNotFoundException)
+ {
+ return;
+ }
+ catch (ArgumentException)
+ {
+ return;
+ }
+ }
+}
+
+public class Info : MarshalByRefObject
+{
+ public void DisplayDate()
+ {
+ Console.WriteLine("Today is {0:D}", DateTime.Now);
+ }
+
+ public void DisplayCultures()
+ {
+ Console.WriteLine("Application domain is {0}", AppDomain.CurrentDomain.Id);
+ Console.WriteLine("Default Culture: {0}", CultureInfo.DefaultThreadCurrentCulture);
+ Console.WriteLine("Default UI Culture: {0}", CultureInfo.DefaultThreadCurrentUICulture);
+ }
+}
+// The example displays the following output:
+// Today is 14 октября 2011 г.
+// Application domain is 2
+// Default Culture: ru-RU
+// Default UI Culture: ru-RU
+// Today is vendredi 14 octobre 2011
+// Application domain is 1
+// Default Culture: fr-FR
+// Default UI Culture: fr-FR
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/asyncculture1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/asyncculture1.cs
new file mode 100644
index 0000000000000..bda34aac05faa
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/asyncculture1.cs
@@ -0,0 +1,66 @@
+//
+using System;
+using System.Globalization;
+using System.Threading;
+using System.Threading.Tasks;
+
+public class AsyncCultureEx1
+{
+ public static void Main()
+ {
+ decimal[] values = { 163025412.32m, 18905365.59m };
+ string formatString = "C2";
+
+ string FormatDelegate()
+ {
+ string output = $"Formatting using the {CultureInfo.CurrentCulture.Name} " +
+ "culture on thread {Thread.CurrentThread.ManagedThreadId}.\n";
+ foreach (decimal value in values)
+ output += $"{value.ToString(formatString)} ";
+
+ output += Environment.NewLine;
+ return output;
+ }
+
+ Console.WriteLine($"The example is running on thread {Thread.CurrentThread.ManagedThreadId}");
+ // Make the current culture different from the system culture.
+ Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
+ if (CultureInfo.CurrentCulture.Name == "fr-FR")
+ Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
+ else
+ Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
+
+ Console.WriteLine($"Changed the current culture to {CultureInfo.CurrentCulture.Name}.\n");
+
+ // Execute the delegate synchronously.
+ Console.WriteLine("Executing the delegate synchronously:");
+ Console.WriteLine(FormatDelegate());
+
+ // Call an async delegate to format the values using one format string.
+ Console.WriteLine("Executing a task asynchronously:");
+ var t1 = Task.Run(FormatDelegate);
+ Console.WriteLine(t1.Result);
+
+ Console.WriteLine("Executing a task synchronously:");
+ var t2 = new Task(FormatDelegate);
+ t2.RunSynchronously();
+ Console.WriteLine(t2.Result);
+ }
+}
+// The example displays the following output:
+// The example is running on thread 1
+// The current culture is en-US
+// Changed the current culture to fr-FR.
+//
+// Executing the delegate synchronously:
+// Formatting using the fr-FR culture on thread 1.
+// 163 025 412,32 € 18 905 365,59 €
+//
+// Executing a task asynchronously:
+// Formatting using the fr-FR culture on thread 3.
+// 163 025 412,32 € 18 905 365,59 €
+//
+// Executing a task synchronously:
+// Formatting using the fr-FR culture on thread 1.
+// 163 025 412,32 € 18 905 365,59 €
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/asyncculture3.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/asyncculture3.cs
new file mode 100644
index 0000000000000..743c06454f6c0
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/asyncculture3.cs
@@ -0,0 +1,70 @@
+//
+using System;
+using System.Globalization;
+using System.Threading;
+using System.Threading.Tasks;
+
+public class AsyncCultureEx3
+{
+ public static void Main()
+ {
+ decimal[] values = { 163025412.32m, 18905365.59m };
+ string formatString = "C2";
+ Func formatDelegate = () =>
+ {
+ string output = String.Format("Formatting using the {0} culture on thread {1}.\n",
+ CultureInfo.CurrentCulture.Name,
+ Thread.CurrentThread.ManagedThreadId);
+ foreach (var value in values)
+ output += String.Format("{0} ", value.ToString(formatString));
+
+ output += Environment.NewLine;
+ return output;
+ };
+
+ Console.WriteLine("The example is running on thread {0}",
+ Thread.CurrentThread.ManagedThreadId);
+ // Make the current culture different from the system culture.
+ Console.WriteLine("The current culture is {0}",
+ CultureInfo.CurrentCulture.Name);
+ if (CultureInfo.CurrentCulture.Name == "fr-FR")
+ Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
+ else
+ Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
+
+ Console.WriteLine("Changed the current culture to {0}.\n",
+ CultureInfo.CurrentCulture.Name);
+ CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CurrentCulture;
+
+ // Execute the delegate synchronously.
+ Console.WriteLine("Executing the delegate synchronously:");
+ Console.WriteLine(formatDelegate());
+
+ // Call an async delegate to format the values using one format string.
+ Console.WriteLine("Executing a task asynchronously:");
+ var t1 = Task.Run(formatDelegate);
+ Console.WriteLine(t1.Result);
+
+ Console.WriteLine("Executing a task synchronously:");
+ var t2 = new Task(formatDelegate);
+ t2.RunSynchronously();
+ Console.WriteLine(t2.Result);
+ }
+}
+// The example displays the following output:
+// The example is running on thread 1
+// The current culture is en-US
+// Changed the current culture to fr-FR.
+//
+// Executing the delegate synchronously:
+// Formatting using the fr-FR culture on thread 1.
+// 163 025 412,32 € 18 905 365,59 €
+//
+// Executing a task asynchronously:
+// Formatting using the fr-FR culture on thread 3.
+// 163 025 412,32 € 18 905 365,59 €
+//
+// Executing a task synchronously:
+// Formatting using the fr-FR culture on thread 1.
+// 163 025 412,32 € 18 905 365,59 €
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/change1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/change1.cs
new file mode 100644
index 0000000000000..f079c787e387d
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/change1.cs
@@ -0,0 +1,25 @@
+//
+using System;
+using System.Globalization;
+
+public class ChangeEx1
+{
+ public static void Main()
+ {
+ CultureInfo current = CultureInfo.CurrentCulture;
+ Console.WriteLine("The current culture is {0}", current.Name);
+ CultureInfo newCulture;
+ if (current.Name.Equals("fr-FR"))
+ newCulture = new CultureInfo("fr-LU");
+ else
+ newCulture = new CultureInfo("fr-FR");
+
+ CultureInfo.CurrentCulture = newCulture;
+ Console.WriteLine("The current culture is now {0}",
+ CultureInfo.CurrentCulture.Name);
+ }
+}
+// The example displays output like the following:
+// The current culture is en-US
+// The current culture is now fr-FR
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/changeui1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/changeui1.cs
new file mode 100644
index 0000000000000..6db5a3d52494d
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/changeui1.cs
@@ -0,0 +1,25 @@
+//
+using System;
+using System.Globalization;
+
+public class ChangeUICultureEx
+{
+ public static void Main()
+ {
+ CultureInfo current = CultureInfo.CurrentUICulture;
+ Console.WriteLine("The current UI culture is {0}", current.Name);
+ CultureInfo newUICulture;
+ if (current.Name.Equals("sl-SI"))
+ newUICulture = new CultureInfo("hr-HR");
+ else
+ newUICulture = new CultureInfo("sl-SI");
+
+ CultureInfo.CurrentUICulture = newUICulture;
+ Console.WriteLine("The current UI culture is now {0}",
+ CultureInfo.CurrentUICulture.Name);
+ }
+}
+// The example displays output like the following:
+// The current UI culture is en-US
+// The current UI culture is now sl-SI
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/current1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/current1.cs
new file mode 100644
index 0000000000000..fe3a1587f5a9d
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/current1.cs
@@ -0,0 +1,20 @@
+//
+using System;
+using System.Globalization;
+using System.Threading;
+
+public class CurrentCultureEx
+{
+ public static void Main()
+ {
+ CultureInfo culture1 = CultureInfo.CurrentCulture;
+ CultureInfo culture2 = Thread.CurrentThread.CurrentCulture;
+ Console.WriteLine("The current culture is {0}", culture1.Name);
+ Console.WriteLine("The two CultureInfo objects are equal: {0}",
+ culture1 == culture2);
+ }
+}
+// The example displays output like the following:
+// The current culture is en-US
+// The two CultureInfo objects are equal: True
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/currentui1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/currentui1.cs
new file mode 100644
index 0000000000000..82c3347a4d2cb
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/currentui1.cs
@@ -0,0 +1,20 @@
+//
+using System;
+using System.Globalization;
+using System.Threading;
+
+public class CurrentUIEx
+{
+ public static void Main()
+ {
+ CultureInfo uiCulture1 = CultureInfo.CurrentUICulture;
+ CultureInfo uiCulture2 = Thread.CurrentThread.CurrentUICulture;
+ Console.WriteLine("The current UI culture is {0}", uiCulture1.Name);
+ Console.WriteLine("The two CultureInfo objects are equal: {0}",
+ uiCulture1 == uiCulture2);
+ }
+}
+// The example displays output like the following:
+// The current UI culture is en-US
+// The two CultureInfo objects are equal: True
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/defaultthread1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/defaultthread1.cs
new file mode 100644
index 0000000000000..9edecf6f2e45a
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/defaultthread1.cs
@@ -0,0 +1,70 @@
+//
+using System;
+using System.Globalization;
+using System.Threading;
+
+public class DefaultThreadEx
+{
+ static Random rnd = new Random();
+
+ public static void Main()
+ {
+ if (Thread.CurrentThread.CurrentCulture.Name != "fr-FR")
+ {
+ // If current culture is not fr-FR, set culture to fr-FR.
+ Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
+ Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
+ }
+ else
+ {
+ // Set culture to en-US.
+ Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
+ Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
+ }
+ ThreadProc();
+
+ Thread worker = new Thread(ThreadProc);
+ worker.Name = "WorkerThread";
+ worker.Start();
+ }
+
+ private static void DisplayThreadInfo()
+ {
+ Console.WriteLine("\nCurrent Thread Name: '{0}'",
+ Thread.CurrentThread.Name);
+ Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}",
+ Thread.CurrentThread.CurrentCulture.Name,
+ Thread.CurrentThread.CurrentUICulture.Name);
+ }
+
+ private static void DisplayValues()
+ {
+ // Create new thread and display three random numbers.
+ Console.WriteLine("Some currency values:");
+ for (int ctr = 0; ctr <= 3; ctr++)
+ Console.WriteLine(" {0:C2}", rnd.NextDouble() * 10);
+ }
+
+ private static void ThreadProc()
+ {
+ DisplayThreadInfo();
+ DisplayValues();
+ }
+}
+// The example displays output similar to the following:
+// Current Thread Name: ''
+// Current Thread Culture/UI Culture: fr-FR/fr-FR
+// Some currency values:
+// 8,11 €
+// 1,48 €
+// 8,99 €
+// 9,04 €
+//
+// Current Thread Name: 'WorkerThread'
+// Current Thread Culture/UI Culture: en-US/en-US
+// Some currency values:
+// $6.72
+// $6.35
+// $2.90
+// $7.72
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/getcultures1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/getcultures1.cs
new file mode 100644
index 0000000000000..9b876f3d32c4a
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/getcultures1.cs
@@ -0,0 +1,44 @@
+//
+using System;
+using System.Globalization;
+
+public class GetCulturesEx
+{
+ public static void Main()
+ {
+ // Get all custom cultures.
+ CultureInfo[] custom = CultureInfo.GetCultures(CultureTypes.UserCustomCulture);
+ if (custom.Length == 0)
+ {
+ Console.WriteLine("There are no user-defined custom cultures.");
+ }
+ else
+ {
+ Console.WriteLine("Custom cultures:");
+ foreach (var culture in custom)
+ Console.WriteLine(" {0} -- {1}", culture.Name, culture.DisplayName);
+ }
+ Console.WriteLine();
+
+ // Get all replacement cultures.
+ CultureInfo[] replacements = CultureInfo.GetCultures(CultureTypes.ReplacementCultures);
+ if (replacements.Length == 0)
+ {
+ Console.WriteLine("There are no replacement cultures.");
+ }
+ else
+ {
+ Console.WriteLine("Replacement cultures:");
+ foreach (var culture in replacements)
+ Console.WriteLine(" {0} -- {1}", culture.Name, culture.DisplayName);
+ }
+ Console.WriteLine();
+ }
+}
+// The example displays output like the following:
+// Custom cultures:
+// x-en-US-sample -- English (United States)
+// fj-FJ -- Boumaa Fijian (Viti)
+//
+// There are no replacement cultures.
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/project.csproj b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/project.csproj
new file mode 100644
index 0000000000000..2508cb7fae22e
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/project.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Library
+ net481
+
+
+
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/setthreads1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/setthreads1.cs
new file mode 100644
index 0000000000000..2d0eede894a5f
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/CultureInfo/csharp/setthreads1.cs
@@ -0,0 +1,70 @@
+//
+using System;
+using System.Globalization;
+using System.Threading;
+
+public class SetThreadsEx
+{
+ static Random rnd = new Random();
+
+ public static void Main()
+ {
+ if (Thread.CurrentThread.CurrentCulture.Name != "fr-FR")
+ {
+ // If current culture is not fr-FR, set culture to fr-FR.
+ CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
+ CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
+ }
+ else
+ {
+ // Set culture to en-US.
+ CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
+ CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
+ }
+ ThreadProc();
+
+ Thread worker = new Thread(SetThreadsEx.ThreadProc);
+ worker.Name = "WorkerThread";
+ worker.Start();
+ }
+
+ private static void DisplayThreadInfo()
+ {
+ Console.WriteLine("\nCurrent Thread Name: '{0}'",
+ Thread.CurrentThread.Name);
+ Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}",
+ Thread.CurrentThread.CurrentCulture.Name,
+ Thread.CurrentThread.CurrentUICulture.Name);
+ }
+
+ private static void DisplayValues()
+ {
+ // Create new thread and display three random numbers.
+ Console.WriteLine("Some currency values:");
+ for (int ctr = 0; ctr <= 3; ctr++)
+ Console.WriteLine(" {0:C2}", rnd.NextDouble() * 10);
+ }
+
+ private static void ThreadProc()
+ {
+ DisplayThreadInfo();
+ DisplayValues();
+ }
+}
+// The example displays output similar to the following:
+// Current Thread Name: ''
+// Current Thread Culture/UI Culture: fr-FR/fr-FR
+// Some currency values:
+// 6,83 €
+// 3,47 €
+// 6,07 €
+// 1,70 €
+//
+// Current Thread Name: 'WorkerThread'
+// Current Thread Culture/UI Culture: fr-FR/fr-FR
+// Some currency values:
+// 9,54 €
+// 9,50 €
+// 0,58 €
+// 6,91 €
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/create1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/create1.cs
new file mode 100644
index 0000000000000..12d26afd04c38
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/create1.cs
@@ -0,0 +1,112 @@
+using System;
+
+public class Example
+{
+ public static void Main()
+ {
+ CreateInvariant1();
+ Console.WriteLine();
+ CreateNeutral2();
+ Console.WriteLine();
+ CreateSpecific3();
+ }
+
+ private static void CreateInvariant1()
+ {
+ //
+ System.Globalization.DateTimeFormatInfo dtfi;
+
+ dtfi = System.Globalization.DateTimeFormatInfo.InvariantInfo;
+ Console.WriteLine(dtfi.IsReadOnly);
+
+ dtfi = new System.Globalization.DateTimeFormatInfo();
+ Console.WriteLine(dtfi.IsReadOnly);
+
+ dtfi = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat;
+ Console.WriteLine(dtfi.IsReadOnly);
+ // The example displays the following output:
+ // True
+ // False
+ // True
+ //
+ }
+
+ private static void CreateNeutral2()
+ {
+ //
+ System.Globalization.CultureInfo specific, neutral;
+ System.Globalization.DateTimeFormatInfo dtfi;
+
+ // Instantiate a culture by creating a specific culture and using its Parent property.
+ specific = System.Globalization.CultureInfo.GetCultureInfo("fr-FR");
+ neutral = specific.Parent;
+ dtfi = neutral.DateTimeFormat;
+ Console.WriteLine("{0} from Parent property: {1}", neutral.Name, dtfi.IsReadOnly);
+
+ dtfi = System.Globalization.CultureInfo.GetCultureInfo("fr-FR").Parent.DateTimeFormat;
+ Console.WriteLine("{0} from Parent property: {1}", neutral.Name, dtfi.IsReadOnly);
+
+ // Instantiate a neutral culture using the CultureInfo constructor.
+ neutral = new System.Globalization.CultureInfo("fr");
+ dtfi = neutral.DateTimeFormat;
+ Console.WriteLine("{0} from CultureInfo constructor: {1}", neutral.Name, dtfi.IsReadOnly);
+
+ // Instantiate a culture using CreateSpecificCulture.
+ neutral = System.Globalization.CultureInfo.CreateSpecificCulture("fr");
+ dtfi = neutral.DateTimeFormat;
+ Console.WriteLine("{0} from CreateSpecificCulture: {1}", neutral.Name, dtfi.IsReadOnly);
+
+ // Retrieve a culture by calling the GetCultureInfo method.
+ neutral = System.Globalization.CultureInfo.GetCultureInfo("fr");
+ dtfi = neutral.DateTimeFormat;
+ Console.WriteLine("{0} from GetCultureInfo: {1}", neutral.Name, dtfi.IsReadOnly);
+
+ // Instantiate a DateTimeFormatInfo object by calling GetInstance.
+ neutral = System.Globalization.CultureInfo.CreateSpecificCulture("fr");
+ dtfi = System.Globalization.DateTimeFormatInfo.GetInstance(neutral);
+ Console.WriteLine("{0} from GetInstance: {1}", neutral.Name, dtfi.IsReadOnly);
+
+ // The example displays the following output:
+ // fr from Parent property: False
+ // fr from Parent property: False
+ // fr from CultureInfo constructor: False
+ // fr-FR from CreateSpecificCulture: False
+ // fr from GetCultureInfo: True
+ // fr-FR from GetInstance: False
+ //
+ }
+
+ private static void CreateSpecific3()
+ {
+ //
+ System.Globalization.CultureInfo ci = null;
+ System.Globalization.DateTimeFormatInfo dtfi = null;
+
+ // Instantiate a culture using CreateSpecificCulture.
+ ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-US");
+ dtfi = ci.DateTimeFormat;
+ Console.WriteLine("{0} from CreateSpecificCulture: {1}", ci.Name, dtfi.IsReadOnly);
+
+ // Instantiate a culture using the CultureInfo constructor.
+ ci = new System.Globalization.CultureInfo("en-CA");
+ dtfi = ci.DateTimeFormat;
+ Console.WriteLine("{0} from CultureInfo constructor: {1}", ci.Name, dtfi.IsReadOnly);
+
+ // Retrieve a culture by calling the GetCultureInfo method.
+ ci = System.Globalization.CultureInfo.GetCultureInfo("en-AU");
+ dtfi = ci.DateTimeFormat;
+ Console.WriteLine("{0} from GetCultureInfo: {1}", ci.Name, dtfi.IsReadOnly);
+
+ // Instantiate a DateTimeFormatInfo object by calling DateTimeFormatInfo.GetInstance.
+ ci = System.Globalization.CultureInfo.CreateSpecificCulture("en-GB");
+ dtfi = System.Globalization.DateTimeFormatInfo.GetInstance(ci);
+ Console.WriteLine("{0} from GetInstance: {1}", ci.Name, dtfi.IsReadOnly);
+
+ // The example displays the following output:
+ // en-US from CreateSpecificCulture: False
+ // en-CA from CultureInfo constructor: False
+ // en-AU from GetCultureInfo: True
+ // en-GB from GetInstance: False
+ //
+ }
+}
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/create2.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/create2.cs
new file mode 100644
index 0000000000000..01e02d14e15c0
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/create2.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Globalization;
+
+public class Create2Ex
+{
+ public static void Main()
+ {
+ //
+ DateTimeFormatInfo dtfi;
+
+ dtfi = DateTimeFormatInfo.CurrentInfo;
+ Console.WriteLine(dtfi.IsReadOnly);
+
+ dtfi = CultureInfo.CurrentCulture.DateTimeFormat;
+ Console.WriteLine(dtfi.IsReadOnly);
+
+ dtfi = DateTimeFormatInfo.GetInstance(CultureInfo.CurrentCulture);
+ Console.WriteLine(dtfi.IsReadOnly);
+ // The example displays the following output:
+ // True
+ // True
+ // True
+ //
+ }
+}
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example1.cs
new file mode 100644
index 0000000000000..04262e40ad837
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example1.cs
@@ -0,0 +1,30 @@
+//
+using System;
+using System.Globalization;
+
+public class Example1
+{
+ public static void Main()
+ {
+ DateTime dateValue = new DateTime(2013, 8, 18);
+ CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
+ DateTimeFormatInfo dtfi = enUS.DateTimeFormat;
+
+ Console.WriteLine("Before modifying DateTimeFormatInfo object: ");
+ Console.WriteLine("{0}: {1}\n", dtfi.ShortDatePattern,
+ dateValue.ToString("d", enUS));
+
+ // Modify the short date pattern.
+ dtfi.ShortDatePattern = "yyyy-MM-dd";
+ Console.WriteLine("After modifying DateTimeFormatInfo object: ");
+ Console.WriteLine("{0}: {1}", dtfi.ShortDatePattern,
+ dateValue.ToString("d", enUS));
+ }
+}
+// The example displays the following output:
+// Before modifying DateTimeFormatInfo object:
+// M/d/yyyy: 8/18/2013
+//
+// After modifying DateTimeFormatInfo object:
+// yyyy-MM-dd: 2013-08-18
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example2.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example2.cs
new file mode 100644
index 0000000000000..6f4e5ddea758d
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example2.cs
@@ -0,0 +1,39 @@
+//
+using System;
+using System.Globalization;
+
+public class Example2
+{
+ public static void Main()
+ {
+ DateTime value = new DateTime(2013, 7, 9);
+ CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
+ DateTimeFormatInfo dtfi = enUS.DateTimeFormat;
+ String[] formats = { "D", "F", "f" };
+
+ // Display date before modifying properties.
+ foreach (var fmt in formats)
+ Console.WriteLine("{0}: {1}", fmt, value.ToString(fmt, dtfi));
+
+ Console.WriteLine();
+
+ // We don't want to change the FullDateTimePattern, so we need to save it.
+ String originalFullDateTimePattern = dtfi.FullDateTimePattern;
+
+ // Modify day name abbreviations and long date pattern.
+ dtfi.AbbreviatedDayNames = new String[] { "Su", "M", "Tu", "W", "Th", "F", "Sa" };
+ dtfi.LongDatePattern = "ddd dd-MMM-yyyy";
+ dtfi.FullDateTimePattern = originalFullDateTimePattern;
+ foreach (var fmt in formats)
+ Console.WriteLine("{0}: {1}", fmt, value.ToString(fmt, dtfi));
+ }
+}
+// The example displays the following output:
+// D: Tuesday, July 9, 2013
+// F: Tuesday, July 9, 2013 12:00:00 AM
+// f: Tuesday, July 9, 2013 12:00 AM
+//
+// D: Tu 09-Jul-2013
+// F: Tuesday, July 9, 2013 12:00:00 AM
+// f: Tu 09-Jul-2013 12:00 AM
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example3.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example3.cs
new file mode 100644
index 0000000000000..5f78c7499ddbc
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example3.cs
@@ -0,0 +1,25 @@
+//
+using System;
+using System.Globalization;
+
+public class Example3
+{
+ public static void Main()
+ {
+ DateTime dateValue = new DateTime(2013, 08, 28);
+ CultureInfo frFR = CultureInfo.CreateSpecificCulture("fr-FR");
+ DateTimeFormatInfo dtfi = frFR.DateTimeFormat;
+
+ Console.WriteLine("Before modifying DateSeparator property: {0}",
+ dateValue.ToString("g", frFR));
+
+ // Modify the date separator.
+ dtfi.DateSeparator = "-";
+ Console.WriteLine("After modifying the DateSeparator property: {0}",
+ dateValue.ToString("g", frFR));
+ }
+}
+// The example displays the following output:
+// Before modifying DateSeparator property: 28/08/2013 00:00
+// After modifying the DateSeparator property: 28-08-2013 00:00
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example4.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example4.cs
new file mode 100644
index 0000000000000..14f4fc8140451
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example4.cs
@@ -0,0 +1,47 @@
+//
+using System;
+using System.Globalization;
+
+public class Example4
+{
+ public static void Main()
+ {
+ DateTime dateValue = new DateTime(2013, 5, 18, 13, 30, 0);
+ String[] formats = { "D", "f", "F" };
+
+ CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
+ DateTimeFormatInfo dtfi = enUS.DateTimeFormat;
+ String originalLongDatePattern = dtfi.LongDatePattern;
+
+ // Display the default form of three long date formats.
+ foreach (var fmt in formats)
+ Console.WriteLine(dateValue.ToString(fmt, dtfi));
+
+ Console.WriteLine();
+
+ // Modify the long date pattern.
+ dtfi.LongDatePattern = originalLongDatePattern + " g";
+ foreach (var fmt in formats)
+ Console.WriteLine(dateValue.ToString(fmt, dtfi));
+
+ Console.WriteLine();
+
+ // Change A.D. to C.E. (for Common Era)
+ dtfi.LongDatePattern = originalLongDatePattern + @" 'C.E.'";
+ foreach (var fmt in formats)
+ Console.WriteLine(dateValue.ToString(fmt, dtfi));
+ }
+}
+// The example displays the following output:
+// Saturday, May 18, 2013
+// Saturday, May 18, 2013 1:30 PM
+// Saturday, May 18, 2013 1:30:00 PM
+//
+// Saturday, May 18, 2013 A.D.
+// Saturday, May 18, 2013 A.D. 1:30 PM
+// Saturday, May 18, 2013 A.D. 1:30:00 PM
+//
+// Saturday, May 18, 2013 C.E.
+// Saturday, May 18, 2013 C.E. 1:30 PM
+// Saturday, May 18, 2013 C.E. 1:30:00 PM
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example5.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example5.cs
new file mode 100644
index 0000000000000..e23c4454dad1b
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/example5.cs
@@ -0,0 +1,47 @@
+//
+using System;
+using System.Globalization;
+using System.Text.RegularExpressions;
+
+public class Example5
+{
+ public static void Main()
+ {
+ CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
+ DateTimeFormatInfo dtfi = enUS.DateTimeFormat;
+
+ Console.WriteLine("Original Property Values:");
+ Console.WriteLine("ShortTimePattern: " + dtfi.ShortTimePattern);
+ Console.WriteLine("LongTimePattern: " + dtfi.LongTimePattern);
+ Console.WriteLine("FullDateTimePattern: " + dtfi.FullDateTimePattern);
+ Console.WriteLine();
+
+ dtfi.LongTimePattern = ReplaceWith24HourClock(dtfi.LongTimePattern);
+ dtfi.ShortTimePattern = ReplaceWith24HourClock(dtfi.ShortTimePattern);
+
+ Console.WriteLine("Modififed Property Values:");
+ Console.WriteLine("ShortTimePattern: " + dtfi.ShortTimePattern);
+ Console.WriteLine("LongTimePattern: " + dtfi.LongTimePattern);
+ Console.WriteLine("FullDateTimePattern: " + dtfi.FullDateTimePattern);
+ }
+
+ private static string ReplaceWith24HourClock(string fmt)
+ {
+ string pattern = @"^(?\s*t+\s*)? " +
+ @"(?(openAMPM) h+(?[^ht]+)$ " +
+ @"| \s*h+(?[^ht]+)\s*t+)";
+ return Regex.Replace(fmt, pattern, "HH${nonHours}",
+ RegexOptions.IgnorePatternWhitespace);
+ }
+}
+// The example displays the following output:
+// Original Property Values:
+// ShortTimePattern: h:mm tt
+// LongTimePattern: h:mm:ss tt
+// FullDateTimePattern: dddd, MMMM dd, yyyy h:mm:ss tt
+//
+// Modififed Property Values:
+// ShortTimePattern: HH:mm
+// LongTimePattern: HH:mm:ss
+// FullDateTimePattern: dddd, MMMM dd, yyyy HH:mm:ss
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/formatprovider1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/formatprovider1.cs
new file mode 100644
index 0000000000000..e555bf7ba6862
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/formatprovider1.cs
@@ -0,0 +1,43 @@
+//
+using System;
+using System.Globalization;
+
+public class CurrentCultureFormatProvider : IFormatProvider
+{
+ public Object GetFormat(Type formatType)
+ {
+ Console.WriteLine("Requesting an object of type {0}",
+ formatType.Name);
+ if (formatType == typeof(NumberFormatInfo))
+ return NumberFormatInfo.CurrentInfo;
+ else if (formatType == typeof(DateTimeFormatInfo))
+ return DateTimeFormatInfo.CurrentInfo;
+ else
+ return null;
+ }
+}
+
+public class FormatProviderEx1
+{
+ public static void Main()
+ {
+ DateTime dateValue = new DateTime(2013, 5, 28, 13, 30, 0);
+ string value = dateValue.ToString("F", new CurrentCultureFormatProvider());
+ Console.WriteLine(value);
+ Console.WriteLine();
+ string composite = String.Format(new CurrentCultureFormatProvider(),
+ "Date: {0:d} Amount: {1:C} Description: {2}",
+ dateValue, 1264.03m, "Service Charge");
+ Console.WriteLine(composite);
+ Console.WriteLine();
+ }
+}
+// The example displays output like the following:
+// Requesting an object of type DateTimeFormatInfo
+// Tuesday, May 28, 2013 1:30:00 PM
+//
+// Requesting an object of type ICustomFormatter
+// Requesting an object of type DateTimeFormatInfo
+// Requesting an object of type NumberFormatInfo
+// Date: 5/28/2013 Amount: $1,264.03 Description: Service Charge
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/instantiate2.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/instantiate2.cs
new file mode 100644
index 0000000000000..fde2e0a0c06aa
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/instantiate2.cs
@@ -0,0 +1,21 @@
+//
+using System;
+using System.Globalization;
+
+public class InstantiateEx1
+{
+ public static void Main()
+ {
+ DateTimeFormatInfo current1 = DateTimeFormatInfo.CurrentInfo;
+ current1 = (DateTimeFormatInfo)current1.Clone();
+ Console.WriteLine(current1.IsReadOnly);
+
+ CultureInfo culture2 = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
+ DateTimeFormatInfo current2 = culture2.DateTimeFormat;
+ Console.WriteLine(current2.IsReadOnly);
+ }
+}
+// The example displays the following output:
+// False
+// False
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/instantiate3.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/instantiate3.cs
new file mode 100644
index 0000000000000..50f450e2a8057
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/instantiate3.cs
@@ -0,0 +1,32 @@
+//
+using System;
+using System.Globalization;
+
+public class InstantiateEx3
+{
+ public static void Main()
+ {
+ CultureInfo culture;
+ DateTimeFormatInfo dtfi;
+
+ culture = CultureInfo.CurrentCulture;
+ dtfi = culture.DateTimeFormat;
+ Console.WriteLine("Culture Name: {0}", culture.Name);
+ Console.WriteLine("User Overrides: {0}", culture.UseUserOverride);
+ Console.WriteLine("Long Time Pattern: {0}\n", culture.DateTimeFormat.LongTimePattern);
+
+ culture = new CultureInfo(CultureInfo.CurrentCulture.Name, false);
+ Console.WriteLine("Culture Name: {0}", culture.Name);
+ Console.WriteLine("User Overrides: {0}", culture.UseUserOverride);
+ Console.WriteLine("Long Time Pattern: {0}\n", culture.DateTimeFormat.LongTimePattern);
+ }
+}
+// The example displays the following output:
+// Culture Name: en-US
+// User Overrides: True
+// Long Time Pattern: HH:mm:ss
+//
+// Culture Name: en-US
+// User Overrides: False
+// Long Time Pattern: h:mm:ss tt
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/instantiate6.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/instantiate6.cs
new file mode 100644
index 0000000000000..8f599ce580688
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/instantiate6.cs
@@ -0,0 +1,120 @@
+//
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+
+public class InstantiateEx6
+{
+ public static void Main()
+ {
+ // Get all the neutral cultures
+ List names = new List();
+ Array.ForEach(CultureInfo.GetCultures(CultureTypes.NeutralCultures),
+ culture => names.Add(culture.Name));
+ names.Sort();
+ foreach (var name in names)
+ {
+ // Ignore the invariant culture.
+ if (name == "") continue;
+
+ ListSimilarChildCultures(name);
+ }
+ }
+
+ private static void ListSimilarChildCultures(String name)
+ {
+ // Create the neutral DateTimeFormatInfo object.
+ DateTimeFormatInfo dtfi = CultureInfo.GetCultureInfo(name).DateTimeFormat;
+ // Retrieve all specific cultures of the neutral culture.
+ CultureInfo[] cultures = Array.FindAll(CultureInfo.GetCultures(CultureTypes.SpecificCultures),
+ culture => culture.Name.StartsWith(name + "-", StringComparison.OrdinalIgnoreCase));
+ // Create an array of DateTimeFormatInfo properties
+ PropertyInfo[] properties = typeof(DateTimeFormatInfo).GetProperties(BindingFlags.Instance | BindingFlags.Public);
+ bool hasOneMatch = false;
+
+ foreach (var ci in cultures)
+ {
+ bool match = true;
+ // Get the DateTimeFormatInfo for a specific culture.
+ DateTimeFormatInfo specificDtfi = ci.DateTimeFormat;
+ // Compare the property values of the two.
+ foreach (var prop in properties)
+ {
+ // We're not interested in the value of IsReadOnly.
+ if (prop.Name == "IsReadOnly") continue;
+
+ // For arrays, iterate the individual elements to see if they are the same.
+ if (prop.PropertyType.IsArray)
+ {
+ IList nList = (IList)prop.GetValue(dtfi, null);
+ IList sList = (IList)prop.GetValue(specificDtfi, null);
+ if (nList.Count != sList.Count)
+ {
+ match = false;
+ Console.WriteLine(" Different n in {2} array for {0} and {1}", name, ci.Name, prop.Name);
+ break;
+ }
+
+ for (int ctr = 0; ctr < nList.Count; ctr++)
+ {
+ if (!nList[ctr].Equals(sList[ctr]))
+ {
+ match = false;
+ Console.WriteLine(" {0} value different for {1} and {2}", prop.Name, name, ci.Name);
+ break;
+ }
+ }
+
+ if (!match) break;
+ }
+ // Get non-array values.
+ else
+ {
+ Object specificValue = prop.GetValue(specificDtfi);
+ Object neutralValue = prop.GetValue(dtfi);
+
+ // Handle comparison of Calendar objects.
+ if (prop.Name == "Calendar")
+ {
+ // The cultures have a different calendar type.
+ if (specificValue.ToString() != neutralValue.ToString())
+ {
+ Console.WriteLine(" Different calendar types for {0} and {1}", name, ci.Name);
+ match = false;
+ break;
+ }
+
+ if (specificValue is GregorianCalendar)
+ {
+ if (((GregorianCalendar)specificValue).CalendarType != ((GregorianCalendar)neutralValue).CalendarType)
+ {
+ Console.WriteLine(" Different Gregorian calendar types for {0} and {1}", name, ci.Name);
+ match = false;
+ break;
+ }
+ }
+ }
+ else if (!specificValue.Equals(neutralValue))
+ {
+ match = false;
+ Console.WriteLine(" Different {0} values for {1} and {2}", prop.Name, name, ci.Name);
+ break;
+ }
+ }
+ }
+ if (match)
+ {
+ Console.WriteLine("DateTimeFormatInfo object for '{0}' matches '{1}'",
+ name, ci.Name);
+ hasOneMatch = true;
+ }
+ }
+ if (!hasOneMatch)
+ Console.WriteLine("DateTimeFormatInfo object for '{0}' --> No Match", name);
+
+ Console.WriteLine();
+ }
+}
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/parse1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/parse1.cs
new file mode 100644
index 0000000000000..4b3502d2c4002
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/parse1.cs
@@ -0,0 +1,46 @@
+//
+using System;
+using System.Globalization;
+
+public class ParseEx1
+{
+ public static void Main()
+ {
+ string[] dateStrings = { "08/18/2014", "01/02/2015" };
+ string[] cultureNames = { "en-US", "en-GB", "fr-FR", "fi-FI" };
+
+ foreach (var cultureName in cultureNames)
+ {
+ CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
+ Console.WriteLine("Parsing strings using the {0} culture.",
+ culture.Name);
+ foreach (var dateStr in dateStrings)
+ {
+ try
+ {
+ Console.WriteLine(String.Format(culture,
+ " '{0}' --> {1:D}", dateStr,
+ DateTime.Parse(dateStr, culture)));
+ }
+ catch (FormatException)
+ {
+ Console.WriteLine(" Unable to parse '{0}'", dateStr);
+ }
+ }
+ }
+ }
+}
+// The example displays the following output:
+// Parsing strings using the en-US culture.
+// '08/18/2014' --> Monday, August 18, 2014
+// '01/02/2015' --> Friday, January 02, 2015
+// Parsing strings using the en-GB culture.
+// Unable to parse '08/18/2014'
+// '01/02/2015' --> 01 February 2015
+// Parsing strings using the fr-FR culture.
+// Unable to parse '08/18/2014'
+// '01/02/2015' --> dimanche 1 février 2015
+// Parsing strings using the fi-FI culture.
+// Unable to parse '08/18/2014'
+// '01/02/2015' --> 1. helmikuuta 2015
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/parse2.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/parse2.cs
new file mode 100644
index 0000000000000..05097bec5880d
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/parse2.cs
@@ -0,0 +1,38 @@
+//
+using System;
+using System.Globalization;
+
+public class ParseEx2
+{
+ public static void Main()
+ {
+ string inputDate = "14/05/10";
+
+ CultureInfo[] cultures = { CultureInfo.GetCultureInfo("en-US"),
+ CultureInfo.CreateSpecificCulture("en-US") };
+
+ foreach (var culture in cultures)
+ {
+ try
+ {
+ Console.WriteLine("{0} culture reflects user overrides: {1}",
+ culture.Name, culture.UseUserOverride);
+ DateTime occasion = DateTime.Parse(inputDate, culture);
+ Console.WriteLine("'{0}' --> {1}", inputDate,
+ occasion.ToString("D", CultureInfo.InvariantCulture));
+ }
+ catch (FormatException)
+ {
+ Console.WriteLine("Unable to parse '{0}'", inputDate);
+ }
+ Console.WriteLine();
+ }
+ }
+}
+// The example displays the following output:
+// en-US culture reflects user overrides: False
+// Unable to parse '14/05/10'
+//
+// en-US culture reflects user overrides: True
+// '14/05/10' --> Saturday, 10 May 2014
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/project.csproj b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/project.csproj
new file mode 100644
index 0000000000000..410c4a67f2207
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/project.csproj
@@ -0,0 +1,9 @@
+
+
+
+ Library
+ net8.0
+ enable
+
+
+
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/serialize1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/serialize1.cs
new file mode 100644
index 0000000000000..ecd092ff9e766
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/serialize1.cs
@@ -0,0 +1,30 @@
+//
+using System;
+using System.Globalization;
+using System.IO;
+
+public class SerializeEx1
+{
+ public static void Main()
+ {
+ StreamWriter sw = new StreamWriter(@".\DateData.dat");
+ // Define a date and time to serialize.
+ DateTime originalDate = new DateTime(2014, 08, 18, 08, 16, 35);
+ // Display information on the date and time.
+ Console.WriteLine("Date to serialize: {0:F}", originalDate);
+ Console.WriteLine("Current Culture: {0}",
+ CultureInfo.CurrentCulture.Name);
+ Console.WriteLine("Time Zone: {0}",
+ TimeZoneInfo.Local.DisplayName);
+ // Convert the date value to UTC.
+ DateTime utcDate = originalDate.ToUniversalTime();
+ // Serialize the UTC value.
+ sw.Write(utcDate.ToString("o", DateTimeFormatInfo.InvariantInfo));
+ sw.Close();
+ }
+}
+// The example displays the following output:
+// Date to serialize: Monday, August 18, 2014 8:16:35 AM
+// Current Culture: en-US
+// Time Zone: (UTC-08:00) Pacific Time (US & Canada)
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/serialize2.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/serialize2.cs
new file mode 100644
index 0000000000000..8798f411bcfd0
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/DateTimeFormatInfo/csharp/serialize2.cs
@@ -0,0 +1,31 @@
+//
+using System;
+using System.Globalization;
+using System.IO;
+
+public class SerializeEx2
+{
+ public static void Main()
+ {
+ // Open the file and retrieve the date string.
+ StreamReader sr = new StreamReader(@".\DateData.dat");
+ String dateValue = sr.ReadToEnd();
+
+ // Parse the date.
+ DateTime parsedDate = DateTime.ParseExact(dateValue, "o",
+ DateTimeFormatInfo.InvariantInfo);
+ // Convert it to local time.
+ DateTime restoredDate = parsedDate.ToLocalTime();
+ // Display information on the date and time.
+ Console.WriteLine("Deserialized date: {0:F}", restoredDate);
+ Console.WriteLine("Current Culture: {0}",
+ CultureInfo.CurrentCulture.Name);
+ Console.WriteLine("Time Zone: {0}",
+ TimeZoneInfo.Local.DisplayName);
+ }
+}
+// The example displays the following output:
+// Deserialized date: lundi 18 août 2014 17:16:35
+// Current Culture: fr-FR
+// Time Zone: (UTC+01:00) Brussels, Copenhagen, Madrid, Paris
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/customize_currency1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/customize_currency1.cs
new file mode 100644
index 0000000000000..1e5cb5579d2fc
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/customize_currency1.cs
@@ -0,0 +1,42 @@
+//
+using System;
+using System.Globalization;
+
+public class Example
+{
+ public static void Main()
+ {
+ // Retrieve a writable NumberFormatInfo object.
+ CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
+ NumberFormatInfo nfi = enUS.NumberFormat;
+
+ // Use the ISO currency symbol instead of the native currency symbol.
+ nfi.CurrencySymbol = (new RegionInfo(enUS.Name)).ISOCurrencySymbol;
+ // Change the positive currency pattern to .
+ nfi.CurrencyPositivePattern = 2;
+ // Change the negative currency pattern to .
+ nfi.CurrencyNegativePattern = 12;
+
+ // Produce the result strings by calling ToString.
+ Decimal[] values = { 1065.23m, 19.89m, -.03m, -175902.32m };
+ foreach (var value in values)
+ Console.WriteLine(value.ToString("C", enUS));
+
+ Console.WriteLine();
+
+ // Produce the result strings by calling a composite formatting method.
+ foreach (var value in values)
+ Console.WriteLine(String.Format(enUS, "{0:C}", value));
+ }
+}
+// The example displays the following output:
+// USD 1,065.23
+// USD 19.89
+// USD -0.03
+// USD -175,902.32
+//
+// USD 1,065.23
+// USD 19.89
+// USD -0.03
+// USD -175,902.32
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/customize_ssn1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/customize_ssn1.cs
new file mode 100644
index 0000000000000..1e91cac484a24
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/customize_ssn1.cs
@@ -0,0 +1,37 @@
+//
+using System;
+using System.Globalization;
+
+public class CustomizeSSNEx
+{
+ public static void Main()
+ {
+ // Instantiate a read-only NumberFormatInfo object.
+ CultureInfo enUS = CultureInfo.CreateSpecificCulture("en-US");
+ NumberFormatInfo nfi = enUS.NumberFormat;
+
+ // Modify the relevant properties.
+ nfi.NumberGroupSeparator = "-";
+ nfi.NumberGroupSizes = new int[] { 3, 2, 4 };
+ nfi.NumberDecimalDigits = 0;
+
+ int[] ids = { 111223333, 999776666 };
+
+ // Produce the result string by calling ToString.
+ foreach (var id in ids)
+ Console.WriteLine(id.ToString("N", enUS));
+
+ Console.WriteLine();
+
+ // Produce the result string using composite formatting.
+ foreach (var id in ids)
+ Console.WriteLine(String.Format(enUS, "{0:N}", id));
+ }
+}
+// The example displays the following output:
+// 1112-23-333
+// 9997-76-666
+//
+// 1112-23-333
+// 9997-76-666
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/formatprovider1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/formatprovider1.cs
new file mode 100644
index 0000000000000..cdf2540b45c48
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/formatprovider1.cs
@@ -0,0 +1,43 @@
+//
+using System;
+using System.Globalization;
+
+public class CurrentCultureFormatProvider : IFormatProvider
+{
+ public Object GetFormat(Type formatType)
+ {
+ Console.WriteLine("Requesting an object of type {0}",
+ formatType.Name);
+ if (formatType == typeof(NumberFormatInfo))
+ return NumberFormatInfo.CurrentInfo;
+ else if (formatType == typeof(DateTimeFormatInfo))
+ return DateTimeFormatInfo.CurrentInfo;
+ else
+ return null;
+ }
+}
+
+public class FormatProviderEx
+{
+ public static void Main()
+ {
+ Decimal amount = 1203.541m;
+ string value = amount.ToString("C2", new CurrentCultureFormatProvider());
+ Console.WriteLine(value);
+ Console.WriteLine();
+ string composite = String.Format(new CurrentCultureFormatProvider(),
+ "Date: {0} Amount: {1} Description: {2}",
+ DateTime.Now, 1264.03m, "Service Charge");
+ Console.WriteLine(composite);
+ Console.WriteLine();
+ }
+}
+// The example displays output like the following:
+// Requesting an object of type NumberFormatInfo
+// $1,203.54
+//
+// Requesting an object of type ICustomFormatter
+// Requesting an object of type DateTimeFormatInfo
+// Requesting an object of type NumberFormatInfo
+// Date: 11/15/2012 2:00:01 PM Amount: 1264.03 Description: Service Charge
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate1.cs
new file mode 100644
index 0000000000000..9f1517d5dadcd
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate1.cs
@@ -0,0 +1,23 @@
+//
+using System;
+using System.Globalization;
+
+public class InstantiateEx1
+{
+ public static void Main()
+ {
+ NumberFormatInfo current1 = CultureInfo.CurrentCulture.NumberFormat;
+ Console.WriteLine(current1.IsReadOnly);
+
+ NumberFormatInfo current2 = NumberFormatInfo.CurrentInfo;
+ Console.WriteLine(current2.IsReadOnly);
+
+ NumberFormatInfo current3 = NumberFormatInfo.GetInstance(CultureInfo.CurrentCulture);
+ Console.WriteLine(current3.IsReadOnly);
+ }
+}
+// The example displays the following output:
+// True
+// True
+// True
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate2.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate2.cs
new file mode 100644
index 0000000000000..940e39567844f
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate2.cs
@@ -0,0 +1,21 @@
+//
+using System;
+using System.Globalization;
+
+public class InstantiateEx2
+{
+ public static void Main()
+ {
+ NumberFormatInfo current1 = NumberFormatInfo.CurrentInfo;
+ current1 = (NumberFormatInfo)current1.Clone();
+ Console.WriteLine(current1.IsReadOnly);
+
+ CultureInfo culture2 = CultureInfo.CreateSpecificCulture(CultureInfo.CurrentCulture.Name);
+ NumberFormatInfo current2 = culture2.NumberFormat;
+ Console.WriteLine(current2.IsReadOnly);
+ }
+}
+// The example displays the following output:
+// False
+// False
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate3.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate3.cs
new file mode 100644
index 0000000000000..9f823b693991f
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate3.cs
@@ -0,0 +1,32 @@
+//
+using System;
+using System.Globalization;
+
+public class InstantiateEx3
+{
+ public static void Main()
+ {
+ CultureInfo culture;
+ NumberFormatInfo nfi;
+
+ culture = CultureInfo.CurrentCulture;
+ nfi = culture.NumberFormat;
+ Console.WriteLine("Culture Name: {0}", culture.Name);
+ Console.WriteLine("User Overrides: {0}", culture.UseUserOverride);
+ Console.WriteLine("Currency Symbol: {0}\n", culture.NumberFormat.CurrencySymbol);
+
+ culture = new CultureInfo(CultureInfo.CurrentCulture.Name, false);
+ Console.WriteLine("Culture Name: {0}", culture.Name);
+ Console.WriteLine("User Overrides: {0}", culture.UseUserOverride);
+ Console.WriteLine("Currency Symbol: {0}", culture.NumberFormat.CurrencySymbol);
+ }
+}
+// The example displays the following output:
+// Culture Name: en-US
+// User Overrides: True
+// Currency Symbol: USD
+//
+// Culture Name: en-US
+// User Overrides: False
+// Currency Symbol: $
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate4.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate4.cs
new file mode 100644
index 0000000000000..6156482cc1f39
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate4.cs
@@ -0,0 +1,25 @@
+//
+using System;
+using System.Globalization;
+
+public class InstantiateEx4
+{
+ public static void Main()
+ {
+ NumberFormatInfo nfi;
+
+ nfi = System.Globalization.NumberFormatInfo.InvariantInfo;
+ Console.WriteLine(nfi.IsReadOnly);
+
+ nfi = CultureInfo.InvariantCulture.NumberFormat;
+ Console.WriteLine(nfi.IsReadOnly);
+
+ nfi = new NumberFormatInfo();
+ Console.WriteLine(nfi.IsReadOnly);
+ }
+}
+// The example displays the following output:
+// True
+// True
+// False
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate5.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate5.cs
new file mode 100644
index 0000000000000..2e4704eeb08f1
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate5.cs
@@ -0,0 +1,33 @@
+//
+using System;
+using System.Globalization;
+
+public class InstantiateEx5
+{
+ public static void Main()
+ {
+ CultureInfo culture;
+ NumberFormatInfo nfi;
+
+ nfi = CultureInfo.GetCultureInfo("id-ID").NumberFormat;
+ Console.WriteLine("Read-only: {0}", nfi.IsReadOnly);
+
+ culture = new CultureInfo("id-ID");
+ nfi = NumberFormatInfo.GetInstance(culture);
+ Console.WriteLine("Read-only: {0}", nfi.IsReadOnly);
+
+ culture = CultureInfo.CreateSpecificCulture("id-ID");
+ nfi = culture.NumberFormat;
+ Console.WriteLine("Read-only: {0}", nfi.IsReadOnly);
+
+ culture = new CultureInfo("id-ID");
+ nfi = culture.NumberFormat;
+ Console.WriteLine("Read-only: {0}", nfi.IsReadOnly);
+ }
+}
+// The example displays the following output:
+// Read-only: True
+// Read-only: False
+// Read-only: False
+// Read-only: False
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate6.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate6.cs
new file mode 100644
index 0000000000000..6b8bccaa8fbab
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/instantiate6.cs
@@ -0,0 +1,87 @@
+//
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Reflection;
+
+public class InstantiateEx6
+{
+ public static void Main()
+ {
+ // Get all the neutral cultures
+ List names = new List();
+ Array.ForEach(CultureInfo.GetCultures(CultureTypes.NeutralCultures),
+ culture => names.Add(culture.Name));
+ names.Sort();
+ foreach (var name in names)
+ {
+ // Ignore the invariant culture.
+ if (name == "") continue;
+
+ ListSimilarChildCultures(name);
+ }
+ }
+
+ private static void ListSimilarChildCultures(string name)
+ {
+ // Create the neutral NumberFormatInfo object.
+ NumberFormatInfo nfi = CultureInfo.GetCultureInfo(name).NumberFormat;
+ // Retrieve all specific cultures of the neutral culture.
+ CultureInfo[] cultures = Array.FindAll(CultureInfo.GetCultures(CultureTypes.SpecificCultures),
+ culture => culture.Name.StartsWith(name + "-", StringComparison.OrdinalIgnoreCase));
+ // Create an array of NumberFormatInfo properties
+ PropertyInfo[] properties = typeof(NumberFormatInfo).GetProperties(BindingFlags.Instance | BindingFlags.Public);
+ bool hasOneMatch = false;
+
+ foreach (var ci in cultures)
+ {
+ bool match = true;
+ // Get the NumberFormatInfo for a specific culture.
+ NumberFormatInfo specificNfi = ci.NumberFormat;
+ // Compare the property values of the two.
+ foreach (var prop in properties)
+ {
+ // We're not interested in the value of IsReadOnly.
+ if (prop.Name == "IsReadOnly") continue;
+
+ // For arrays, iterate the individual elements to see if they are the same.
+ if (prop.PropertyType.IsArray)
+ {
+ IList nList = (IList)prop.GetValue(nfi, null);
+ IList sList = (IList)prop.GetValue(specificNfi, null);
+ if (nList.Count != sList.Count)
+ {
+ match = false;
+ break;
+ }
+
+ for (int ctr = 0; ctr < nList.Count; ctr++)
+ {
+ if (!nList[ctr].Equals(sList[ctr]))
+ {
+ match = false;
+ break;
+ }
+ }
+ }
+ else if (!prop.GetValue(specificNfi).Equals(prop.GetValue(nfi)))
+ {
+ match = false;
+ break;
+ }
+ }
+ if (match)
+ {
+ Console.WriteLine("NumberFormatInfo object for '{0}' matches '{1}'",
+ name, ci.Name);
+ hasOneMatch = true;
+ }
+ }
+ if (!hasOneMatch)
+ Console.WriteLine("NumberFormatInfo object for '{0}' --> No Match", name);
+
+ Console.WriteLine();
+ }
+}
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/parse1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/parse1.cs
new file mode 100644
index 0000000000000..b4131e78d7fdb
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/parse1.cs
@@ -0,0 +1,41 @@
+//
+using System;
+using System.Globalization;
+
+public class ParseEx1
+{
+ public static void Main()
+ {
+ String[] values = { "1,034,562.91", "9 532 978,07" };
+ String[] cultureNames = { "en-US", "fr-FR", "" };
+
+ foreach (var value in values)
+ {
+ foreach (var cultureName in cultureNames)
+ {
+ CultureInfo culture = CultureInfo.CreateSpecificCulture(cultureName);
+ String name = culture.Name == "" ? "Invariant" : culture.Name;
+ try
+ {
+ Decimal amount = Decimal.Parse(value, culture);
+ Console.WriteLine("'{0}' --> {1} ({2})", value, amount, name);
+ }
+ catch (FormatException)
+ {
+ Console.WriteLine("'{0}': FormatException ({1})",
+ value, name);
+ }
+ }
+ Console.WriteLine();
+ }
+ }
+}
+// The example displays the following output:
+// '1,034,562.91' --> 1034562.91 (en-US)
+// '1,034,562.91': FormatException (fr-FR)
+// '1,034,562.91' --> 1034562.91 (Invariant)
+//
+// '9 532 978,07': FormatException (en-US)
+// '9 532 978,07' --> 9532978.07 (fr-FR)
+// '9 532 978,07': FormatException (Invariant)
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/parsepersisted.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/parsepersisted.cs
new file mode 100644
index 0000000000000..23e05bd954e21
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/parsepersisted.cs
@@ -0,0 +1,80 @@
+//
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Threading;
+
+public class ParsePersistedEx
+{
+ public static void Main()
+ {
+ CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
+ PersistData();
+
+ CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("pt-BR");
+ RestoreData();
+ }
+
+ private static void PersistData()
+ {
+ // Define an array of floating-point values.
+ Double[] values = { 160325.972, 8631.16, 1.304e5, 98017554.385,
+ 8.5938287084321676e94 };
+ Console.WriteLine("Original values: ");
+ foreach (var value in values)
+ Console.WriteLine(value.ToString("R", CultureInfo.InvariantCulture));
+
+ // Serialize an array of doubles to a file
+ StreamWriter sw = new StreamWriter(@".\NumericData.bin");
+ for (int ctr = 0; ctr < values.Length; ctr++)
+ {
+ sw.Write(values[ctr].ToString("R"));
+ if (ctr < values.Length - 1) sw.Write("|");
+ }
+ sw.Close();
+ Console.WriteLine();
+ }
+
+ private static void RestoreData()
+ {
+ // Deserialize the data
+ StreamReader sr = new StreamReader(@".\NumericData.bin");
+ String data = sr.ReadToEnd();
+ sr.Close();
+
+ String[] stringValues = data.Split('|');
+ List newValueList = new List();
+
+ foreach (var stringValue in stringValues)
+ {
+ try
+ {
+ newValueList.Add(Double.Parse(stringValue));
+ }
+ catch (FormatException)
+ {
+ newValueList.Add(Double.NaN);
+ }
+ }
+
+ Console.WriteLine("Restored values:");
+ foreach (var newValue in newValueList)
+ Console.WriteLine(newValue.ToString("R", NumberFormatInfo.InvariantInfo));
+ }
+}
+// The example displays the following output:
+// Original values:
+// 160325.972
+// 8631.16
+// 130400
+// 98017554.385
+// 8.5938287084321671E+94
+//
+// Restored values:
+// 160325972
+// 863116
+// 130400
+// 98017554385
+// 8.5938287084321666E+110
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/parseuser1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/parseuser1.cs
new file mode 100644
index 0000000000000..0470738820851
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/parseuser1.cs
@@ -0,0 +1,45 @@
+//
+using System;
+using System.Globalization;
+
+public class ParseUserEx
+{
+ public static void Main()
+ {
+ CultureInfo stdCulture = CultureInfo.GetCultureInfo("en-US");
+ CultureInfo custCulture = CultureInfo.CreateSpecificCulture("en-US");
+
+ String value = "310,16";
+ try
+ {
+ Console.WriteLine("{0} culture reflects user overrides: {1}",
+ stdCulture.Name, stdCulture.UseUserOverride);
+ Decimal amount = Decimal.Parse(value, stdCulture);
+ Console.WriteLine("'{0}' --> {1}", value, amount.ToString(CultureInfo.InvariantCulture));
+ }
+ catch (FormatException)
+ {
+ Console.WriteLine("Unable to parse '{0}'", value);
+ }
+ Console.WriteLine();
+
+ try
+ {
+ Console.WriteLine("{0} culture reflects user overrides: {1}",
+ custCulture.Name, custCulture.UseUserOverride);
+ Decimal amount = Decimal.Parse(value, custCulture);
+ Console.WriteLine("'{0}' --> {1}", value, amount.ToString(CultureInfo.InvariantCulture));
+ }
+ catch (FormatException)
+ {
+ Console.WriteLine("Unable to parse '{0}'", value);
+ }
+ }
+}
+// The example displays the following output:
+// en-US culture reflects user overrides: False
+// '310,16' --> 31016
+//
+// en-US culture reflects user overrides: True
+// '310,16' --> 310.16
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/project.csproj b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/project.csproj
new file mode 100644
index 0000000000000..410c4a67f2207
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/project.csproj
@@ -0,0 +1,9 @@
+
+
+
+ Library
+ net8.0
+ enable
+
+
+
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/properties1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/properties1.cs
new file mode 100644
index 0000000000000..3be5c7e9cb886
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/properties1.cs
@@ -0,0 +1,41 @@
+//
+using System;
+using System.Globalization;
+
+public class PropertiesEx1
+{
+ public static void Main()
+ {
+ string[] formatStrings = { "C2", "E1", "F", "G3", "N",
+ "#,##0.000", "0,000,000,000.0##" };
+ CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US");
+ Decimal[] values = { 1345.6538m, 1921651.16m };
+
+ foreach (var value in values)
+ {
+ foreach (var formatString in formatStrings)
+ {
+ string resultString = value.ToString(formatString, culture);
+ Console.WriteLine("{0,-18} --> {1}", formatString, resultString);
+ }
+ Console.WriteLine();
+ }
+ }
+}
+// The example displays the following output:
+// C2 --> $1,345.65
+// E1 --> 1.3E+003
+// F --> 1345.65
+// G3 --> 1.35E+03
+// N --> 1,345.65
+// #,##0.000 --> 1,345.654
+// 0,000,000,000.0## --> 0,000,001,345.654
+//
+// C2 --> $1,921,651.16
+// E1 --> 1.9E+006
+// F --> 1921651.16
+// G3 --> 1.92E+06
+// N --> 1,921,651.16
+// #,##0.000 --> 1,921,651.160
+// 0,000,000,000.0## --> 0,001,921,651.16
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/properties2.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/properties2.cs
new file mode 100644
index 0000000000000..dee3c390c4ad0
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/NumberFormatInfo/csharp/properties2.cs
@@ -0,0 +1,22 @@
+//
+using System;
+
+public class PropertiesEx2
+{
+ public static void Main()
+ {
+ Decimal[] values = { 1345.6538m, 1921651.16m };
+
+ foreach (var value in values)
+ {
+ string resultString = value.ToString();
+ Console.WriteLine(resultString);
+ Console.WriteLine();
+ }
+ }
+}
+// The example displays the following output:
+// 1345.6538
+//
+// 1921651.16
+//
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/RegionInfo/csharp/Project.csproj b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/RegionInfo/csharp/Project.csproj
new file mode 100644
index 0000000000000..5a1b02db67729
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/RegionInfo/csharp/Project.csproj
@@ -0,0 +1,8 @@
+
+
+
+ Library
+ net8.0
+
+
+
\ No newline at end of file
diff --git a/docs/fundamentals/runtime-libraries/snippets/System.Globalization/RegionInfo/csharp/propertyvalues1.cs b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/RegionInfo/csharp/propertyvalues1.cs
new file mode 100644
index 0000000000000..18ebcf53bbdae
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/snippets/System.Globalization/RegionInfo/csharp/propertyvalues1.cs
@@ -0,0 +1,46 @@
+//
+using System;
+using System.Globalization;
+using System.Reflection;
+
+public class Example
+{
+ public static void Main()
+ {
+ // Instantiate three Belgian RegionInfo objects.
+ RegionInfo BE = new RegionInfo("BE");
+ RegionInfo frBE = new RegionInfo("fr-BE");
+ RegionInfo nlBE = new RegionInfo("nl-BE");
+
+ RegionInfo[] regions = { BE, frBE, nlBE };
+ PropertyInfo[] props = typeof(RegionInfo).GetProperties(BindingFlags.Instance | BindingFlags.Public);
+
+ Console.WriteLine("{0,-30}{1,18}{2,18}{3,18}\n",
+ "RegionInfo Property", "BE", "fr-BE", "nl-BE");
+ foreach (var prop in props)
+ {
+ Console.Write("{0,-30}", prop.Name);
+ foreach (var region in regions)
+ Console.Write("{0,18}", prop.GetValue(region, null));
+
+ Console.WriteLine();
+ }
+ }
+}
+// The example displays the following output:
+// RegionInfo Property BE fr-BE nl-BE
+//
+// Name BE fr-BE nl-BE
+// EnglishName Belgium Belgium Belgium
+// DisplayName Belgium Belgium Belgium
+// NativeName België Belgique België
+// TwoLetterISORegionName BE BE BE
+// ThreeLetterISORegionName BEL BEL BEL
+// ThreeLetterWindowsRegionName BEL BEL BEL
+// IsMetric True True True
+// GeoId 21 21 21
+// CurrencyEnglishName Euro Euro Euro
+// CurrencyNativeName euro euro euro
+// CurrencySymbol € € €
+// ISOCurrencySymbol EUR EUR EUR
+//
diff --git a/docs/fundamentals/runtime-libraries/system-globalization-compareinfo.md b/docs/fundamentals/runtime-libraries/system-globalization-compareinfo.md
new file mode 100644
index 0000000000000..ad66e6081f817
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/system-globalization-compareinfo.md
@@ -0,0 +1,34 @@
+---
+title: System.Globalization.CompareInfo class
+description: Learn more about the System.Globalization.CompareInfo class.
+ms.date: 12/28/2023
+ms.topic: conceptual
+---
+# class
+
+[!INCLUDE [context](includes/context.md)]
+
+Conventions for comparing and sorting data vary from culture to culture. For example, sort order may be based on phonetics or on the visual representation of characters. In East Asian languages, characters are sorted by the stroke and radical of ideographs. Sorting also depends on the order languages and cultures use for the alphabet. For example, the Danish language has an "Æ" character that it sorts after "Z" in the alphabet. In addition, comparisons may be case-sensitive or case-insensitive, and casing rules may also differ by culture. The class is responsible for maintaining this culture-sensitive string comparison data and for performing culture-sensitive string operations.
+
+Typically, you do not have to instantiate a object directly, because one is used implicitly by all non-ordinal string comparison operations, including calls to the method. However, if you do want to retrieve a object, you can do it in one of these ways:
+
+- By retrieving the value of the property for a particular culture.
+
+- By calling the static method with a culture name. This allows for late-bound access to a object.
+
+## Ignored search values
+
+Character sets include ignorable characters, which are characters that are not considered when performing a linguistic or culture-sensitive comparison. Comparison methods such as and do not consider such characters when they perform a culture-sensitive comparison. Ignorable characters include:
+
+- . Culture-sensitive comparison methods will always find an empty string at the beginning (index zero) of the string being searched.
+
+- A character or string consisting of characters with code points that are not considered in the operation because of comparison options, In particular, the and options produce searches in which symbols and nonspacing combining characters are ignored.
+
+- A string with code points that have no linguistic significance. For example, a soft hyphen (U+00AD) is always ignored in a culture-sensitive string comparison.
+
+## Security considerations
+
+If a security decision depends on a string comparison or a case change, you should use the property to ensure that the behavior is consistent, regardless of the culture settings of the operating system.
+
+> [!NOTE]
+> When possible, you should use string comparison methods that have a parameter of type to specify the kind of comparison expected. As a general rule, use linguistic options (using the current culture) for comparing strings displayed in the user interface and specify or for security comparisons.
diff --git a/docs/fundamentals/runtime-libraries/system-globalization-compareoptions.md b/docs/fundamentals/runtime-libraries/system-globalization-compareoptions.md
new file mode 100644
index 0000000000000..ca2b4e5e78e83
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/system-globalization-compareoptions.md
@@ -0,0 +1,22 @@
+---
+title: System.Globalization.CompareOptions enum
+description: Learn more about the System.Globalization.CompareOptions enum.
+ms.date: 12/28/2023
+ms.topic: conceptual
+---
+# enum
+
+[!INCLUDE [context](includes/context.md)]
+
+The options denote case sensitivity or necessity to ignore types of characters.
+
+.NET uses three distinct ways of sorting: word sort, string sort, and ordinal sort. Word sort performs a culture-sensitive comparison of strings. Certain nonalphanumeric characters might have special weights assigned to them. For example, the hyphen ("-") might have a very small weight assigned to it so that "coop" and "co-op" appear next to each other in a sorted list. String sort is similar to word sort, except that there are no special cases. Therefore, all nonalphanumeric symbols come before all alphanumeric characters. Ordinal sort compares strings based on the Unicode values of each element of the string. For a downloadable set of text files that contain information on the character weights used in sorting and comparison operations for Windows operating systems, see [Sorting Weight Tables](https://www.microsoft.com/download/details.aspx?id=10921). For the sort weight table for Linux and macOS, see the [Default Unicode Collation Element Table](https://www.unicode.org/Public/UCA/latest/allkeys.txt). The specific version of the sort weight table on Linux and macOS depends on the version of the [International Components for Unicode](https://icu.unicode.org/) libraries installed on the system. For information on ICU versions and the Unicode versions that they implement, see [Downloading ICU](https://icu.unicode.org/download).
+
+The `StringSort` value can only be used with and . is thrown if the StringSort value is used with , , , or .
+
+> [!NOTE]
+> When possible, you should use string comparison methods that accept a value to specify the kind of comparison expected. As a general rule, user-facing comparisons are best served by the use of linguistic options (using the current culture), while security comparisons should specify `Ordinal` or `OrdinalIgnoreCase`.
+
+## Culture-sensitive sorts
+
+[!INCLUDE[platform-note](includes/c-and-posix-cultures.md)]
diff --git a/docs/fundamentals/runtime-libraries/system-globalization-cultureandregioninfobuilder.md b/docs/fundamentals/runtime-libraries/system-globalization-cultureandregioninfobuilder.md
new file mode 100644
index 0000000000000..3b8a932629df5
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/system-globalization-cultureandregioninfobuilder.md
@@ -0,0 +1,63 @@
+---
+title: System.Globalization.CultureAndRegionInfoBuilder class
+description: Learn more about the System.Globalization.CultureAndRegionInfoBuilder class.
+ms.date: 12/28/2023
+ms.topic: conceptual
+---
+# class
+
+[!INCLUDE [context](includes/context.md)]
+
+The class holds culture-specific information, such as the associated language, sublanguage, country/region, calendar, and cultural conventions. This class also provides culture-specific instances of the , , , and classes, which are required for culture-specific operations such as casing, formatting and parsing dates and numbers, and comparing strings.
+
+By default, .NET supports objects that represent a predefined set of cultures. For a list of these cultures available on Windows systems, see the **Language tag** column in the [list of language/region names supported by Windows](/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c). Culture names follow the standard defined by [BCP 47](https://tools.ietf.org/html/bcp47). The class enables you to create a custom culture that is completely new or that overrides a predefined culture. When a custom culture is installed and registered on a particular computer, it becomes indistinguishable from predefined objects, and can be instantiated and used just like those objects.
+
+> [!IMPORTANT]
+> Note that the class is found in an assembly named sysglobl.dll. Successfully compiling code that uses this type requires that you add a reference to sysglobl.dll.
+
+A custom culture can be registered on a computer only by a user who has administrative rights on that computer. Consequently, apps typically do not create and install custom cultures. Instead, you can use the class to create a special-purpose tool that an administrator can use to create, install, and register a custom culture. After the custom culture is registered on a computer, you can use the class in your app to create instances of the custom culture just as you would for a predefined culture.
+
+If you parse date and time strings generated for a custom culture, you should use the or method instead of the or method to improve the probability that the parse operation will succeed. A date and time string for a custom culture can be complicated and therefore difficult to parse. The and methods try to parse a string with several implicit parse patterns, all of which might fail. The method, in contrast, requires the application to explicitly designate one or more exact parse patterns that are likely to succeed.
+
+## Define and create a custom culture
+
+You use the class to define and name a custom culture. The custom culture can be an entirely new culture, a new culture that is based on an existing culture (that is, a supplemental culture), or a culture that replaces an existing .NET culture. In each case, the basic steps are the same:
+
+1. Instantiate a object by calling its constructor. To replace an existing culture, pass that culture's name and the enumeration value to the constructor. To create a new culture or a supplemental culture, pass a unique culture name and either the or enumeration value.
+
+ > [!NOTE]
+ > If you use the enumeration value to instantiate a object, the object's properties are automatically populated with values from the object to be replaced.
+
+2. If you're creating a new or supplemental culture:
+
+ - Populate the object's properties by calling the method and passing a object whose property values are similar to your new object.
+ - Populate the object's regional properties by calling the method and passing a object that represents the region of your custom culture.
+
+3. Modify the properties of the object as necessary.
+
+4. If you are planning to register the custom culture in a separate routine, call the method. This generates an XML file that you can load and register in a separate custom culture installation routine.
+
+## Register a custom culture
+
+If you are developing a registration application for a custom culture that is separate from the application that creates the culture, you call the method to load the XML file that contains the custom culture's definition and instantiate the object. To handle the registration, call the method. For the registration to succeed, the application that registers the custom culture must be running with administrative privileges on the target system; otherwise, the call to throws an exception.
+
+> [!WARNING]
+> Culture data can differ between systems. If you're using the class to create a custom culture that is uniform across multiple systems and you are creating your custom culture by loading data from existing and objects and customizing it, you should develop two different utilities. The first creates the custom culture and saves it to an XML file. The second uses the method to load the custom culture from an XML file and register it on the target computer.
+
+The registration process performs the following tasks:
+
+- Creates an .nlp file that contains the information that is defined in the object.
+- Stores the .nlp file in the %windir%\Globalization system directory on the target computer. This enables the custom culture's settings to persist between sessions. (The method requires administrative privileges because the .nlp file is stored in a system directory.)
+- Prepares .NET to search the %windir%\Globalization system directory instead of an internal cache the next time there's a request to create your new custom culture.
+
+When a custom culture is successfully registered, it's indistinguishable from the cultures that are predefined by .NET. The custom culture is available until a call to the method removes the .nlp file from the local computer.
+
+## Instantiate a custom culture
+
+You can create an instance of the custom culture in one of the following ways:
+
+- By invoking the constructor with the culture name.
+- By calling the method with the culture name.
+- By calling the method with the culture name.
+
+In addition, the array of objects that is returned by the method includes the custom culture.
diff --git a/docs/fundamentals/runtime-libraries/system-globalization-cultureinfo.md b/docs/fundamentals/runtime-libraries/system-globalization-cultureinfo.md
new file mode 100644
index 0000000000000..5a54cc4a3e235
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/system-globalization-cultureinfo.md
@@ -0,0 +1,232 @@
+---
+title: System.Globalization.CultureInfo class
+description: Learn more about the System.Globalization.CultureInfo class.
+ms.date: 12/28/2023
+ms.topic: conceptual
+---
+# class
+
+[!INCLUDE [context](includes/context.md)]
+
+The class provides culture-specific information, such as the language, sublanguage, country/region, calendar, and conventions associated with a particular culture. This class also provides access to culture-specific instances of the , , , and objects. These objects contain the information required for culture-specific operations, such as casing, formatting dates and numbers, and comparing strings. The class is used either directly or indirectly by classes that format, parse, or manipulate culture-specific data, such as , , , and the numeric types.
+
+## Culture names and identifiers
+
+The class specifies a unique name for each culture, based on RFC 4646. The name is a combination of an ISO 639 two-letter or three-letter lowercase culture code associated with a language and an ISO 3166 two-letter uppercase subculture code associated with a country or region. In addition, for apps that target .NET Framework 4 or later and are running under Windows 10 or later, culture names that correspond to valid BCP-47 language tags are supported.
+
+> [!NOTE]
+> When a culture name is passed to a class constructor or a method such as or , its case is not significant.
+
+The format for the culture name based on RFC 4646 is *`languagecode2`*-*`country/regioncode2`*, where *`languagecode2`* is the two-letter language code and *`country/regioncode2`* is the two-letter subculture code. Examples include `ja-JP` for Japanese (Japan) and `en-US` for English (United States). In cases where a two-letter language code is not available, a three-letter code as defined in ISO 639-3 is used.
+
+Some culture names also specify an ISO 15924 script. For example, Cyrl specifies the Cyrillic script and Latn specifies the Latin script. A culture name that includes a script uses the pattern *`languagecode2`*-*`scripttag`*-*`country/regioncode2`*. An example of this type of culture name is `uz-Cyrl-UZ` for Uzbek (Cyrillic, Uzbekistan). On Windows operating systems before Windows Vista, a culture name that includes a script uses the pattern *`languagecode2`*-*`country/regioncode2`*-*`scripttag`*, for example, `uz-UZ-Cyrl` for Uzbek (Cyrillic, Uzbekistan).
+
+A neutral culture is specified by only the two-letter, lowercase language code. For example, `fr` specifies the neutral culture for French, and `de` specifies the neutral culture for German.
+
+> [!NOTE]
+> There are two culture names that contradict this rule. The cultures Chinese (Simplified), named `zh-Hans`, and Chinese (Traditional), named `zh-Hant`, are neutral cultures. The culture names represent the current standard and should be used unless you have a reason for using the older names `zh-CHS` and `zh-CHT`.
+
+A culture identifier is a standard international numeric abbreviation and has the components necessary to uniquely identify one of the installed cultures. Your application can use predefined culture identifiers or define custom identifiers.
+
+Certain predefined culture names and identifiers are used by this and other classes in the namespace. For detailed culture information for Windows systems, see the **Language tag** column in the [list of language/region names supported by Windows](/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c). Culture names follow the standard defined by [BCP 47](https://tools.ietf.org/html/bcp47).
+
+The culture names and identifiers represent only a subset of cultures that can be found on a particular computer. Windows versions or service packs can change the available cultures. Applications can add custom cultures using the class. Users can add their own custom cultures using the [Microsoft Locale Builder](https://www.microsoft.com/download/details.aspx?id=41158) tool. Microsoft Locale Builder is written in managed code using the `CultureAndRegionInfoBuilder` class.
+
+Several distinct names are closely associated with a culture, notably the names associated with the following class members:
+
+-
+-
+-
+
+## Invariant, neutral, and specific cultures
+
+The cultures are generally grouped into three sets: invariant cultures, neutral cultures, and specific cultures.
+
+An invariant culture is culture-insensitive. Your application specifies the invariant culture by name using an empty string ("") or by its identifier. defines an instance of the invariant culture. It is associated with the English language but not with any country/region. It is used in almost any method in the `Globalization` namespace that requires a culture.
+
+A neutral culture is a culture that is associated with a language but not with a country/region. A specific culture is a culture that is associated with a language and a country/region. For example, `fr` is the neutral name for the French culture, and `fr-FR` is the name of the specific French (France) culture. Note that Chinese (Simplified) and Chinese (Traditional) are also considered neutral cultures.
+
+Creating an instance of a class for a neutral culture is not recommended because the data it contains is arbitrary. To display and sort data, specify both the language and region. Additionally, the property of a object created for a neutral culture returns only the country and does not include the region.
+
+The defined cultures have a hierarchy in which the parent of a specific culture is a neutral culture and the parent of a neutral culture is the invariant culture. The property contains the neutral culture associated with a specific culture. Custom cultures should define the property in conformance with this pattern.
+
+If the resources for a specific culture are not available in the operating system, the resources for the associated neutral culture are used. If the resources for the neutral culture are not available, the resources embedded in the main assembly are used. For more information on the resource fallback process, see [Packaging and Deploying Resources](/dotnet/framework/resources/packaging-and-deploying-resources-in-desktop-apps).
+
+The list of locales in the Windows API is slightly different from the list of cultures supported by .NET. If interoperability with Windows is required, for example, through the p/invoke mechanism, the application should use a specific culture that's defined for the operating system. Use of the specific culture ensures consistency with the equivalent Windows locale, which is identified with a locale identifier that is the same as .
+
+A or a can be created only for the invariant culture or for specific cultures, not for neutral cultures.
+
+If is the but the is not set to `zh-TW`, then , , and return an empty string ("").
+
+## Custom cultures
+
+On Windows, you can create custom locales. For more information, see [Custom locales](/windows/win32/intl/custom-locales).
+
+## CultureInfo and cultural data
+
+.NET derives its cultural data from a one of a variety of sources, depending on implementation, platform, and version:
+
+- In all versions of .NET (Core) running on Unix platforms or Windows 10 and later versions, cultural data is provided by the [International Components for Unicode (ICU) Library](https://icu.unicode.org/). The specific version of the ICU Library depends on the individual operating system.
+- In all versions of .NET (Core) running on Windows 9 and earlier versions, cultural data is provided by the Windows operating system.
+- In .NET Framework 4 and later versions, cultural data is provided by the Windows operating system.
+- In .NET Framework 3.5 and earlier versions, cultural data is provided by both the Windows operating system and .NET Framework.
+
+Because of this, a culture available on a particular .NET implementation, platform, or version may not be available on a different .NET implementation, platform, or version.
+
+Some `CultureInfo` objects differ depending on the underlying platform. In particular, `zh-CN`, or Chinese (Simplified, China) and `zh-TW`, or Chinese (Traditional, Taiwan), are available cultures on Windows systems, but they are aliased cultures on Unix systems. "zh-CN" is an alias for the "zh-Hans-CN" culture, and "zh-TW" is an alias for the "zh-Hant-TW" culture. Aliased cultures are not returned by calls to the method and may have different property values, including different cultures, than their Windows counterparts. For the `zh-CN` and `zh-TW` cultures, these differenes include the following:
+
+- On Windows systems, the parent culture of the "zh-CN" culture is "zh-Hans", and the parent culture of the "zh-TW" culture is "zh-Hant". The parent culture of both these cultures is "zh". On Unix systems, the parents of both cultures are "zh". This means that, if you don't provide culture-specific resources for the "zh-CN" or "zh-TW" cultures but do provide a resources for the neutral "zh-Hans" or "zh-Hant" culture, your application will load the resources for the neutral culture on Windows but not on Unix. On Unix systems, you must explicitly set the thread's to either "zh-Hans" or "zh-Hant".
+
+- On Windows systems, calling on an instance that represents the "zh-CN" culture and passing it a "zh-Hans-CN" instance returns `true`. On Unix systems, the method call returns `false`. This behavior also applies to calling on a "zh-TW" instance and passing it a "zh-Hant-Tw" instance.
+
+## Dynamic culture data
+
+Except for the invariant culture, culture data is dynamic. This is true even for the predefined cultures. For example, countries or regions adopt new currencies, change their spellings of words, or change their preferred calendar, and culture definitions change to track this. Custom cultures are subject to change without notice, and any specific culture might be overridden by a custom replacement culture. Also, as discussed below, an individual user can override cultural preferences. Applications should always obtain culture data at run time.
+
+> [!CAUTION]
+> When saving data, your application should use the invariant culture, a binary format, or a specific culture-independent format. Data saved according to the current values associated with a particular culture, other than the invariant culture, might become unreadable or might change in meaning if that culture changes.
+
+## The current culture and current UI culture
+
+Every thread in a .NET application has a current culture and a current UI culture. The current culture determines the formatting conventions for dates, times, numbers, and currency values, the sort order of text, casing conventions, and the ways in which strings are compared. The current UI culture is used to retrieve culture-specific resources at run time.
+
+> [!NOTE]
+> For information on how the current and current UI culture is determined on a per-thread basis, see the [Culture and threads](#culture-and-threads) section. For information on how the current and current UI culture is determined on threads executing in a new application domain, and on threads that cross application domain boundaries, see the [Culture and application domains](#culture-and-application-domains) section. For information on how the current and current UI culture is determined on threads performing task-based asynchronous operations, see the [Culture and task-based asynchronous operations](#culture-and-task-based-asynchronous-operations) section.
+
+For more detailed information on the current culture, see the property. For more detailed information on the current UI culture, see the property topic.
+
+### Retrieve the current and current UI cultures
+
+You can get a object that represents the current culture in either of two ways:
+
+- By retrieving the value of the property.
+- By retrieving the value of the [Thread.CurrentThread.CurrentCulture]() property.
+
+The following example retrieves both property values, compares them to show that they are equal, and displays the name of the current culture.
+
+:::code language="csharp" source="./snippets/System.Globalization/CultureInfo/csharp/Current1.cs" id="Snippet1":::
+
+You can get a object that represents the current UI culture in either of two ways:
+
+- By retrieving the value of the property.
+
+- By retrieving the value of the [Thread.CurrentThread.CurrentUICulture]() property.
+
+The following example retrieves both property values, compares them to show that they are equal, and displays the name of the current UI culture.
+
+:::code language="csharp" source="./snippets/System.Globalization/CultureInfo/csharp/CurrentUI1.cs" id="Snippet2":::
+
+### Set the current and current UI cultures
+
+To change the culture and UI culture of a thread, do the following:
+
+1. Instantiate a object that represents that culture by calling a class constructor and passing it the name of the culture. The constructor instantiates a object that reflects user overrides if the new culture is the same as the current Windows culture. The constructor allows you to specify whether the newly instantiated object reflects user overrides if the new culture is the same as the current Windows culture.
+
+2. Assign the object to the or property on .NET Core and .NET Framework 4.6 and later versions. (On .NET Framework 4.5.2 and earlier versions, you can assign the `CultureInfo` object to the or property.)
+
+The following example retrieves the current culture. If it is anything other than the French (France) culture, it changes the current culture to French (France). Otherwise, it changes the current culture to French (Luxembourg).
+
+:::code language="csharp" source="./snippets/System.Globalization/CultureInfo/csharp/Change1.cs" id="Snippet3":::
+
+The following example retrieves the current culture. If it is anything other the Slovenian (Slovenia) culture, it changes the current culture to Slovenian (Slovenia). Otherwise, it changes the current culture to Croatian (Croatia).
+
+:::code language="csharp" source="./snippets/System.Globalization/CultureInfo/csharp/ChangeUI1.cs" id="Snippet4":::
+
+## Get all cultures
+
+You can retrieve an array of specific categories of cultures or of all the cultures available on the local computer by calling the method. For example, you can retrieve custom cultures, specific cultures, or neutral cultures either alone or in combination.
+
+The following example calls the method twice, first with the enumeration member to retrieve all custom cultures, and then with the enumeration member to retrieve all replacement cultures.
+
+:::code language="csharp" source="./snippets/System.Globalization/CultureInfo/csharp/GetCultures1.cs" id="Snippet5":::
+
+## Culture and threads
+
+When a new application thread is started, its current culture and current UI culture are defined by the current system culture, and not by the current thread culture. The following example illustrates the difference. It sets the current culture and current UI culture of an application thread to the French (France) culture (fr-FR). If the current culture is already fr-FR, the example sets it to the English (United States) culture (en-US). It displays three random numbers as currency values and then creates a new thread, which, in turn, displays three more random numbers as currency values. But as the output from the example shows, the currency values displayed by the new thread do not reflect the formatting conventions of the French (France) culture, unlike the output from the main application thread.
+
+:::code language="csharp" source="./snippets/System.Globalization/CultureInfo/csharp/defaultthread1.cs" id="Snippet1":::
+
+You can set the culture and UI culture of all threads in an application domain by assigning a object that represents that culture to the and properties. The following example uses these properties to ensure that all threads in the default application domain share the same culture.
+
+:::code language="csharp" source="./snippets/System.Globalization/CultureInfo/csharp/setthreads1.cs" id="Snippet3":::
+
+> [!WARNING]
+> Although the and properties are static members, they define the default culture and default UI culture only for the application domain that is current at the time these property values are set. For more information, see the next section, [Culture and application domains](#culture-and-application-domains).
+
+When you assign values to the and properties, the culture and UI culture of the threads in the application domain also change if they have not explicitly been assigned a culture. However, these threads reflect the new culture settings only while they execute in the current application domain. If these threads execute in another application domain, their culture becomes the default culture defined for that application domain. As a result, we recommend that you always set the culture of the main application thread, and not rely on the and properties to change it.
+
+## Culture and application domains
+
+ and are static properties that explicitly define a default culture only for the application domain that is current when the property value is set or retrieved. The following example sets the default culture and default UI culture in the default application domain to French (France), and then uses the class and the delegate to set the default culture and UI culture in a new application domain to Russian (Russia). A single thread then executes two methods in each application domain. Note that the thread's culture and UI culture are not explicitly set; they are derived from the default culture and UI culture of the application domain in which the thread is executing. Note also that the and properties return the default values of the application domain that is current when the method call is made.
+
+:::code language="csharp" source="./snippets/System.Globalization/CultureInfo/csharp/appdomainex1.cs" id="Snippet1":::
+
+For more information about cultures and application domains, see the "Application Domains and Threads" section in the [Application Domains](../../framework/app-domains/application-domains.md) topic.
+
+## Culture and task-based asynchronous operations
+
+The [task-based asynchronous programming pattern](../../standard/parallel-programming/task-based-asynchronous-programming.md) uses and objects to asynchronously execute delegates on thread pool threads. The specific thread on which a particular task runs is not known in advance, but is determined only at runtime.
+
+For apps that target .NET Framework 4.6 or a later version, culture is part of an asynchronous operation's context. In other words, asynchronous operations by default inherit the values of the and properties of the thread from which they are launched. If the current culture or current UI culture differs from the system culture, the current culture crosses thread boundaries and becomes the current culture of the thread pool thread that is executing an asynchronous operation.
+
+The following example provides a simple illustration. The example defines a delegate, `formatDelegate`, that returns some numbers formatted as currency values. The example changes the current system culture to either French (France) or, if French (France) is already the current culture, English (United States). It then:
+
+- Invokes the delegate directly so that it runs synchronously on the main app thread.
+- Creates a task that executes the delegate asynchronously on a thread pool thread.
+- Creates a task that executes the delegate synchronously on the main app thread by calling the method.
+
+As the output from the example shows, when the current culture is changed to French (France), the current culture of the thread from which tasks are invoked asynchronously becomes the current culture for that asynchronous operation.
+
+:::code language="csharp" source="./snippets/System.Globalization/CultureInfo/csharp/asyncculture1.cs" id="Snippet1":::
+
+For apps that target versions of .NET Framework from .NET Framework 4.5 and later but prior to .NET Framework 4.6, you can use the and properties to ensure that the culture of the calling thread is used in asynchronous tasks that execute on thread pool threads. The following example is identical to the previous example, except that it uses the property to ensure that thread pool threads have the same culture as the main app thread.
+
+:::code language="csharp" source="./snippets/System.Globalization/CultureInfo/csharp/asyncculture3.cs" id="Snippet3":::
+
+ and are per-app domain properties; that is, they establish a default culture for all threads not explicitly assigned a culture in a specific application domain. However, for apps that target .NET Framework 4.6 or later, the culture of the calling thread remains part of an asynchronous task's context even if the task crosses app domain boundaries.
+
+## CultureInfo object serialization
+
+When a object is serialized, all that is actually stored is and . It is successfully deserialized only in an environment where that has the same meaning. The following three examples show why this is not always the case:
+
+- If the property value is , and if that culture was first introduced in a particular version of the Windows operating system, it is not possible to deserialize it on an earlier version of Windows. For example, if a culture was introduced in Windows 10, it cannot be deserialized on Windows 8.
+
+- If the value is , and the computer on which it is deserialized does not have this user custom culture installed, it is not possible to deserialize it.
+
+- If the value is , and the computer on which it is deserialized does not have this replacement culture, it deserializes to the same name, but not all of the same characteristics. For example, if `en-US` is a replacement culture on computer A, but not on computer B, and if a object referring to this culture is serialized on computer A and deserialized on computer B, then none of the custom characteristics of the culture are transmitted. The culture deserializes successfully, but with a different meaning.
+
+## Control Panel overrides
+
+The user might choose to override some of the values associated with the current culture of Windows through the regional and language options portion of Control Panel. For example, the user might choose to display the date in a different format or to use a currency other than the default for the culture. In general, your applications should honor these user overrides.
+
+If is `true` and the specified culture matches the current culture of Windows, the uses those overrides, including user settings for the properties of the instance returned by the property, and the properties of the instance returned by the property. If the user settings are incompatible with the culture associated with the , for example, if the selected calendar is not one of the , the results of the methods and the values of the properties are undefined.
+
+## Alternate sort orders
+
+Some cultures support more than one sort order. For example:
+
+- The Spanish (Spain) culture has two sort orders: the default international sort order, and the traditional sort order. When you instantiate a object with the `es-ES` culture name, the international sort order is used. When you instantiate a object with the `es-ES-tradnl` culture name, the traditional sort order is used.
+
+- The `zh-CN` (Chinese (Simplified, PRC)) culture supports two sort orders: by pronunciation (the default) and by stroke count. When you instantiate a object with the `zh-CN` culture name, the default sort order is used. When you instantiate a object with a local identifier of 0x00020804, strings are sorted by stroke count.
+
+The following table lists the cultures that support alternate sort orders and the identifiers for the default and alternate sort orders.
+
+|Culture name|Culture|Default sort name and identifier|Alternate sort name and identifier|
+|------------------|-------------|--------------------------------------|----------------------------------------|
+|es-ES|Spanish (Spain)|International: 0x00000C0A|Traditional: 0x0000040A|
+|zh-TW|Chinese (Taiwan)|Stroke Count: 0x00000404|Bopomofo: 0x00030404|
+|zh-CN|Chinese (PRC)|Pronunciation: 0x00000804|Stroke Count: 0x00020804|
+|zh-HK|Chinese (Hong Kong SAR)|Stroke Count: 0x00000c04|Stroke Count: 0x00020c04|
+|zh-SG|Chinese (Singapore)|Pronunciation: 0x00001004|Stroke Count: 0x00021004|
+|zh-MO|Chinese (Macao SAR)|Pronunciation: 0x00001404|Stroke Count: 0x00021404|
+|ja-JP|Japanese (Japan)|Default: 0x00000411|Unicode: 0x00010411|
+|ko-KR|Korean (Korea)|Default: 0x00000412|Korean Xwansung - Unicode: 0x00010412|
+|de-DE|German (Germany)|Dictionary: 0x00000407|Phone Book Sort DIN: 0x00010407|
+|hu-HU|Hungarian (Hungary)|Default: 0x0000040e|Technical Sort: 0x0001040e|
+|ka-GE|Georgian (Georgia)|Traditional: 0x00000437|Modern Sort: 0x00010437|
+
+## The current culture and UWP apps
+
+In Universal Windows Platform (UWP) apps, the and properties are read-write, just as they are in .NET Framework and .NET Core apps. However, UWP apps recognize a single culture. The and properties map to the first value in the [Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages](/uwp/api/windows.applicationmodel.resources.core.resourcecontext#properties_) collection.
+
+In .NET apps, the current culture is a per-thread setting, and the and properties reflect the culture and UI culture of the current thread only. In UWP apps, the current culture maps to the [Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages](/uwp/api/windows.applicationmodel.resources.core.resourcecontext#properties_) collection, which is a global setting. Setting the or property changes the culture of the entire app; culture cannot be set on a per-thread basis.
diff --git a/docs/fundamentals/runtime-libraries/system-globalization-datetimeformatinfo.md b/docs/fundamentals/runtime-libraries/system-globalization-datetimeformatinfo.md
new file mode 100644
index 0000000000000..67c8066c365c7
--- /dev/null
+++ b/docs/fundamentals/runtime-libraries/system-globalization-datetimeformatinfo.md
@@ -0,0 +1,282 @@
+---
+title: System.Globalization.DateTimeFormatInfo class
+description: Learn more about the System.Globalization.DateTimeFormatInfo class.
+ms.date: 12/28/2023
+ms.topic: conceptual
+---
+# class
+
+[!INCLUDE [context](includes/context.md)]
+
+The properties of the class contain culture-specific information for formatting or parsing date and time values such as the following:
+
+- The patterns used to format date values.
+- The patterns used to format time values.
+- The names of the days of the week.
+- The names of the months of the year.
+- The A.M. and P.M. designators used in time values.
+- The calendar in which dates are expressed.
+
+## Instantiate a DateTimeFormatInfo object
+
+A object can represent the formatting conventions of the invariant culture, a specific culture, a neutral culture, or the current culture. This section discusses how to instantiate each type of object.
+
+### Instantiate a DateTimeFormatInfo object for the invariant culture
+
+The invariant culture represents a culture that is culture-insensitive. It is based on the English language, but not on any specific English-speaking country/region. Although the data of specific cultures can be dynamic and can change to reflect new cultural conventions or user preferences, the data of the invariant culture does not change. You can instantiate a object that represents the formatting conventions of the invariant culture in the following ways:
+
+- By retrieving the value of the property. The returned object is read-only.
+- By calling the parameterless constructor. The returned object is read/write.
+- By retrieving the value of the property from the object that is returned by the property. The returned object is read-only.
+
+The following example uses each of these methods to instantiate a object that represents the invariant culture. It then indicates whether the object is read-only.
+
+:::code language="csharp" source="./snippets/System.Globalization/DateTimeFormatInfo/csharp/create1.cs" interactive="try-dotnet-method" id="Snippet1":::
+
+### Instantiate a DateTimeFormatInfo object for a specific culture
+
+A specific culture represents a language that is spoken in a particular country/region. For example, en-US is a specific culture that represents the English language spoken in the United States, and en-CA is a specific culture that represents the English language spoken in Canada. You can instantiate a object that represents the formatting conventions of a specific culture in the following ways:
+
+- By calling the method and retrieving the value of the returned object's property. The returned object is read-only.
+
+- By passing the static method a object that represents the culture whose object you want to retrieve. The returned object is read/write.
+
+- By calling the static method and retrieving the value of the returned object's property. The returned object is read/write.
+
+- By calling the class constructor and retrieving the value of the returned object's property. The returned object is read/write.
+
+The following example illustrates each of these ways to instantiate a object and indicates whether the resulting object is read-only.
+
+:::code language="csharp" source="./snippets/System.Globalization/DateTimeFormatInfo/csharp/create1.cs" interactive="try-dotnet-method" id="Snippet3":::
+
+### Instantiate a DateTimeFormatInfo object for a neutral culture
+
+A neutral culture represents a culture or language that is independent of a country/region; it is typically the parent of one or more specific cultures. For example, Fr is a neutral culture for the French language and the parent of the fr-FR culture. You can instantiate a object that represents the formatting conventions of a neutral culture in the same ways that you create a object that represents the formatting conventions of a specific culture. In addition, you can retrieve a neutral culture's object by retrieving a neutral culture from a specific culture's property and retrieving the object returned by its property. Unless the parent culture represents the invariant culture, the returned object is read/write. The following example illustrates these ways of instantiating a object that represents a neutral culture.
+
+:::code language="csharp" source="./snippets/System.Globalization/DateTimeFormatInfo/csharp/create1.cs" interactive="try-dotnet-method" id="Snippet2":::
+
+However, a neutral culture lacks culture-specific formatting information, because it is independent of a specific country/region. Instead of populating the object with generic values, .NET returns a object that reflects the formatting conventions of a specific culture that is a child of the neutral culture. For example, the object for the neutral en culture reflects the formatting conventions of the en-US culture, and the object for the fr culture reflects the formatting conventions of the fr-FR culture.
+
+You can use code like the following to determine which specific culture's formatting conventions a neutral culture represents. The example uses reflection to compare the properties of a neutral culture with the properties of a specific child culture. It considers two calendars to be equivalent if they are the same calendar type and, for Gregorian calendars, if their properties have identical values.
+
+:::code language="csharp" source="./snippets/System.Globalization/DateTimeFormatInfo/csharp/instantiate6.cs" interactive="try-dotnet" id="Snippet6":::
+
+### Instantiate a DateTimeFormatInfo object for the current culture
+
+You can instantiate a object that represents the formatting conventions of the current culture in the following ways:
+
+- By retrieving the value of the property. The returned object is read-only.
+
+- By retrieving the value of the property from the object that is returned by the property. The returned object is read-only.
+
+- By calling the