从我下面最后一个问题这@乔恩飞碟双向给了我很多的帮助与(再次感谢!)
我现在想知道当它们被转换回本地日期/时间时,如何安全地处理以UTC格式存储的日期/时间.
正如乔恩在我的上一个问题中DateTimeOffset表示,使用时间代表了一个瞬间,并且没有办法预测一分钟之后当地时间会说什么.我需要能够根据这些日期/时间进行计算.
那么我如何确保何时从数据库中提取日期,将它们转换为本地日期/时间并对它们进行具体计算它们是否准确?
脚本
我的申请记录通过电子邮件发送的信息.收到电子邮件的日期/时间记录为提交时间.电子邮件是从交换中提取的.
我需要知道的是:
1)如果这些电子邮件来自不同的国家/地区,我是否只是将Recieved电子邮件的日期/时间转换为UTC格式并存储?例如Email.Received.ToUniversalTime()
以下语句打印"1/1/0001 4:00:00 PM -05:00"
Console.WriteLine(JsonConvert.DeserializeObject<DateTimeOffset>("\"0001-01-01T16:00:00\""));
Run Code Online (Sandbox Code Playgroud)
这是因为当json.net将DateTime字符串(没有偏移量)反序列化为DateTimeOffset对象时,它会分配本地偏移量,在本例中为-05:00.
如果我不想使用本地偏移怎么办?有什么方法可以指定用于此反序列化的偏移量吗?
(用例是数据库服务器,Web服务器位于不同的时区,我需要具有区域未指定时间的传入请求,以便在反序列化后使数据库服务器具有偏移量.)
更新:我无法控制传入时间字符串的格式.我有一个数据传输对象类,它具有DateTimeOffset属性,我需要将传入的时间数据存储到此属性.
我想运行一个简单的 T-SQL SELECT 查询,以便此输入 (datetimeoffset)...
2015-01-01 00:15:00.0000000 +01:00
或者
2015-05-04 14:15:00.0000000 +02:00
...输出如下(日期时间):
2015-01-01 01:15:00
或者
2015-05-04 16:15:00
输入是一列,输出也应该是一列。
有任何想法吗?
更新20170126
好吧,一如既往,它从来没有我想象的那么容易。该查询是一个更大查询的一部分,我现在将其制定如下(见下文),输入列名为“TimeStamp”,输出列名为“Tijd”。但这不起作用,因为它似乎无法识别变量声明中的 [TimeStamp] 。我缺少什么?
DECLARE @dt datetimeoffset = (SELECT CONVERT(datetimeoffset, [TimeStamp]))
SELECT @dt as Original
,CONVERT(datetime2,@dt,1) AS Tijd
,[Id]
,[EanCode]
,[DataAccessPointId]
,[DataSource]
,[ElectricityUsageNormalkWh] AS Piek
,[ElectricityUsageLowkWh] AS Dal
,[DateAltKey] = CONVERT(int, CONVERT(varchar(8), [TimeStamp], 112))
,[TimeAltKey] = DATEPART(hh,[TimeStamp]) * 10000 + DATEPART(mi,[TimeStamp]) * 100 + DATEPART(ss,[TimeStamp])
FROM [dbo].[ElectricityTelemetryData]
Run Code Online (Sandbox Code Playgroud) 我有一个字符串“2020-03-25T22:00:00.000Z”,我想将其转换为 OffsetDateTime。下面是我尝试过的代码,但是当我将毫秒作为 000 传递时,它不会反映在 OffsetDateTime 中。
OffsetDateTime offsetDateTime=OffsetDateTime.parse("2020-03-25T22:00:01.123Z",
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
print(offsetDateTime)
//Output: 2020-03-25T22:00:01.123Z
Run Code Online (Sandbox Code Playgroud)
但是当mili为000时
OffsetDateTime offsetDateTime=OffsetDateTime.parse("2020-03-25T22:00:01.000Z",
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
print(offsetDateTime)
//Output: 2020-03-25T22:01Z (mili second is missing)
Run Code Online (Sandbox Code Playgroud)
我也尝试了自定义格式化程序,但它的行为相同
OffsetDateTime.parse("2020-03-25T22:00:00.123Z",
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX"));
Run Code Online (Sandbox Code Playgroud)
谁能帮我一下吗
天然气日定义为欧洲标准时间 24 小时的时间范围,从 UTC 5:00 开始,到次日 UTC 5:00 结束。在欧洲夏令时期间,它从 4:00 UTC 开始,到次日 4:00 UTC 结束(请参阅维基百科或ACER了解英文解释)。
我需要在应用程序中使用天然气日才能执行以下操作:
在我看来,“加油日”应该像时区一样可用,然后我可以在我的应用程序中使用它,但尝试使用DateTime或DateTimeOffset让我完全不知道我应该做什么这项工作。
谁能指出我必须做什么才能进行上面解释的计算的正确方向?是否有一个库可以让这件事变得更容易一些?例如,我已经研究过NodaTime,但我在其文档中找不到任何可以让我更轻松地解决此任务的内容。
当我尝试实例化DbContext时,我收到此消息:
System.NotSupportedException:没有与原始类型"DateTimeOffset"的概念边类型"DateTimeOffset"对应的商店类型.
我在SQL Server上使用Entity Framework版本6.
DbContext(带有抛出异常的行)的构造函数如下所示:
internal TestHubContext(string connectionStringName) : base(connectionStringName)
{
var objectContext = (this as IObjectContextAdapter).ObjectContext;
...
}
Run Code Online (Sandbox Code Playgroud)
使用代码优先创建实体,如下所示:
public class Order
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public System.Guid Id { get; set; }
[MaxLength(60)]
[Required]
public string CreatedBy { get; set; }
[Required]
public System.DateTimeOffset CreatedUtcDate { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
数据库迁移运行正常并生成如下表:
CREATE TABLE [dbo].[Orders](
[Id] [uniqueidentifier] NOT NULL,
[CreatedBy] [nvarchar](60) NOT NULL,
[CreatedUtcDate] [datetimeoffset](7) NOT NULL,
Run Code Online (Sandbox Code Playgroud)
因此数据库和C#代码中存在相关的数据类型.关于为什么会这样,我有点失落.
这是我得到的堆栈跟踪:
System.Data.Entity.ModelConfiguration.Edm.Services上的System.Data.Entity.SqlServer.SqlProviderManifest.GetStoreType(TypeUsage edmType)中的System.Data.Entity.SqlServer.SqlProviderManifest.GetStorePrimitiveTypeIfPostSql9(String storeTypeName,String nameForException,PrimitiveTypeKind primitiveTypeKind) System.SData.Entity.ModelConfiguration上的System.Data.Entity.ModelConfiguration.Edm.Services.PropertyMappingGenerator.Generate(EntityType entityType,IEnumerable
1 …
我需要从多种格式的字符串中解析datetimeoffsets.其中一个失败的字符串是:08/12/1992 07.00.00 -05:00
现在当我尝试解析这个时,我使用:
DateTimeOffset.ParseExact("08/12/1992 07.00.00 -05:00", "dd/MM/yyyy HH:mm:ss zzz", CultureInfo.InvariantCulture)
Run Code Online (Sandbox Code Playgroud)
这给了一个FormatException:
"字符串未被识别为有效的DateTime."
我也可以尝试在分隔符中添加分隔符:
DateTimeOffset.ParseExact("08/12/1992 07.00.00 -05:00", "dd'/'MM'/'yyyy HH':'mm':'ss zzz", CultureInfo.InvariantCulture)
Run Code Online (Sandbox Code Playgroud)
...或其他小/大写字母或分隔符的排列,但我得到同样的错误.
任何人都可以告诉我为什么上面的ParseExact行不起作用,以及如何纠正它们?
编辑:我尝试使用LINQ查询用点(: - >.)替换冒号.显然这不能正常工作 - 感谢回复.
当类型为Utc时,将UTC中的DateTime转换为DateTimeOffset时出错。origDateTime来自Web服务,因此我无法控制内容或格式。在大多数情况下,它带有Kind = Unspecified(即使在Utc中,即使时间很艰难)也可以正常工作,但是在极少数情况下,Kind = Utc然后转换为DateTimeOffset会引发异常:“ Utc DateTime实例的UTC偏移量必须为0。\ r \ n参数名称:offset“我应如何解决?
try {
//cause error !!!!
DateTime databaseUtcTime = DateTime.Parse("4/2/2016 6:25:20 PM");
var localTimeTemp = databaseUtcTime.ToLocalTime();
DateTime origDateTime = localTimeTemp.ToUniversalTime();
//this is working
//DateTime origDateTime = DateTime.Parse("4/2/2016 6:25:20 PM");
string timeZoneName = "Pacific Standard Time";
TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
DateTimeOffset localTime = new DateTimeOffset(origDateTime, localTimeZone.GetUtcOffset(origDateTime));
return localTime;
}
catch (Exception ex) {
string msg = ex.Message;
return null;
}
Run Code Online (Sandbox Code Playgroud) 我转换了一个字符串,表示我用来创建DateTime对象的太平洋时区的时间:
var pacificDateTime = new DateTime(2016, 11, 16, 15, 0, 0) // 11/16/2016 3:00:00 PM
Run Code Online (Sandbox Code Playgroud)
使用它,我创建了一个DateTimeOffset因为最终它变得更容易使用.
var pacificTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var dateTimeNoKind = new DateTime(pacificDateTime.Ticks, DateTimeKind.Unspecified)
var DateTimeOffsetValue = TimeZoneInfo.ConverTimeToUtc(dateTimeNoKind, pacificTimeZoneInfo) // 11/16/2016 11:00:00 PM
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.UTC与Pacific之间的区别在于UTC提前8小时(给定时间在夏令时内).
然后我想从UTC转换为AEST - 但这是出现问题的地方:
var australianEasternTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
TimeZoneInfo.ConvertTime(DateTimeOffsetValue, australianEasternTimeZoneInfo) // 11/17/2016 10:00:00 AM
Run Code Online (Sandbox Code Playgroud)
AEST比UTC早10个小时.我曾预料到价值,11/17/2016 09:00:00 AM但我的结果却增加了一小时.
作为测试,当我从UTC时间转换为PST或GMT或EST时,它们似乎正确地转换回来.
我觉得我错过了一些明显的东西或忽略了一些简单的东西?
我目前在UTC + 1区域。TimeZoneInfo.Local.BaseUtcOffset返回+1。
并new DateTimeOffset(DateTime.Today).AddDays(4).Offset返回+1。
但是new DateTimeOffset(DateTime.Today.AddDays(4)).Offset返回+2!
甚至更有趣的是,直到加上四天的偏移量都是一样的。从四天开始,通话new DateTimeOffset(DateTime.Today.AddDays(x)).Offset返回+2偏移。为什么?
//Same offset +1
var offset2 = new DateTimeOffset(DateTime.Today).AddDays(7).Offset;
var offset22 = new DateTimeOffset(DateTime.Today.AddDays(7)).Offset;
//Same offset +1
var offset3 = new DateTimeOffset(DateTime.Today).AddDays(3).Offset;
var offset32 = new DateTimeOffset(DateTime.Today.AddDays(3)).Offset;
//Different offset +1 and +2
var offset4 = new DateTimeOffset(DateTime.Today).AddDays(4).Offset;
var offset42 = new DateTimeOffset(DateTime.Today.AddDays(4)).Offset;
//Different offset +1 and +2
var offset5 = new DateTimeOffset(DateTime.Today).AddDays(5).Offset;
var offset52 = new DateTimeOffset(DateTime.Today.AddDays(5)).Offset;
Run Code Online (Sandbox Code Playgroud)