I really dislike the fact that String.Format
uses the current culture. This means that the output depends on the user's system. For example, if I code this quickly without thinking about cultures:
var now = DateTime.Now;
string json = String.Format("{{ 'Date': \"{0}\" }}", now);
I can test this, and it works great on my system.
{ 'Date': "9-11-2013 13:37:00" }
And after a while I forget about this little snippet of code, and it ends up in my product. Then some user in Saudi Arabia uses program, and everything fails since it produced:
{ 'Date': "06/01/35 01:37:00 ?" }
To prevent such bugs I want String.Format
to use the invariant culture by default, and if I want to use a specific culture I can specify the culture explicitly. This will prevent all such bugs.
In C# 6 you can use string interpolation to do string formatting. It's still current culture specific though.
string json = $"{{ 'Date': \"{now}\" }}";
Luckily there is a way to make it culture invariant. Statically import the System.FormattableString
namespace and use the Invariant
method, like this:
using static System.FormattableString;
string json = Invariant($"{{ 'Date': \"{now}\" }}");
For C# 5 and earlier, I wrote myself a set of extension methods to do that for me. In the process, it also provides a much nicer syntax.
public static string FormatInvariant(this string format, params object[] args)
{
if (format == null) throw new NullReferenceException("format");
if (args == null) throw new NullReferenceException("args");
return FormatWith(format, CultureInfo.InvariantCulture, args);
}
public static string FormatCurrentCulture(this string format, params object[] args)
{
if (format == null) throw new NullReferenceException("format");
if (args == null) throw new NullReferenceException("args");
return FormatWith(format, CultureInfo.CurrentCulture, args);
}
public static string FormatWith(this string format, IFormatProvider provider, params object[] args)
{
if (format == null) throw new NullReferenceException("format");
if (provider == null) throw new NullReferenceException("provider");
if (args == null) throw new NullReferenceException("args");
return String.Format(provider, format, args);
}
(Get the full source code with comments and Code Contracts.)
Example usage:
string json = "{{ 'Date': \"{0}\" }}".FormatInvariant(now);