With the release of my Weather Barometer app I received a lot of feedback and questions around incorrect measurement units, so I thought I would put together a blog post about this as it’s a little more ‘interesting’ then one would expect. Weather Barometer uses meters or feet for elevation and hectopascal (hPa which are the same as millibars) or inches Mercury (inHg) for barometric pressure. The hectopascal is the international metric unit for measuring atmospheric or barometric pressure. One hectopascal is exactly equal to one millibar, and although the scientific community has officially adopted the hectopascal in preference to the millibar, the millibar is still used extensively throughout the world due to the proliferation of its use historically. So we are using accepted measurement units, but the question is why don’t I see the unit of measurement I expect.
First let me describe the code that is responsible for displaying the units. The native Windows GPS units are metric, so if we are going to display GPS elevation in metric then we don’t need to do anything, but if we want to display elevation in feet, however, then we need to convert the native GPS meters to feet; for that we use a Converter.
public sealed class ElevationValueToStringConverter : IValueConverter
{
public object ConvertBack(object value, Type targetType,
object parameter, string language)
{
throw new NotImplementedException("Converting from string is not supported.");
//return value;
}
public object Convert(object value, Type targetType,
object parameter, string language)
{
double x;
try
{
x = (double)value;
if (Double.IsNaN(x))
{
return "";
}
}
catch (Exception)
{
return "";
}
if (RegionInfo.CurrentRegion.IsMetric)
{
return x.ToString("F0");
}
else
{
return (x * 3.2808).ToString("F0");
}
}
}
NOTE the line RegionInfo.CurrentRegion.IsMetric is responsible for querying the system to see what units the user has selected. The Microsoft documentation for this is here https://msdn.microsoft.com/en-us/library/system.globalization.regioninfo.ismetric(v=vs.110).aspx and states RegionInfo.IsMetric gets a value indicating whether the country/region uses the metric system for measurements, but why are we using ‘RegionInfo.CurrentRegion’, looking at the Microsoft documentation for this here https://msdn.microsoft.com/en-us/library/system.globalization.regioninfo.currentregion(v=vs.110).aspx we see that it gets the RegionInfo that represents the country/region used by the current thread, ie the Weather Barometer thread, so it should be returning a true or false concerning if the user’s region uses metric measurements or not.
The Windows Phone barometer sensor also returns pressures in metric so we have similar code for displaying pressure where 0.0295299830714 is the conversion factor for converting hPa to inHg. I should mention that Converters are a cool and handy programming feature in UWP.
public sealed class PressureValueToStringConverter : IValueConverter
{
public object ConvertBack(object value, Type targetType,
object parameter, string language)
{
throw new NotImplementedException("Converting from string is not supported.");
//return value;
}
public object Convert(object value, Type targetType,
object parameter, string language)
{
double x;
try
{
x = (double)value;
if (Double.IsNaN(x))
{
return "";
}
}
catch (Exception)
{
return "";
}
if (RegionInfo.CurrentRegion.IsMetric)
{
return (x).ToString("F2");
}
else
{
return (x*0.0295299830714).ToString("F2");
}
}
}
So now we know how the code works, how do the settings work to display the data in the units we want to see? In the Windows Phone Settings there is ‘Time & Language’ which allows you to set ‘Speech, region, keyboard’.
If we open that we see ‘Date & Time’, ‘Language’, ‘Region’, ‘Keyboard’ and ‘Speech’.
Now I think that most people believe that unit of measure are controlled by the Region settings, which makes sense given that for most countries the units of measure mandated by the government. Looking at the Region Settings we see we can change what Country/Region we are in by changing the selected country, so for example one would think that if the Country/Region is say set to ‘Canada’
then metric units of measure would be used, whereas if we switch that to ‘United States’ that the phone would switch to using imperial given the United States uses the imperial system. So first a screen shot of the Weather Barometer with Region set to Canada showing metric unit usage:
Now if we change the Region to ‘United States’ and restart the phone as required,
we see it is still displaying Metric units in the Weather Barometer.
Now this isn’t what most people probably expected, so what is it that controls which units are used, if it’s not the Region setting? If we switch the Region back to ‘Canada’, restart the phone to get back to our ‘all Canada settings’ and go into ‘LANGUAGE’ we see that I have ‘English (Canada)’ as the top listed language which makes it the active language.
If we tap and hold our finger on ‘English (United States)’ such that the popup menu appears and then select ‘Move up’ until it is at the top of the list
and then restart as required to make ‘English (United States)’ the active language and, when we run the Weather Barometer we see that the units used are now imperial.
So it’s the language setting which determines which units are used. This might be confusing or counter-intuitive but it is how Microsoft set it up. I was thinking about this and I think it might because there is a country (or countries) that use different units of measure in different regions, and which might have different languages. Microsoft might have connected units to country/languages to accommodate this. I don’t know of any countries where this is the case, but I can’t claim to be an expert on the topic. Now remember on the REGION screen for Regional format we were using the default setting of ‘Match phone language’,
what would happen if we changed that to say ‘English (Canada)’ and did a restart, leaving our active language as ‘English (United States)’?
If we now run Weather Barometer the units are still shown in imperial,
so clearly Language controls what units the system uses.
I hope this helps you understand how the Regions/Language setting determines whether your phone is using Metric or Imperial units. I would agree that it seems a little confusing and counter-intuitive, but I’m sure Microsoft has reasons why it is set up this way I’m still considering not using the system unit setting, however, and making it an application setting to make it easy for users to set and get the units they want.
As a follow up I have tested some language settings which should return metric but don’t, so I’m following up with Microsoft to see if its something I need to fix, a setting I’m missing or something else. I’ll post as I get information.