Jan*_*nik 1 c# datetime nodatime
我试图了解我们所遇到的这个时区问题.我们希望以UTC格式存储所有日期时间,然后将日期时间转换为用户时区.
我们决定使用Nodatime,因为它似乎是正确的方法.但是我们遇到了一些问题
这就是我们将datetime转换为UTC的方法(注意:我现在硬编码了usersTimeZone)
public static DateTime ConvertLocaltoUTC(this DateTime dateTime)
{
LocalDateTime localDateTime = LocalDateTime.FromDateTime(dateTime);
IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;
var usersTimezoneId = "Europe/Copenhagen";
var usersTimezone = timeZoneProvider[usersTimezoneId];
var zonedDbDateTime = usersTimezone.AtLeniently(localDateTime);
var returnThis = zonedDbDateTime.ToDateTimeUtc();
return zonedDbDateTime.ToDateTimeUtc();
}
Run Code Online (Sandbox Code Playgroud)
以下是我们如何将其转换回来的方式
public static DateTime ConvertUTCtoLocal(this DateTime dateTime)
{
Instant instant = Instant.FromDateTimeUtc(dateTime);
IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;
var usersTimezoneId = "Europe/Copenhagen"; //just an example
var usersTimezone = timeZoneProvider[usersTimezoneId];
var usersZonedDateTime = instant.InZone(usersTimezone);
return usersZonedDateTime.ToDateTimeUnspecified();
}
Run Code Online (Sandbox Code Playgroud)
但是当我们将它转换回本地时,它会引发异常:
参数异常:Instant.FromDateTimeUtc的DateTime.Kind无效
在"ConvertUTCtoLocal()"的第一行,日期时间的一个例子可能是:"9/18/2017 5:28:46 PM" - 是的,这是通过ConvertLocalToUTC方法.
我提供了错误的格式,或者我在这里做错了什么?
您展示的例外情况:
参数异常:Instant.FromDateTimeUtc的DateTime.Kind无效
从这段代码抛出:
Run Code Online (Sandbox Code Playgroud)Instant instant = Instant.FromDateTimeUtc(dateTime);
这意味着dateTime.Kind需要DateTimeKind.Utc转换为a Instant,无论出于何种原因,它都不是.
如果你查看你的ConvertLocaltoUTC方法的结果,你会发现它确实有.Kind == DateTimeKind.Utc.
所以,问题出在你的代码的其他地方,无论你在哪里创建了dateTime你传入的代码ConvertUTCtoLocal.
您可能会发现解决方案可能是以下任何一种:
您可能需要调用DateTime.SpecifyKind将类型设置为UTC,但请注意,只有在您的值实际为UTC且仅设置类型时才执行此操作.例如,在DateTime从数据库加载基于UTC时使用此选项.
您可能需要致电.ToUniversalTime(),但如果机器的当地时区与您的情况相关,请务必小心.例如,在UI控件选择日期的桌面或移动应用程序中执行此操作,但您的意思是它表示UTC而不是本地时间.
您可能需要更改将字符串解析为DateTime值的方式,例如通过传递DateTimeStyles.RoundTripKind给DateTime.Parse调用(或其任何变体).例如,如果要从text,csv等中读取数据,请执行此操作.
如果您想避免必须决定,请不要编写DateTime作为输入或DateTime作为输出的函数.相反,使用DateTimeOffset,或者使用野田时间类型,如Instant,LocalDateTime等趁早.
这对我有用:
Instant instant = Instant.FromDateTimeUtc(DateTime.SpecifyKind(datetime, DateTimeKind.Utc));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1223 次 |
| 最近记录: |