【问题标题】:Inconsistent DateTime conversion behaviour in .NET Web Service.NET Web 服务中不一致的 DateTime 转换行为
【发布时间】:2015-12-27 11:48:34
【问题描述】:

问题

我有一个 Windows 应用程序使用 SharePoint 托管的 Web 服务与服务器同步。 当应用程序使用 LAN(通过内部代理服务器)同步到服务器时,所有 DateTime 格式都是 dd/MM/yyyy 格式(这就是它的意图)
但是,当应用通过 4G 同步时,所有 DateTime 格式都是 MM/dd/yyyy 格式。
所有入站和出站数据都会发生这种情况。

服务器

带有托管 SOAP 服务的 SharePoint 2013 的 Windows Server 2012
地区:新加坡
格式:英文(新加坡)

客户

Windows 10 平板电脑应用
地区:新加坡
格式:英文(新加坡)

其他信息:
1. WiFi 和 4G 使用的是同一台平板电脑,所以我们可以统治 出 2 个具有不同区域设置的平板电脑。
2. 我已验证 Windows 10 应用程序正确传递了格式,并且它是在 WiFi 和 4G 上表现不同的服务器。
3. 我相信这个问题是由 .NET 本身引起的,而不是因为 SharePoint。但是,我不想排除它,因为我不确定实际原因。如果您认为这是由 SharePoint 引起的,请在需要任何进一步信息时发表评论

片段:

为了简单起见,我跳过了 sn-p 中的 using 语句和 SPWeb 语句。以及日期时间类型的 SPList 中的 LastModifiedTime 字段,而不是单行文本。

型号

public class Record
{
    public string ID {get; set}
    public string ModifiedDateTime {get; set;} //Don't ask why it is not a DateTime object. It was too late by the time I took over
}

网络服务

public class WebService : IWebService
{
    public List<Record> GetUpdates(string lastModifiedTime)
    {
        SPQuery query= QueryBuilder.GetUpdateQuery(lastModifiedDateTime);
        SPList spRecordList = spWeb.Lists["Record"];
        SPListItemCollection results = spRecordList.GetItems(query);
        List<Record> records = new List<Record>();
        foreach(SPListItem spRecord in results)
        {
            Record record = new Record();
            record.ID = spRecord.ID.ToString();
            record.ModifiedDateTime = Convert.ToString(spRecord["LastModifiedTime"]);
            //1 June 2015 would return as 01/06/2015 in WiFi but 06/01/2015 on 4G

            records.Add(record);
        } 
        return records;
    }

    public Record CreateOrUpdateRecord(Record record)
    {
        SPListItem spRecord = null;
        SPList spRecordList = spWeb.Lists["Record"];
        if(string.IsNullOrEmpty(record.ID))
        {
            spRecord = spRecordList.AddItem();
            record.ID = spRecord.ID.ToString();
        }
        else
        {
            spRecord = spRecordList.GetItemByID(record.ID);
        }

        DateTime modified = Convert.ToDateTime(record.Modified);
        spRecord["LastModifiedTime"] = modified;

        /*
            Say ModifiedDateTime is 1 June 2015.
            Then on WiFi, modified = 01/06/2015
            On 4G, modified = 06/01/2015
        */

        return record;

    }
}

现在,我通过在字符串和 DateTime 之间转换时使用格式字符串解决了这个问题,反之亦然。所以或多或少,我现在已经让它工作了。

所以我的问题是,这种行为背后的原因是什么?如果可能,请引用文档链接或对任何其他解释此行为的来源的引用

服务器是否有可能从请求标头中推断出文化信息?我一直认为 DateTime.Parse()/Convert.ToDateTime() 总是从它运行的机器的区域设置中获得默认值。

【问题讨论】:

    标签: c# asp.net .net datetime sharepoint


    【解决方案1】:

    首先,DateTime 没有 any 隐式格式。它只有日期和时间值。格式概念仅在您获得 textual (字符串)表示时才适用。我强烈建议将此数据类型从string 更改为DateTime,如果您可以通过网络服务返回。

    我已验证 Windows 10 应用程序正确传递了格式,并且 它是在 WiFi 和 4G 上表现不同的服务器

    没有这样的事情。将字符串解析为 DateTime 或反之亦然 not 取决于您连接到 Internet 的方式。一切都与文化环境有关。

    既然你把它当作;

    DateTime modified = Convert.ToDateTime(record.Modified);
    

    此代码将使用CurrentCulture 设置默认情况下它所在的位置。既然你说了;

    在 WiFi 和 4G 上使用的是同一台平板电脑,所以我们可以统治 出 2 台具有不同区域设置的平板电脑

    一个区域设置将您的字符串解析为 1 月 6 日,而其他设置将您的字符串解析为 6 月 1 日。这正常。看起来一种设置使用dd/MM/yyyy 格式,另一种使用MM/dd/yyyy

    作为一种解决方案,您可以使用DateTime.ParseExact 方法来指定与您的字符串匹配的精确 文化。或者,您可以在两台平板电脑上均衡区域设置。

    例如;

    DateTime dt = DateTime.ParseExact("01/06/2015", "dd/MM/yyyy", CultureInfo.InvariantCulture);
    

    将解析为 2015 年 6 月 1 日,但

    DateTime dt = DateTime.ParseExact("01/06/2015", "MM/dd/yyyy", CultureInfo.InvariantCulture);
    

    将解析为 2015 年 1 月 6 日。

    【讨论】:

    • 感谢您的回复。你的回答也跟我想的一样。如果 Convert.ToDateTime 确实使用服务器的当前文化,那么为什么它会在上述场景中以两种不同的方式表现?正如我所说,我已经应用了您在代码中提到的修复程序。但我很想知道这种行为背后的原因。
    • @Sugesh 如果您没有为所有DateTime 解析方法(包括Convert.ToDateTime)提供任何文化,它们默认使用CurrentCulture 设置。显然,一种设置将您的字符串解析为1 June 2015,但另一种设置解析为6 January 2015。在我的DateTime.ParseExact 示例中,我提供了与字符串完全匹配的格式。在第一个中,我使用dd/MM/yyyy 格式并说; “01 应该被解析为日,06 应该被解析为月部分”并使用了MM/dd/yyyy 格式,这显然意味着相反。这就是它们返回不同结果的原因。
    • 我们俩都在同一个页面中,我最初使用 CurrentCulture 的方法。也许我的问题不清楚。 CurrentCulture 在这两种情况下不同的原因可能是什么?它是相同的服务器,相同的方法,我希望两个调用具有相同的结果,因为它是相同的服务器,并且两个调用之间没有更改区域设置。我提到的 WiFi/4G 场景也经常发生这种情况。我已经测试了很多次,每次都是一样的。
    • @Sugesh 但你说:..so we can rule out 2 tablets having different regional settings 在你的问题中。这使您的CurrentCulture 设置在您的两台平板电脑中都不同。这就是为什么你会得到不同的结果。只需尝试将它们设置为相等并查看差异。
    • 也许我的措辞不清楚。这是我在这两种情况下使用的同一台平板电脑。第一次通过 WiFi 通话,第二次通过 4G 通话。我的意思是,我们可以从可能的因素中排除平板电脑具有不同文化的可能性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 2020-03-04
    • 2012-04-20
    • 1970-01-01
    相关资源
    最近更新 更多