在C#中,如何始终将DateTime值视为DateTime所代表的时间的欧洲/伦敦本地值,并将其转换为UTC?

在C#中,如何始终将DateTime值视为DateTime所代表的时间的欧洲/伦敦本地值,并将其转换为UTC?,c#,datetime,timezone-offset,C#,Datetime,Timezone Offset,我正在使用SQL Server数据库中不维护的日期时间值,我希望在我的代码中以UTC的形式使用它们 为了帮助理解这个问题,我使用的值表示在我们的CRM系统中发生操作的时间 当我从SQL Server检索值时,它们没有时区指示,但我知道它们始终代表欧洲/伦敦-冬季为UTC,夏季为UTC+1 我知道我可以使用DateTimeKind.Local来表示DateTime值是以本地时间表示的,但我不明白如何指定DateTime应用于哪个时区。例如,如果我使用的是日期时间2021-01-01 12:34:5

我正在使用SQL Server数据库中不维护的日期时间值,我希望在我的代码中以UTC的形式使用它们

为了帮助理解这个问题,我使用的值表示在我们的CRM系统中发生操作的时间

当我从SQL Server检索值时,它们没有时区指示,但我知道它们始终代表欧洲/伦敦-冬季为UTC,夏季为UTC+1

我知道我可以使用DateTimeKind.Local来表示DateTime值是以本地时间表示的,但我不明白如何指定DateTime应用于哪个时区。例如,如果我使用的是日期时间
2021-01-01 12:34:56
,我需要确保无论代码在何处或何时运行,此日期都正确解释为
2021-01-01 12:34:56+00:00
。同样,我需要确保无论代码在何处或何时运行,我都需要将
2021-05-01 12:34:56
解释为
2021-01-01 12:34:56+01:00

我如何表明我的日期时间值在其表示的时间始终适用于欧洲/伦敦?

Check是一个功能强大的C#日期时间库。 主页上的例子似乎与您的案例有关

/ Instant represents time from epoch
Instant now = SystemClock.Instance.GetCurrentInstant();

// Convert an instant to a ZonedDateTime
ZonedDateTime nowInIsoUtc = now.InUtc();

// Create a duration
Duration duration = Duration.FromMinutes(3);

// Add it to our ZonedDateTime
ZonedDateTime thenInIsoUtc = nowInIsoUtc + duration;

// Time zone support (multiple providers)
var london = DateTimeZoneProviders.Tzdb["Europe/London"];

// Time zone conversions
var localDate = new LocalDateTime(2012, 3, 27, 0, 45, 00);
var before = london.AtStrictly(localDate);

有一个问题是,没有显式时区指示器的本地datetime值是不明确的值。即,相同的本地时间在一个DST过渡日出现两次。没有办法找到他们中的哪一个,你不能。在.NET中,
DateTime
单独是执行程序的区域设置的
UTC
未定义的
本地
。SQL Server的
datetime
甚至都没有,这就是为什么它总是作为
Undefined
加载的原因。您必须使用
datetimeoffset
来保留时区偏移。如果你想要时区本身,你必须明确地存储它为什么不在代码中使用
DateTimeOffset
,在数据库中使用
DateTimeOffset
?如果时区总是相同的,那么您所要求的实际上就是您现在拥有的:所有
DateTime
值都假定为本地值。如果您
需要确保无论我的代码在何处或何时运行,您都需要存储偏移量或时区information@Damien_The_Unbeliever这是一个有趣的边缘案件,我没有想到,谢谢你。如果我使用“至少”,Ygabel建议的解决方案会很好地工作。@PanagiotisKanavos不幸的是,我无法更改数据库模式。我自己的代码使用的是DateTimeOffset,这就是问题的症结所在。使用下面建议的NodaTime,我已经能够将SQL datetime值转换为具有适当偏移量的datetimeoffset:)