|
1 | 1 | [/statusIcon)](http://anj.no:8500/viewType.html?buildTypeId=UnitsNet_ReleaseBuilds&guest=1 "Build Status")
|
2 | 2 | Units.NET
|
3 |
| -======== |
| 3 | +=== |
4 | 4 | Everyone have written their share of trivial conversions - or less obvious ones where you need to Google that magic constant.
|
5 | 5 |
|
6 | 6 | Stop littering your code with unnecessary calculations. Units.NET gives you all the common units of measurement and the conversions between them. It is light-weight, unit tested and supports [PCL](http://msdn.microsoft.com/en-us/library/gg597391.aspx "MSDN PCL").
|
7 | 7 |
|
8 | 8 |
|
9 |
| -Install |
10 |
| -======= |
11 |
| -To install Units.NET, run the following command in the [Package Manager Console](http://docs.nuget.org/docs/start-here/using-the-package-manager-console) or go to the [NuGet site](https://www.nuget.org/packages/UnitsNet/ "NuGet site") for the complete relase history. |
| 9 | +Installing |
| 10 | +=== |
| 11 | +Run the following command in the [Package Manager Console](http://docs.nuget.org/docs/start-here/using-the-package-manager-console) or go to the [NuGet site](https://www.nuget.org/packages/UnitsNet/) for the complete relase history. |
12 | 12 |
|
13 |
| - |
| 13 | + |
14 | 14 |
|
15 | 15 | Build Targets:
|
| 16 | +* Portable Class Library (.NET 4.0 + Silverlight 5 + Win8/WinPhone8) |
16 | 17 | * .NET 3.5 Client
|
17 |
| -* Silverlight 4 |
18 |
| -* WinRT / .NET Core 4.5 |
19 |
| -* Portable Class Library (.NET 4.0 + Silverlight 4 + Windows Phone 7 + Xbox 360) |
20 | 18 |
|
21 | 19 | Features
|
22 |
| -======== |
23 |
| - |
24 |
| -* Immutable structs for units of measurement, such as Length, Mass, Force and Pressure. See full list [here](https://github.com/InitialForce/UnitsNet/blob/master/Src/UnitsNet/ "Data structures"). |
25 |
| -* Convert between most popular units in the metric and imperial systems. See full list [here](https://github.com/InitialForce/UnitsNet/blob/master/Src/UnitsNet/Unit.cs "Unit.cs"). |
26 |
| -* Choose between static (Length, Mass, Force etc.) or dynamic (UnitValue) representations for units of measurement. |
27 |
| -* Parse abbreviation string to unit taking culture into account. |
28 |
| -* Get abbreviation string for unit in different cultures. |
29 |
| - |
30 |
| -Static Representation and Explicit Conversion |
31 |
| ------------------------------------------------ |
| 20 | +=== |
| 21 | +* 15+ units of measurement, [see full list](https://github.com/InitialForce/UnitsNet/tree/develop/Src/UnitsNet/Units) |
| 22 | +* Generated code for uniform implementations and fewer bugs |
| 23 | +* Immutable structs implementing IEquatable, IComparable and operator overloads |
| 24 | +* Extendable with [custom units](https://github.com/InitialForce/UnitsNet/wiki/Extending-with-Custom-Units) |
| 25 | +* Localization of abbreviations |
| 26 | +* ToString() variants for custom cultures and format patterns |
| 27 | +* Over 200 tests to ensure conversions and localizations are in order |
| 28 | + |
| 29 | +Statically Typed Units |
| 30 | +--- |
32 | 31 | ```C#
|
33 |
| -// Stop postfixing your variables and method names with the unit... |
34 |
| -double weightKg = GetPersonWeightInKg(); |
35 |
| -UpdatePersonWeightInGrams(weightKg * 1000); |
36 |
| - |
37 |
| -// ...and start using a static representation for the measurement then |
38 |
| -// explicitly convert to the unit of choice - when you need it. |
| 32 | +// Convert to the unit of choice - when you need it. |
39 | 33 | Mass weight = GetPersonWeight();
|
40 | 34 | UpdatePersonWeightInGrams(weight.Grams);
|
41 | 35 |
|
42 |
| -// Convert between compatible units of measurement... |
43 |
| -Force scaleMeasurement = Force.FromNewtons(850); |
44 |
| -Mass personWeight = Mass.FromGravitationalForce(scaleMeasurement); |
45 |
| -double weightKg = personWeight.Kilograms; |
46 |
| - |
47 |
| -// ...while avoiding confusing conversions, such as between weight and mass. |
| 36 | +// Avoid confusing conversions, such as between weight and mass. |
48 | 37 | Mass weight = GetPersonWeight();
|
49 |
| -double weightNewtons = weight.Newtons; // No such thing. |
| 38 | +double weightNewtons = weight.Newtons; // No such thing |
50 | 39 |
|
51 | 40 | // Some popular conversions.
|
52 | 41 | Length meter = Length.FromMeters(1);
|
53 | 42 | double cm = meter.Centimeters; // 100
|
54 | 43 | double yards = meter.Yards; // 1.09361
|
55 | 44 | double feet = meter.Feet; // 3.28084
|
56 | 45 | double inches = meter.Inches; // 39.3701
|
57 |
| -
|
58 |
| -Pressure p = Pressure.FromPascal(1); |
59 |
| -double kpa = p.KiloPascals; // 1×10-3 |
60 |
| -double bar = p.Bars; // 1×10-5 |
61 |
| -double atm = p.Atmosphere; // 9.86923267×10-6 |
62 |
| -double psi = p.Psi; // 1.45037738×10-4 |
63 | 46 | ```
|
64 | 47 |
|
65 |
| -Dynamic Representation and Conversion |
66 |
| ------------------- |
| 48 | +Unit Enumeration |
| 49 | +--- |
| 50 | +All units have a corresponding unit enum value, in fact the unit classes are generated from these. This is useful when you want to let the user choose the unit, such as when editing the height in his user profile. |
67 | 51 | ```C#
|
68 |
| -// Explicitly |
69 |
| -double m = UnitConverter.Convert(1, Unit.Kilometer, Unit.Meter); // 1000 |
70 |
| -double mi = UnitConverter.Convert(1, Unit.Kilometer, Unit.Mile); // 0.621371 |
71 |
| -double yds = UnitConverter.Convert(1, Unit.Meter, Unit.Yard); // 1.09361 |
| 52 | +/// <summary>Convert the previous height to the new unit.</summary> |
| 53 | +void OnUserChangedHeightUnit(LengthUnit prevUnit, double prevValue, LengthUnit newUnit) |
| 54 | +{ |
| 55 | + // Construct from dynamic unit and value |
| 56 | + var prevHeight = Length.From(prevValue, prevUnit); |
| 57 | + |
| 58 | + // Convert to the new unit |
| 59 | + double newHeightValue = prevHeight.As(newUnit); |
| 60 | + |
| 61 | + // Update UI with the converted value and the newly selected unit |
| 62 | + UpdateHeightUI(newHeightValue, newUnit); |
| 63 | +} |
| 64 | +``` |
72 | 65 |
|
73 |
| -// Or dynamically. |
74 |
| -UnitValue val = GetUnknownValueAndUnit(); |
| 66 | +Culture and Localization |
| 67 | +--- |
| 68 | +The culture defaults to Thread.CurrentUICulture and affects localization of unit abbreviations as well as number formatting. The relevant methods are: |
75 | 69 |
|
76 |
| -// Returns false if conversion was not possible. |
77 |
| -double cm; |
78 |
| -val.TryConvert(Unit.Centimeter, out cm); |
79 |
| -``` |
| 70 | +* ToString() |
| 71 | +* GetAbbreviation() |
| 72 | +* Parse/TryParse() |
| 73 | +* ParseUnit/TryParseUnit() support cultures. |
| 74 | + |
| 75 | +The abbreviations support localization, but currently only US English, Russian and Norwegian are implemented. Localization defaults to US English if no localization for the current/specified culture is found. |
80 | 76 |
|
81 |
| -Helper Methods to Construct Measurements |
82 |
| ----------------------------------------- |
83 | 77 | ```C#
|
84 |
| -var f = Force.FromPressureByArea(Pressure p, Length2d area); |
85 |
| -var f = Force.FromMassAcceleration(Mass mass, double metersPerSecondSquared); |
| 78 | +var usEnglish = new CultureInfo("en-US"); |
| 79 | +var russian = new CultureInfo("ru-RU"); |
| 80 | +var oneKg = Mass.FromKilograms(1); |
| 81 | + |
| 82 | +// ToString() with Thread.CurrentUICulture as US English and Russian respectively |
| 83 | +"1 kg" == oneKg.ToString(); |
| 84 | +"1 кг" == oneKg.ToString(); |
| 85 | + |
| 86 | +// ToString() with specific culture and string format pattern |
| 87 | +"mg 1.00" == oneKg.ToString(MassUnit.Milligram, usEnglish, "{1} {0:0.00}"); |
| 88 | +"мг 1,00" == oneKg.ToString(MassUnit.Milligram, russian, "{1} {0:0.00}"); |
| 89 | + |
| 90 | +// Parse measurement from string |
| 91 | +Mass kg = Mass.Parse(usEnglish, "1.0 kg"); |
| 92 | +Mass kg = Mass.Parse(russian, "1,0 кг"); |
| 93 | + |
| 94 | +// Parse unit from string, a unit can have multiple abbreviations |
| 95 | +RotationalSpeedUnit.RevolutionPerMinute == RotationalSpeed.ParseUnit("rpm"); |
| 96 | +RotationalSpeedUnit.RevolutionPerMinute == RotationalSpeed.ParseUnit("r/min"); |
| 97 | + |
| 98 | +// Get default abbreviation for a unit |
| 99 | +"kg" == Mass.GetAbbreviation(MassUnit.Kilogram); |
86 | 100 | ```
|
87 | 101 |
|
88 |
| -Parse and Get Culture-Specific Abbreviations |
89 |
| -------------------------------------------------- |
| 102 | +Helper Construction Methods |
| 103 | +--- |
| 104 | +Construct measurements with various helper methods for convenience and readability. |
90 | 105 | ```C#
|
91 |
| -var us = new CultureInfo("en-US"); |
92 |
| -var norwegian = new CultureInfo("nb-NO"); |
93 |
| - |
94 |
| -Unit.Tablespoon == UnitSystem.Create(us).Parse("tbsp"); |
95 |
| -Unit.Tablespoon == UnitSystem.Create(norwegian).Parse("ss"); |
96 |
| - |
97 |
| -"T" == UnitSystem.GetDefaultAbbreviation(Unit.Tablespoon, us); |
98 |
| -"ss" == UnitSystem.GetDefaultAbbreviation(Unit.Tablespoon, norwegian); |
| 106 | +Force.FromPressureByArea(Pressure p, Length2d area) |
| 107 | +Force.FromMassAcceleration(Mass mass, double metersPerSecondSquared) |
99 | 108 | ```
|
100 | 109 |
|
101 |
| -Precision |
102 |
| -========= |
103 |
| -A base unit is chosen for all classes of units, which is represented by a double value (64-bit), and all conversions go via this unit. |
104 |
| -This means there will always be a small error in both representing other units than the base unit as well as converting between units. |
| 110 | +Precision and Accuracy |
| 111 | +=== |
| 112 | +A base unit is chosen for each unit class, represented by a double value (64-bit), and all conversions go via this unit. This means there will always be a small error in both representing other units than the base unit as well as converting between units. Also, some conversions may use different constants in different contexts, such as the air temperature or the standard gravity. |
| 113 | + |
| 114 | +Units.NET was intended for convenience and ease of use, not highly accurate conversions, but I am open to suggestions for improvements. |
| 115 | + |
| 116 | +The tests accept an error up to 1E-5 for all the units added so far. In many usecases this is sufficient, but for others this may be a showstopper and something you need to be aware of. |
105 | 117 |
|
106 |
| -In the unit tests I accept an error less than 1E-5 for all units I've added so far. In many usecases this is sufficient, but for some usecases this is definitely not OK and something you need to be aware of. |
107 | 118 | For more details, see [Precision](https://github.com/InitialForce/UnitsNet/wiki/Precision).
|
108 | 119 |
|
109 | 120 |
|
110 | 121 | What It Is Not
|
111 |
| -============== |
112 |
| - |
| 122 | +=== |
113 | 123 | * It is not an equation solver.
|
114 | 124 | * It does not figure out the units after a calculation.
|
115 | 125 |
|
116 |
| -Frequently Asked Questions |
117 |
| -========================== |
118 |
| -Q: Why is the conversion not perfectly accurate? |
119 |
| -As an example, when converting 1 PoundForce (lbF) to KilogramForce (kgF) I expected the result to be 0.45359237 and instead I got0.45359240790780886 using the following for the conversion: |
120 |
| - |
121 |
| -```C# |
122 |
| -double kg = UnitConverter.Convert(1, Unit.PoundForce, Unit.KilogramForce); |
123 |
| -``` |
124 |
| - |
125 |
| -A: There are a few concerns here. |
126 |
| -* For several unit conversions there is no one perfect answer. Some units depend on constants such as the standard gravity, where different precisions are used in different contexts. Other constants depend on the environment, such as the temperature or altitude. |
127 |
| -* By design, Units.NET was not intended for high-accuracy conversions but rather convenience and simplicity. I am open to suggestions for improvements. If you want to know more, see the [Precision](https://github.com/InitialForce/UnitsNet/wiki/Precision) article. |
128 |
| - |
129 |
| - |
130 | 126 | Want To Contribute?
|
131 |
| -=================== |
132 |
| -This project is still early and many units and conversions are not yet covered. If you are missing something, please help by contributing or [ask](https://github.com/InitialForce/UnitsNet/issues) for it by creating an issue. |
| 127 | +== |
| 128 | +This project is still early and many units and conversions are not yet covered. If you are missing something, please help by contributing or [ask for it](https://github.com/InitialForce/UnitsNet/issues) by creating an issue. |
133 | 129 |
|
134 |
| -Before adding new units, please read the wiki on [Adding a New Unit](https://github.com/InitialForce/UnitsNet/wiki/Adding-a-New-Unit). Other than that, we could always use more/better tests and documentation. |
| 130 | +Please read the wiki on [Adding a New Unit](https://github.com/InitialForce/UnitsNet/wiki/Adding-a-New-Unit). |
135 | 131 |
|
136 | 132 | The repo uses [git-flow](https://github.com/nvie/gitflow) branch structure.
|
137 | 133 | In practice this means:
|
138 | 134 | * [Fork the repo](https://help.github.com/articles/fork-a-repo) as normal
|
139 | 135 | * Checkout the default **develop** branch. There is no master branch.
|
140 |
| - * Adding a new unit |
141 |
| - * Branch out from **develop** into **feature/MyNewUnit** |
142 |
| - * Fixing a bug in latest release |
143 |
| - * Branch out from **stable** into **hotfix/FixSomeBug** |
| 136 | + * Do work on branches such as **feature/add-myunit** and **fix-some-bug** |
144 | 137 | * [Create a pull request](https://help.github.com/articles/using-pull-requests) as normal.
|
145 | 138 |
|
146 |
| -Using [git-flow extensions](https://github.com/nvie/gitflow/wiki/Installation) is recommended, but not necessary. |
147 |
| - |
148 | 139 | Continuous Integration
|
149 |
| -====================== |
| 140 | +=== |
150 | 141 | A [TeamCity build server](http://anj.no:8500/project.html?projectId=UnitsNet&tab=projectOverview&guest=1) performs the following:
|
151 |
| - * Build and test pull requests. Notifies on success or error. |
152 |
| - * Build and publish nuget on commits to **stable** branch. |
153 |
| - |
| 142 | +* Build and test pull requests. Notifies on success or error. |
| 143 | +* Build, test and publish nuget on commits to **stable** branch. |
154 | 144 |
|
155 | 145 | [Contact me](https://github.com/anjdreas) if you have any questions.
|
0 commit comments