当前位置: 首页 > 编程语言 > C#

将日期字符串解析为时区(支持夏令时)分享

时间:2023-04-10 15:11:13 C#

一个小问题来了。我认为我现在无法胜任这项任务:)所以我需要一些提示/帮助!这可能很简单,但我的头还没有点击。用户将在AEST中输入日期和时间。还有一个应用程序设置“默认”时区(因为它可能需要更改)当前设置为“澳大利亚东部标准时间”所以我们在美国有一个服务器,其用户字符串没有时区和定义的系统时区(因此本地不匹配,无法更改或使用)现在我需要的是一种方法来表示“使用时区X解析此用户输入的字符串”我不能只将+10或+11作为偏移量因为日期可以是夏令时;即使是同一个时区,也肯定会在+10和+11之间变化!当前AEST时间也可能在DST之内或之外,所以我不能只将UTC日期转换为当前AEST时间并获取“zzz”字符串并附加它,因为输入一个小时后日期将关闭任何当前DST设置。现在代码实际上是这样的:TimeZoneInfoConvTo=TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["DefaultTimeZone"]);DateTimeOffsetgetDate=TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow,ConvTo);字符串TimeZoneId=""+getDate.ToString("zzz");DateTimeOffsetcvStartDate=DateTimeOffset.MinValue;DateTimeOffset.TryParse(StartDate+TimeZoneId,outcvStartDate);然后我通过检查日期是否仍然==DateTimeOffset.MinValue或将其转换为UTC并添加到数据库来检查日期是否无效,显示时它将转换回AEST。但是,有些日期是一小时,有些则很完美(正如预期的那样):)解决这个问题的最优雅方法是什么?编辑:为了帮助解释这个问题,我写了一些测试代码作为Windows测试应用程序://用户输入日期字符串EnteredDate="2011/01/0110:00:00AM";//获取我们要使用的时区TimeZoneInfomyTimeZone=TimeZoneInfo.FindSystemTimeZoneById("AUSEasternStandardTime");//查找所选时区的时区字符串以解析用户字符串//这是不正确的部分,我需要帮助。DateTimeOffsetgetDate=TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow,myTimeZone);字符串TimeZoneId=""+getDate.ToString("zzz");//将字符串解析为日期对象DateTimeOffsetcvEnteredDate=DateTimeOffset.MinValue;DateTimeOffset.TryParse(EnteredDate+TimeZoneId,outcvEnteredDate);//显示textBox1.Text+="Parsed:"+cvEnteredDate.ToString("yyyy/MM/ddHH:mm:sszzz")+Environment.NewLine;//转换为UTC并显示cvEnteredDate=cvEnteredDate.ToUniversalTime();textBox1.Text+="UTC:"+cvEnteredDate.ToString("yyyy/MM/ddHH:mm:sszzz")+Environment.NewLine;//转换回AEST并显示cvEnteredDate=TimeZoneInfo.ConvertTime(cvEnteredDate,myTimeZone);textBox1.Text+="改回:"+cvEnteredDate.ToString("yyyy/MM/ddHH:mm:sszzz")+Environment.NewLine;这个输出是什么?已解析:2011/01/0110:00:00+10:00UTC:2011/01/0100:00:00+00:00改回:2011/01/0111:00:00+11:00请请注意,小时差一,偏移量不同另外,如果我们只是将输入的日期更改为:stringEnteredDate="2011/04/2010:00:00AM";我们得到:Parse:2011/04/2010:00:00+10:00UTC:2011/04/2000:00:00+00:00改回:2011/04/2010:00:00+10:00这个很好很好,用同样的代码只是输入日期不同而已。这是因为当前的DST设置与输入日期的DST设置不同,这是我想要的解决方案:)将其视为先有鸡还是先有蛋的问题。在解析之前我需要输入字符串的正确时区数据,我只在解析字符串之后得到(这将是一个精心设计的解决方案)或者我需要.NET使用myTimeZone对象解析字符串,所以它知道将它设置为本身,但我看不到任何执行此操作的函数,它们都采用已经解析和设置的datetime或datetimeoffset对象,所以我正在寻找其他人可能已经完成的优雅解决方案?当然我不能是唯一注意到这一点的人吗?EDIT2:好的,我已经做了一个“工作”函数来解决我认为的问题,这是一个例子(在c#windows应用程序中添加一个文本框并使用下面的代码来测试你自己):privatevoidForm1_Load(objectsender,EventArgse){TimeZoneInfomyTimeZone=TimeZoneInfo.FindSystemTimeZoneById("澳大利亚东部标准时间");DateTimeOffsetget1Date=ReadStringWithTimeZone("2011/01/0110:00:00AM",myTimeBox1);text+="Read1:"+get1Date.ToString("yyyy/MM/ddHH:mm:sszzz")+Environment.NewLine;get1Date=get1Date.ToUniversalTime();textBox1.Text+="Read1-UTC:"+get1Date.ToString("yyyy/MM/ddHH:mm:sszzz")+Environment.NewLine;get1Date=TimeZoneInfo.ConvertTime(get1Date,myTimeZone);textBox1.Text+="改回:"+get1Date.ToString("yyyy/MM/ddHH:mm:sszzz")+Environment.NewLine+Environment.NewLine;日期时间偏移etget2Date=ReadStringWithTimeZone("2011/04/2010:00:00AM",myTimeZone);textBox1.Text+="Read2:"+get2Date.ToString("yyyy/MM/ddHH:mm:sszzz")+Environment.NewLine;get2Date=get2Date.ToUniversalTime();textBox1.Text+="Read2-UTC:"+get2Date.ToString("yyyy/MM/ddHH:mm:sszzz")+Environment.NewLine;get2Date=TimeZoneInfo.ConvertTime(get2Date,myTimeZone);textBox1.Text+="改回:"+get2Date.ToString("yyyy/MM/ddHH:mm:sszzz")+Environment.NewLine+Environment.NewLine;}publicDateTimeOffsetReadStringWithTimeZone(stringEnteredDate,TimeZoneInfotzi){DateTimeOffsetcvUTCToTZI=TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow,tzi);DateTimeOffsetcvParsedDate=DateTimeOffset.MinValue;DateTimeOffset.TryParse(EnteredDate+""+cvUTCToTZI.ToString("zzz"),outcvParsedDate);如果(tzi.SupportsDaylightSavingTime){TimeSpangetDiff=tzi.GetUtcOffset(cvParsedDate);字符串MakeFinalOffset=(getDiff.Hours9?"":"0")+getDiff.Hours+":"+(getDiff.Minutes>9?"":"0")+getDiff.Minutes;textBox1.Text+="差异:"+MakeFinalOffset+Environment.NewLine;DateTimeOffset.TryParse(EnteredDate+""+MakeFinalOffset,outcvParsedDate);返回cvParsedDate;}else{返回cvParsedDate;}}和输出:差异:+11:00读取时间:2011年1月1日10:00:00+11:00读取1-UTC:2010/12/3123:00:00+00:00改回:2011/01/0110:00:00+11:00差异:+10:00读取:2011/04/2010:00:00+10:00读取2-UTC:2011/04/2000:00:00+00:00改回:2011/04/2010:00:00+10:00唯一的问题是如果用户输入的日期正好是读取当前偏移量并使用它,然后检查它是否应该是夏令时,如果它在那里它读错了但是,它比我现在英里更好。谁能帮我清理一下?这是满足我需求的最佳途径吗?主意?这是一个具有预定义格式的简单解决方案,它也可以是动态的。我个人用它来与javascript对话:vartzOffset=timezone.GetUtcOffset(parsedDateLocal.DateTime);varparsedDateTimeZone=newDateTimeOffset(parsedDateLocal.DateTime,tzOffset);返回parsedDateTimeZone;当我需要将日期时间字符串从已知时区解析为本地时区时,这似乎对我有用。在许多情况下尚未对其进行测试,但到目前为止,它非常适合在欧盟某处的服务器上解析时间。TimeZoneInfo.ConvertTime(DateTime.Parse("2012-05-2523:17:15",CultureInfo.CreateSpecificCulture("en-EU")),TimeZoneInfo.FindSystemTimeZoneById("W.CET"),TimeZoneInfo.Local)由于没有人提供更好的解决方案(这很令人惊讶!)我接受我自己的功能作为答案,虽然我可能会使功能更简洁,稍后重新工作:publicDateTimeOffsetReadStringWithTimeZone(stringEnteredDate,TimeZoneInfotzi){DateTimeOffsetcvUTCToTZI=TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow,tzi);DateTimeOffsetcvParsedDate=DateTimeOffset.MinValue;DateTimeOffset.TryParse(EnteredDate+""+cvUTCToTZI.ToString("zzz"),outcvParsedDate);如果(tzi.SupportsDaylightSavingTime){TimeSpangetDiff=tzi.GetUtcOffset(cvParsedDate);stringMakeFinalOffset=(getDiff.Hours9?"":"0")+getDiff.Hours+":"+(getDiff.Minutes>9?"":"0")+getDiff.Minutes;DateTimeOffset.TryParse(EnteredDate+""+MakeFinalOffset,outcvParsedDate);returncvParsedDate;}else{returncvParsedDate;}}TimeZoneInfo有一个静态方法ConvertTimeToUtc,它允许你指定一个日期时间和时区。这将为您进行时间调整,并返回UTC日期。MSDN文档是http://msdn.microsoft.com/en-us/library/bb495915.aspx,完整示例。最简单的解决方案:先将字符串解析成本地的DateTime,然后使用任意解析方式调用即可,需要详细了解C#学习教程。希望大家多多关注——newDateTimeOffset(dateTimeLocal.Ticks,timezone.BaseUtcOffset)本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: