在C#中将午夜解析为午夜而不丢失一天

时间:2018-08-28 03:57:57

标签: c# datetime

C#日期将是我的尽头。

在WebAPI中,我需要解析从设备以以下格式发送的一些日期: 1944-12-12T00:00:00.000 + 10:30

我的目标是解析它,以便我有正确的日期,即1944年12月12日。它不断将其弹回到1944年11月12日。因此,显然要减去偏移量。但是我不明白为什么。 1944年12月12日午夜是一个时间点。为什么不能仅对其进行解析,所以您最终得到了反映该日期的Datetime。

无论如何,这是我尝试使用的一些代码:

codes="NZ$300, KR$1200, DK$5"
get_country_codes=lambda c: ', '.join(e[0:2] for e in c.split(", "))
get_country_codes(codes)

至少,这使我获得了正确的一天。但是检查DateTime会显示hour属性的值为9。但这是午夜!

如果有人知道我怎样才能将午夜解析为午夜,那将不胜感激。

3 个答案:

答案 0 :(得分:1)

您应该使用DateTimeOffset正确解析

    public static DateTimeOffset? TryParseExactDateTime(string source)
    {
        DateTimeOffset parsedDate;

        if (DateTimeOffset.TryParseExact(source, AppFormatForParsing, CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate))
        {
            return new DateTimeOffset(parsedDate.DateTime);
        }

        return null;
    }

答案 1 :(得分:1)

您被固定在午夜,但aDate并不是指UTC午夜的时刻。您的肉眼会看到字符串的第一部分,然后看到“ 1944-12-12”,它只是字符串的一部分。这会导致您错误地认为相关日期是UTC 1944年12月12日。但是所引用的实际时间是世界标准时间1944年12月11日下午1:00。必须提供一些信息:要么您接受正确的分析并且正确的日期是12月11日,要么将输入字符串转换为引用其他时间点。

由于所有设备都发送往返格式的字符串(请参见ISO 8601),因此您可以放宽输入格式的严格程度,并使用TryParse。这样将允许以下字符串:

  • 1944-12-12T00:00:00.000 + 11:00
  • 1944-12-11T13:00:00.000Z
  • 1944-12-11T00:00:00Z
  • 1944-12-11Z

顺便说一下,前2个字符串:

  • 1944-12- 12 T00:00:00.000 + 11:00
  • 1944-12- 11 T13:00:00.000Z

参考时间完全相同。用Z编写字符串时,您可以清楚地看到相关日期是12月11日。解析时的2之间的区别是,第一个字符串使用DateTimeKind为Local进行解析,第二个字符串使用Kind of Utc进行解析。

如何返回DateTime有点尴尬。仅返回parsedDate.ToUniversalTime()会更简单。这样可以避免人们在不同时区运行代码并看到不同时间的任何本地问题,因为他们在查看本地时间而不是Utc。

一旦有了DateTime对象,并且只希望看到有问题的日期,即专注于该天的午夜,就可以使用DateTime.Date属性。

如果您绝对坚持将输入时间字符串转换为不正确的午夜结束,则可以使用以下简单方法:

private static string MutateToMidnight(string source)
{
    var pieces = source.Split(new char[] { 'T' });
    if (pieces.Length == 0 && pieces[0].EndsWith("Z", StringComparison.InvariantCultureIgnoreCase))
    {
        return pieces[0];
    }
    return pieces[0] + "Z";
}

如前所述,您可以使用TryParse来适应往返格式。这是一种影响:

public static DateTime? TryParseDateTime(string source)
{
    if (DateTime.TryParse(source, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var parsedDate))
    {
        return parsedDate.ToUniversalTime(); // .Date;
    }
    return null;
}

但是,我认为更改原始时间字符串是不合适的。您指的是与发送的时间不同的时刻。

答案 2 :(得分:0)

在编写以下代码时,它表示 UTC 1944-12-12午夜 + 提前11:00

string aDate =“ 1944-12-12T00:00:00.000 + 11:00”;

相反,从格式和目标分析字符串中删除时区

class Program
{
    private static string AppFormatForParsing = "yyyy-MM-ddTHH:mm:ss.fff"; // e.g. "2018-03-29T09:52:46.544+10:30"

    static void Main(string[] args)
    {
        string aDate = "1944-12-12T00:00:00.000";

        DateTime? d = TryParseExactDateTime(aDate)?.ToLocalTime();

        Console.ReadLine();
    }

    public static DateTime? TryParseExactDateTime(string source)
    {
            DateTime parsedDate;

            if (DateTime.TryParseExact(source, AppFormatForParsing, CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate))
            {
                return parsedDate;
            }

            return null;
    }
}

如果以后要添加时差,则可以添加时差或更改时区