C#:自定义时区格式字符串

C#: Custom time zone format strings

我需要从自定义格式中读取与 UTC 的时区偏移量。这根据标准定义为:

Encoded as an ASCII string in the format "&ZZXX". The components of this string, from left to right, are & = "+" or "-", and ZZ = Hours and XX = Minutes of offset. Leading space characters shall not be present.

The offset for UTC shall be +0000; -0000 shall not be used.

我不明白如何在我的案例中使用任何修饰符来读取这种格式(并且只读这种格式):

到目前为止我有:

bool isValidTimezoneOffsetFromUTC(string timezoneOffsetFromUTC)
{
    try
    {
        DateTimeOffset.ParseExact(timezoneOffsetFromUTC, "%K", CultureInfo.InvariantCulture);
        if (timezoneOffsetFromUTC.Length != 5 || timezoneOffsetFromUTC == "-0000") return false;
        return true;
    }
    catch (ArgumentNullException)
    {

    }
    catch (FormatException)
    {

    }
    return false;
}

这看起来太复杂了...有没有办法在没有外部依赖的情况下简化这段代码?

+0000 是一个偏移量,而不是完整的日期时间和时区偏移量。顾名思义,DateTimeOffset 用于带偏移量的完整日期时间。有效值应该是 2021-09-06T 15:36:49 +00:002021-09-06T15:36:49+00:00,而不仅仅是 +00:00

用于指定偏移量的类型是TimeSpan. Parsing a custom timespan format is done using TimeSpan.ParseExact. The method TryParseExact用于解析而不抛出:

var input="-0430";
var formats=new[]{"\+hhmm","\-hhmm"};
Console.WriteLine(TimeSpan.TryParseExact(input,
                                 formats, 
                                 CultureInfo.InvariantCulture, 
                                 out var result));
-----
True

此方法returns true 如果值有效。解析后的值通过 result 输出参数返回。

TimeSpan.ParseExactTryParseExact 不解析负时间戳,因此使用了两种不同的格式,一种用于正偏移量,一种用于负偏移量。在这些格式中,符号用作必须出现在输入中的文字字符。

方法可以重写为:

const string[] formats=new[]{"\+hhmm","\-hhmm"};

bool isValidTimezoneOffsetFromUTC(string timezoneOffsetFromUTC)
{
return TimeSpan.TryParseExact(timezoneOffsetFromUTC,
              formats,
              CultureInfo.InvariantCulture, 
              out var result);
}

更新

丢弃-0000只需要一个简单的相等性检查:

static readonly string[] formats=new[]{"\+hhmm","\-hhmm"};

bool isValidTimezoneOffsetFromUTC(string offset)
{
    if (offset=="-0000")
    {
        return false;
    }
    
    return TimeSpan.TryParseExact(s,
              formats,
              CultureInfo.InvariantCulture, 
              out var result);
}

使用模式匹配这可以成为一个表达体的方法:

static readonly string[] formats=new[]{"\+hhmm","\-hhmm"};

bool isValidDicomOffset(string offset)=>
    offset switch 
    {
       "-0000"=>false,
       string s=> TimeSpan.TryParseExact(offset,
                      formats,
                      CultureInfo.InvariantCulture, 
                      out var result)
    };