单位转换实践:深入解析 Units.NET

摘要

在现代软件开发中,准确处理不同单位的转换是一个常见而复杂的需求。无论是处理温度、长度、重量还是其他物理量,都需要可靠的单位转换机制。本文将深入介绍 Units.NET 库,展示如何在 .NET 应用中优雅地处理单位转换。

基础配置

首先,通过 NuGet 安装 Units.NET:

<PackageReference Include="UnitsNet" Version="5.x.x" />

实战示例:天气 API

基础模型定义

public record WeatherForecast(
Temperature Temperature,
DateTime Date,
string Summary
); public record WeatherResponse(
string DisplayValue,
DateTime Date,
string Summary
);

API 端点实现

var summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
}; app.MapGet("/weather", (string? unit) =>
{
var forecasts = Enumerable.Range(1, 5).Select(index =>
{
// 创建基础温度(摄氏度)
var tempC = Temperature.FromDegreesCelsius(Random.Shared.Next(-20, 55));
// 根据请求的单位进行转换
var temp = unit?.ToLowerInvariant() switch
{
"f" or "fahrenheit" => tempC.ToUnit(TemperatureUnit.DegreeFahrenheit),
"k" or "kelvin" => tempC.ToUnit(TemperatureUnit.Kelvin),
_ => tempC
}; return new WeatherForecast(
Temperature: temp,
Date: DateTime.Now.AddDays(index),
Summary: summaries[Random.Shared.Next(summaries.Length)]
);
})
.ToArray(); return forecasts.Select(f => new WeatherResponse(
Date: f.Date,
Summary: f.Summary,
DisplayValue: f.Temperature.ToString("F2") //控制输出的数字为两位小数
));
})
.WithName("GetWeatherForecast");

当请求的units单位不同时,将输出相同温度的不同单位表示:





单位相互转换

public static class UnitConverter
{
public static Temperature ConvertTemperature(
double value,
string fromUnit,
string toUnit)
{
var temperature = fromUnit.ToLowerInvariant() switch
{
"c" => Temperature.FromDegreesCelsius(value),
"f" => Temperature.FromDegreesFahrenheit(value),
"k" => Temperature.FromKelvins(value),
_ => throw new ArgumentException($"Unsupported unit: {fromUnit}")
}; return toUnit.ToLowerInvariant() switch
{
"c" => temperature.ToUnit(TemperatureUnit.DegreeCelsius),
"f" => temperature.ToUnit(TemperatureUnit.DegreeFahrenheit),
"k" => temperature.ToUnit(TemperatureUnit.Kelvin),
_ => throw new ArgumentException($"Unsupported unit: {toUnit}")
};
}
}

数学运算支持

Units.NET 支持各种数学运算,使得单位计算变得简单:

public class UnitCalculations
{
public static Speed CalculateSpeed(Length distance, Duration time)
{
return distance / time;
} public static Acceleration CalculateAcceleration(Speed initialSpeed, Speed finalSpeed, Duration time)
{
return (finalSpeed - initialSpeed) / time;
} public static Energy CalculateKineticEnergy(Mass mass, Speed velocity)
{
double massValue = mass.Kilograms;
double velocityValue = velocity.MetersPerSecond;
double energyValue = 0.5 * massValue * velocityValue * velocityValue;
return Energy.FromJoules(energyValue);
}
} // 使用示例
var distance = Length.FromKilometers(100);
var time = Duration.FromHours(2);
var speed = UnitCalculations.CalculateSpeed(distance, time);
Console.WriteLine($"Speed: {speed.ToUnit(SpeedUnit.KilometerPerHour)}");

代码执行后,控制台将输出:Speed: 50 km/h

文化本地化支持

var usEnglish = new CultureInfo("en-US");
var russian = new CultureInfo("ru-RU");
var oneKg = Mass.FromKilograms(1);
// ToString() 使用 CurrentCulture 进行缩写语言和数字格式化。这与 .NET Framework 的行为一致,
// 因为 DateTime.ToString() 使用 CurrentCulture 处理整个字符串,可能是因为将英文日期格式与俄文月份名称混合在一起可能会令人困惑。
CultureInfo.CurrentCulture = russian;
string kgRu = oneKg.ToString(); // "1 кг" // 使用特定文化和自定义字符串格式模式的 ToString()
string mgUs = oneKg.ToUnit(MassUnit.Milligram).ToString(usEnglish); // "unit: mg, value: 1.00"
string mgRu = oneKg.ToUnit(MassUnit.Milligram).ToString(russian); // "unit: мг, value: 1,00" Console.WriteLine(mgUs);
Console.WriteLine(mgRu);
// 从字符串解析测量值
Mass kg = Mass.Parse("1.0 kg", usEnglish); // 从字符串解析单位,一个单位可以有多个缩写
RotationalSpeedUnit rpm1 = RotationalSpeed.ParseUnit("rpm"); // RotationalSpeedUnit.RevolutionPerMinute
RotationalSpeedUnit rpm2 = RotationalSpeed.ParseUnit("r/min"); // RotationalSpeedUnit.RevolutionPerMinute // 获取单位的默认缩写,如果在 Length.json 中为 Kilogram 单位定义了多个缩写,则获取第一个
string kgAbbreviation = Mass.GetAbbreviation(MassUnit.Kilogram); // "kg"

控制台将输出不同文化设置下的标准单位

1000000 mg
1000000 мг

结论

Units.NET 是一个强大而灵活的单位转换库,它不仅简化了单位转换的实现,还提供了丰富的功能支持。通过使用 Units.NET,开发者可以专注于业务逻辑,而不必担心单位转换的复杂性。无论是构建天气 API、物流系统还是科学计算应用,Units.NET 都是处理单位转换的理想选择。

[.NET] 单位转换实践:深入解析 Units.NET的更多相关文章

  1. WebSocket原理与实践(三)--解析数据帧

    WebSocket原理与实践(三)--解析数据帧 1-1 理解数据帧的含义:   在WebSocket协议中,数据是通过帧序列来传输的.为了数据安全原因,客户端必须掩码(mask)它发送到服务器的所有 ...

  2. Revit API单位转换类

    用法:txt.Text=UnitConvertC.CovertFromAPI(param.AsDouble());param.Set(UnitConvertC.CovertToAPI(txt.Text ...

  3. spring-boot前端参数单位转换

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import ja ...

  4. Android 尺寸单位转换和屏幕适配相关

    Android 尺寸单位转换和屏幕适配相关 各种尺寸单位的意义 dp: Density-independent Pixels 一个抽象的单元,基于屏幕的物理密度. (dp和dip的意义相同,所以不用区 ...

  5. System.currentTimeMillis()计算方式与时间的单位转换

    目录[-] 一.时间的单位转换 二.System.currentTimeMillis()计算方式 一.时间的单位转换 1秒=1000毫秒(ms) 1毫秒=1/1,000秒(s)1秒=1,000,000 ...

  6. 武汉科技大学ACM:1005: 单位转换

    Problem Description BobLee最近在复习考研,在复习计算 机组成原理的时候,遇到了一个问题.就是在计算机存储里面的单位转换.我们都知道1MB=1024KB,1KB=1024B,1 ...

  7. 【转】Android中dip(dp)与px之间单位转换

    Android中dip(dp)与px之间单位转换 dp这个单位可能对web开发的人比较陌生,因为一般都是使用px(像素)但是,现在在开始android应用和游戏后,基本上都转换成用dp作用为单位了,因 ...

  8. Android屏幕尺寸单位转换

    最近在看Android群英传这本书,书中有一节涉及到了,屏幕尺寸与单位.觉得以后可能会用到,做个笔记. PPI(pixels per inch) ,又称为DPI,它是由对角线的像素点数除以屏幕的大小得 ...

  9. while循环/格式化输出/ 逻辑运算/ 编码 /单位转换

    一.while 循环 1. 循环 while 条件: 代码块(循环体) else: 当上面的条件为假. 才会执行 执行顺序: 判断条件是否为真. 如果真. 执行循环体. 然后再次判断条件....直到循 ...

  10. 单位转换类UnitUtil2

    package com.jlb.scan.util; import java.math.BigDecimal; import java.text.DecimalFormat; import com.j ...

随机推荐

  1. PHP实现断点续传

    解释 业务上要求对资源文件进行加密,遂实现通过php接口调用,修改header头,传输流的方式. 测试中,在苹果手机上,如果文件过大(大概10M以上),会主动调用多次接口.此时如果不使用断点续传的方式 ...

  2. NDT论文翻译

    The Normal Distributions Transform: A New Approach to Laser Scan Matching 正态分布变换:激光扫描匹配的新方法 摘要:匹配 2D ...

  3. Docker容器与守护进程运维 --项目四

    一.Docker容器配置进阶 1.容器的自动重启 Docker提供重启策略控制容器退出时或Docker重启时是否自动启动该容器. 容器默认不支持自动重启,要使用 --restart 选项指定重启策略. ...

  4. QT creator中cmake管理项目,如何引入外部库(引入Eigen库为例)

    在Eigen的官网下载压缩包[点我进入] 解压到当前项目的根目录(当然你也可以自己选择目录) 在当前项目的CMakeLists.txt任意位置加入这句话include_directories(${CM ...

  5. LLM应用实战: 给个公司简称,输出公司全称

    1.背景 本qiang~本周在处理手头项目工作的时候,遇到了一个问题,就是友方提供了一个公司名称列表(量不小~,因此无法人工处理),且该公司名称列表均为简称,需要与库中的全称做一个映射匹配. 看似简单 ...

  6. 厉害了,8.7w人打满分!如果我找 BUG 能像他一样厉害就好了!

    你好呀,我是歪歪. 最近在 B 站上看到一个让我觉得"非常哇塞"视频的: https://www.bilibili.com/video/BV1y4421U72G/ 视频的播放量有接 ...

  7. CommonsCollections4(基于ysoserial)

    环境准备 JDK1.8(8u421)这里ysoserial没有提及JDK版本的影响,我以本地的JDK8版本为准.commons-collections4(4.0 以ysoserial给的版本为准).j ...

  8. 功能齐全的 WPF 自定义控件资源库(收藏版)

    前言 推荐一款界面美观.功能齐全的 WPF 自定义控件资源库.这款资源库通过封装一系列常用的控件,简化开发流程,加快项目交付速度. 控件介绍 资源库封装了一些常用的控件,将其整合到一个自定义的控件库中 ...

  9. 腾讯AICR : 智能化代码评审技术探索与应用实践(下)

  10. Java里快如闪电的线程间通讯

    这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...