Overview
Consistent Culture
settings have been made on both local machine and server, yet they produce differently formatted DateTime
strings:
local: "22/11/2016 12:00:00 AM"
server: "22/11/2016 12:00:00 a.m."
Context
- Language: C# 6
- Platform: .NET 4.6.1
- Local OS: Windows 10 Pro
- Server OS: Windows Server 2012 R2, version 6.3
Background
I am writing a unit test that I would like to behave exactly the same regardless of where the test is run. To do this, I created a custom attribute to manually set the current CultureInfo
of the machine for the duration of the test. This way if I run the test locally in New Zealand, it will still behave the same when run on an AWS server in the United States (in this case to ensure consistent formatting of date strings, where New Zealand = dd/mm/yyyy and United States = mm/dd/yyyy) or anywhere else in the world.
So far the custom attribute correctly sets the machine's culture settings and correctly formats the date and time between New Zealand (dd/mm/yyyy) and United States(mm/dd/yyyy), except my local machine outputs an "AM" following the time, while the server outputs "a.m." (see code below, this is the AMDesignator
property of the DateTimeFormat
class). It seems the server is grabbing formatting settings from outside of the CultureInfo
specified, why is this happening? Am I missing something?
Note - CultureSwitcher.SetTo(CultureInfo culture)
sets both the CurrentCulture
and CurrentUICulture
to the specified CultureInfo
provided.
Results (local | server):
using (var poly = PAssert.Poly())
{
var date = new DateTime(2016, 11, 22);
// New Zealand culture
using (CultureSwitcher.SetTo(new CultureInfo("en-NZ")))
{
var currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture;
var amDesignator = currentCulture.DateTimeFormat.AMDesignator;
var currencySymbol = currentCulture.NumberFormat.CurrencySymbol;
poly.IsTrue(() => System.Threading.Thread.CurrentThread.CurrentCulture.ToString() == "en-NZ"); // True | True
poly.IsTrue(() => System.Threading.Thread.CurrentThread.CurrentUICulture.ToString() == "en-NZ"); // True | True
poly.IsTrue(() => CultureInfo.CurrentCulture.ToString() == "en-NZ"); // True | True
poly.IsTrue(() => CultureInfo.CurrentUICulture.ToString() == "en-NZ"); // True | True
poly.IsTrue(() => amDesignator == "AM"); // True | FALSE - expected "a.m."
poly.IsTrue(() => date.ToString() == "22/11/2016 12:00:00 AM"); // True | FALSE - expected "22/11/2016 12:00:00 a.m."
}
// United States culture
using (CultureSwitcher.SetTo(new CultureInfo("en-US")))
{
var culture = CultureInfo.CreateSpecificCulture("en-US");
var amDesignator = culture.DateTimeFormat.AMDesignator;
var currencySymbol = culture.NumberFormat.CurrencySymbol;
poly.IsTrue(() => System.Threading.Thread.CurrentThread.CurrentCulture.ToString() == "en-US"); // True | True
poly.IsTrue(() => System.Threading.Thread.CurrentThread.CurrentUICulture.ToString() == "en-US"); // True | True
poly.IsTrue(() => CultureInfo.CurrentCulture.ToString() == "en-US"); // True | True
poly.IsTrue(() => CultureInfo.CurrentUICulture.ToString() == "en-US"); // True | True
poly.IsTrue(() => amDesignator == "AM"); // True | True
poly.IsTrue(() => date.ToString() == "11/22/2016 12:00:00 AM"); // True | True
}
}
Try it yourself (results = local | server):
using System;
using System.Globalization;
namespace ConsoleApplication
{
class Program
{
static void Main()
{
// New Zealand culture
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-NZ");
System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en-NZ");
Console.WriteLine(CultureInfo.CurrentCulture.DateTimeFormat.AMDesignator); // "AM" | "a.m."
Console.WriteLine(CultureInfo.CreateSpecificCulture("en-US").DateTimeFormat.AMDesignator); // "AM" | "AM"
Console.WriteLine(CultureInfo.CreateSpecificCulture("en-NZ").DateTimeFormat.AMDesignator); // "AM" | "a.m."
// United States culture
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
Console.WriteLine(CultureInfo.CurrentCulture.DateTimeFormat.AMDesignator); // "AM" | "AM"
Console.WriteLine(CultureInfo.CreateSpecificCulture("en-US").DateTimeFormat.AMDesignator); // "AM" | "AM"
Console.WriteLine(CultureInfo.CreateSpecificCulture("en-NZ").DateTimeFormat.AMDesignator); // "AM" | "a.m."
}
}
}