Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将时间戳从CET/CEST转换为UTC_C#_Datetime_Timezone - Fatal编程技术网

C# 将时间戳从CET/CEST转换为UTC

C# 将时间戳从CET/CEST转换为UTC,c#,datetime,timezone,C#,Datetime,Timezone,我目前正在编写一个工具,用于解析具有自定义非标准文件格式的文件。 这些文件包含几个带有时间戳的测量点的数据(每30秒测量一次)。这些时间戳位于CET/CEST时区,这意味着当时间从夏季变为冬季时,文件中将有多个具有相同时间戳的测量值,因为早上2:00到3:00之间的每个时间戳在文件中都存在两次(一次来自时间更改之前,一次来自时间更改之后) 我已经能够解析文件中我需要的所有时间戳数据(年、月、日、小时和分钟),但我还需要将其转换为UTC。 在.NET Framework或第三方库中是否有进行此转换

我目前正在编写一个工具,用于解析具有自定义非标准文件格式的文件。 这些文件包含几个带有时间戳的测量点的数据(每30秒测量一次)。这些时间戳位于CET/CEST时区,这意味着当时间从夏季变为冬季时,文件中将有多个具有相同时间戳的测量值,因为早上2:00到3:00之间的每个时间戳在文件中都存在两次(一次来自时间更改之前,一次来自时间更改之后)

我已经能够解析文件中我需要的所有时间戳数据(年、月、日、小时和分钟),但我还需要将其转换为UTC。 在.NET Framework或第三方库中是否有进行此转换的功能

我已经尝试过使用
TimeZoneInfo.ConvertTimeToUtc
,但是我已经需要一个DateTime对象,我还不知道如何创建它。 我不能简单地使用一个DateTime构造函数创建一个新的DateTime对象,因为假设我提供了一个时间戳,它在一个文件中存在两次,因为从夏季到冬季的时间发生了变化——它如何知道时间戳是在时间变化之前还是之后

我认为在处理时间戳时,这可能是一个比较常见的问题,但我还没有找到解决问题的好方法。我是否需要手动跟踪文件中的时间更改,以便将时间正确转换为UTC?如果是,我该怎么做

更新: 下面是我试图解决的问题的一个非常简单的例子: 这可能是我的工具从文件中的时间戳解析的一些数据:

Day: 27 - Month: 10 - Year: 2019 - Hour: 1 - Minute: 45 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 2 - Minute: 0 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 2 - Minute: 15 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 2 - Minute: 30 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 2 - Minute: 45 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 2 - Minute: 0 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 2 - Minute: 15 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 2 - Minute: 30 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 2 - Minute: 45 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 3 - Minute: 0 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 3 - Minute: 15 - Second: 0 
Day: 27 - Month: 10 - Year: 2019 - Hour: 3 - Minute: 30 - Second: 0
(实际上,每小时的数据要多得多,但这对于示例来说并不重要)

在本例中,时钟从凌晨3:00设置为凌晨2:00,因为夏令时在此结束,因此我们从CEST更改为CET。 相反的事情发生在6个月后(显然也是6个月前),夏令时开始,时钟向前移动一小时

在我的工具解析的文件中没有任何关于时间戳是在CET还是CEST中的指示,因此我的解析逻辑需要处理这个问题。 我基本上有一个循环,循环遍历文件中的行,解析时间戳,然后调用此函数为每个时间戳获取DateTime对象:

private static DateTime toDateTimeUTC(int year, int month, int day, int hour, int minute, int second)
{
    // ToDo

    return new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc); // This is WRONG!
}

到目前为止,这段代码显然无法正常工作,因为它只是假设时间戳是UTC。

如果您的所有内容都在DateTimeOffset中,并且基于summer/winter使用+1/+2,那么如果您希望使用Offset+0保存ToUniversalTime,则只需保存ToUniversalTime

var input = new DateTimeOffset(2000,1,1,23,59,00, TimeSpan.FromHours(1));
var utc = cet.ToUniversalTime();

如果您在DateTimeOffset中拥有基于夏季/冬季的+1/+2的所有内容,那么如果您希望使用Offset+0保存ToUniversalTime,则只需保存ToUniversalTime即可

var input = new DateTimeOffset(2000,1,1,23,59,00, TimeSpan.FromHours(1));
var utc = cet.ToUniversalTime();

如果您知道每个文件始终有一天的时间,并且由于每30秒记录一次数据,因此始终可以检测到更改,那么您可以发现本地时间戳何时倒转,并确定以这种方式使用哪个不明确的偏移量。大概是这样的:

TimeZoneInfo zone=…;//我想你已经知道了
bool afterFallBack=false;
DateTime previousUnspecifiedTimestamp=DateTime.MinValue;
foreach(日志中的var行)
{
var timestampText=…;//从行中获取时间戳
//在不执行任何时区转换的情况下解析时间戳
//(名称的“未指定”部分指DateTimeKind.unspecified。)
//TODO:检查格式
var unspecifiedTimestamp=DateTime.ParseExact(timestampText,
“yyyy-MM-dd'HH:MM:ss”,timestampText,CultureInfo.InvariantCulture);
//检测“后退”,以便我们知道
if(未指定时间戳<以前未指定时间戳)
{
后撤=真;
}
以前未指定的时间戳=未指定的时间戳;
DateTime utcTimestamp=ConvertToZone(区域,未指定的时间戳,后撤);
//处理日志条目
}
//测试性和整洁性的提取方法
专用静态日期时间转换区(
时区信息区,日期时间日期时间,布尔useLaterAmbiguousOffset)
{
如果(!zone.isambiguustime(dateTime))
{
返回TimeZoneInfo.ConvertToUtc(日期时间,区域);
}
//由此返回的偏移量按“最小偏移量”的顺序排列
//到“最大偏移”-这意味着以后观察到的偏移是
//发生在数组开头的一个。这实际上不是
//记录…您可以订购补偿以增加确定性,
//但如果这种情况发生变化,我会感到惊讶。
var offsets=zone.getAmbiguustimeOffsets(日期时间);
var chosenOffset=useLaterAmbiguousOffset?偏移量[0]:偏移量[1];
返回DateTime.SpecifyKind(DateTime-chosenOffset,DateTimeKind.Utc);
}

顺便说一句,这段代码在我的项目中会更简单,但我不一定建议您仅仅为了这个而切换。如果您正在做大量的日期/时间工作,那么值得一看。

如果您知道每个文件始终有一天,并且您总是可以检测到更改,因为您每30秒记录一次数据,那么您可以发现本地时间戳何时倒转,并计算出以这种方式使用的模糊偏移量。大概是这样的:

TimeZoneInfo zone=…;//我想你已经知道了
bool afterFallBack=false;
DateTime previousUnspecifiedTimestamp=DateTime.MinValue;
foreach(日志中的var行)
{
var timestampText=…;//从行中获取时间戳
//在不执行任何时区转换的情况下解析时间戳
//(名称的“未指定”部分指DateTimeKind.unspecified。)
//TODO:检查格式
var unspecifiedTimestamp=DateTime.ParseExact(timestampText,
“yyyy-MM-