2

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."
        }
    }
}
  • Similar problem I am facing here http://stackoverflow.com/questions/42202771/numbergroupsizes-for-en-in-culture-in-windows-server-2012-is-wrong The issue seems to be with 2012 servers. – Hemanth Bidare Feb 16 '17 at 11:24

0 Answers0