解析可怕的时间戳 C#

Parsing horrible timestamp C#

我有一个来自服务器的时间戳,格式为 20220505 17:36:29 - 它有 2 个空格,我不相信发件人在未来的修订中总是发送相同数量的空格 - 理想情况下我想处理任意数量的空格相同。

我用 DateTime.ParseExact 试过但失败了:

var horribleTimestamp = "20220505  17:36:29";
var timestamp = DateTime.ParseExact(horribleTimestamp, "yyyyMMdd  hh:mm:ss", CultureInfo.InvariantCulture)
// throws `System.FormatException: String '20220505  17:36:29' was not recognized as a valid DateTime.`

为了让我以后不再为时区头痛,我该如何使用 Nodatime 实现这一点,因为我认为切换到时区已经很有意义了。

时间是我 PC 的本地时间,我想将其转换为给定本地时区的全球时间戳(我认为应该是 Instant?)?

您的格式有误。使用 HH 而不是 hh。请参阅下面的更新代码

var horribleTimestamp = "20220505  17:36:29";
var timestamp = DateTime.ParseExact(horribleTimestamp, "yyyyMMdd  HH:mm:ss", CultureInfo.InvariantCulture)

这是 y link 解释了您可以在格式中使用的内容 -> https://www.c-sharpcorner.com/blogs/date-and-time-format-in-c-sharp-programming1

您可以将多种格式作为数组传递给ParseExact

var horribleTimestamp = "20220505  17:36:29";
var formats = new[]{"yyyyMMdd HH:mm:ss","yyyyMMdd  HH:mm:ss","yyyyMMdd   HH:mm:ss"};
var timestamp = DateTime.ParseExact(horribleTimestamp, formats, CultureInfo.InvariantCulture, 0);

dotnetfiddle

可以这样解决白space的问题:

var horribleTimestamp = "20220505  17:36:29";
var date = horribleTimestamp.Substring(0, 8);
var index = horribleTimestamp.LastIndexOf(' ') + 1;
var time = horribleTimestamp.Substring(index, horribleTimestamp.Length - index);
var timestamp = DateTime.ParseExact($"{date} {time}", "yyyyMMdd HH:mm:ss", CultureInfo.InvariantCulture);

我假设日期总是 8 个字符并且 space 总是存在。在其他情况下,检查 index == -1.

如果您想处理任意数量的白色space,有两种选择:

  • 使用正则表达式(或类似表达式)将其转换为具有单个 space
  • 的规范格式
  • 分割成spaces,然后分别解析第一部分和最后一部分。 (或者拆分 spaces,重新组合第一部分和最后一部分并解析...)

在 Noda Time 中,您获得的值表示 LocalDateTime,因此您应该将其解析为。这是一个使用正则表达式方法的完整示例:

using NodaTime;
using NodaTime.Text;
using System.Text.RegularExpressions;

// Lots of spaces just to check the canonicalization
string text = "20220505     17:36:29";

// Replace multiple spaces with a single space.
string canonicalized = Regex.Replace(text, " +", " ");

// Note: patterns are immutable; you should generally store them in
// static readonly fields. Note that "uuuu" represents an absolute year number,
// whereas "yyyy" would be "year of era".
LocalDateTimePattern pattern =
    LocalDateTimePattern.CreateWithInvariantCulture("uuuuMMdd HH:mm:ss");

ParseResult<LocalDateTime> result = pattern.Parse(canonicalized);
// Note: if you're happy with an exception being thrown on a parsing failure,
// juse use result.Value unconditionally. The approach below shows what to do
// if you want to handle parse failures without throwing an exception (or with
// extra behavior).
if (result.Success)
{
    LocalDateTime value = result.Value;
    Console.WriteLine(value);
}
else
{
    // You can also access an exception with more information
    Console.WriteLine("Parsing failed");
}