简体   繁体   English

.NET Web服务中的DateTime转换行为不一致

[英]Inconsistent DateTime conversion behaviour in .NET Web Service

Problem 问题

I've a Windows app syncs with the Server using SharePoint hosted Web Services. 我有一个Windows应用程序使用SharePoint托管的Web服务与服务器同步。 When the app syncs to the server using LAN (goes through an internal Proxy server) all the DateTime formats are in dd/MM/yyyy format (which is how it is intended to be) 当应用程序使用LAN同步到服务器(通过内部代理服务器)时,所有DateTime格式均为dd / MM / yyyy格式(这就是预期的格式)
However, when the app syncs over 4G,all DateTime formats are in MM/dd/yyyy format. 但是,当应用通过4G同步时,所有DateTime格式均为MM / dd / yyyy格式。
This happens for all data inbound and outbound. 所有入站和出站数据都会发生这种情况。

Server 服务器

Windows Server 2012 with SharePoint 2013 hosting SOAP services 具有SharePoint 2013托管SOAP服务的Windows Server 2012
Region: Singapore 地区:新加坡
Format: English (Singapore) 格式:英文(新加坡)

Client 客户

Windows 10 tablet app Windows 10平板电脑应用
Region: Singapore 地区:新加坡
Format: English (Singapore) 格式:英文(新加坡)

Other information: 其他信息:
1. It is the same tablet being used on both WiFi and 4G, so we can rule out 2 tablets having different regional settings. 1. WiFi和4G使用的是同一台平板电脑,因此我们可以排除2台具有不同区域设置的平板电脑。
2. I've verified that the Windows 10 app passes the formats correctly and it is the server that behaves differently over WiFi and 4G. 2.我已验证Windows 10应用正确传递了格式,并且服务器在WiFi和4G上的行为有所不同。
3. I beleive that the issue is caused by .NET itself and not because of SharePoint. 3.我相信问题是由.NET本身引起的,而不是SharePoint引起的。 However, I don't want to rule it out as I'm not sure of the actual cause. 但是,由于我不确定实际原因,因此我不想将其排除在外。 Please comment if you require any further information if you feel that it is caused because of SharePoint 如果您认为是由于SharePoint引起的任何其他信息,请发表评论

Snippets: 摘录:

I've skipped the using statements and SPWeb statements in the snippet to keep it simple. 为了简化起见,我跳过了代码段中的using语句和SPWeb语句。 And the LastModifiedTime field in the SPList of type DateTime and not single line text. SPList中的LastModifiedTime字段的类型为DateTime,而不是单行文本。

Model 模型

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
}

Web Service 网络服务

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;

    }
}

Now, I've fixed the problem by using format strings when converting between string and DateTime and vice-versa. 现在,我已经解决了在字符串和DateTime之间进行转换时使用格式字符串的问题,反之亦然。 So more or less, I've got it working for now. 或多或少,我现在已经开始工作了。

So my question here is, what is the reason behind this behaviour? 所以我的问题是,这种行为背后的原因是什么? If possible, please cite links to documentation or references to any other sources that explain this behaviour 如果可能,请引用说明链接或指向解释此行为的任何其他来源的引用

Is it possible that the server infers the culture info from the request header? 服务器是否有可能从请求标头中推断区域性信息? I've always thought that the DateTime.Parse()/Convert.ToDateTime() always got the defaults from the regional settings of the machine it runs on. 我一直认为DateTime.Parse()/ Convert.ToDateTime()总是从运行它的计算机的区域设置中获取默认值。

First of all, a DateTime does not have any implicit format. 首先, DateTime没有任何隐式格式。 It just have date and time values. 它只具有日期和时间值。 Format concept only applies when you get it textual (string) representation. 格式概念仅在获得文本 (字符串)表示形式时才适用。 I strongly suggest to change this data type from string to DateTime if you can that returns by web service. 如果可以通过Web服务返回,我强烈建议将此数据类型从string更改为DateTime

I've verified that the Windows 10 app passes the formats correctly and it is the server that behaves differently over WiFi and 4G 我已验证Windows 10应用正确传递了格式,并且服务器在WiFi和4G上的行为有所不同

There is no such a thing. 没有这样的事情。 Parsing string to DateTime or vice versa does not depends on how you connected to internet. 解析字符串,日期时间,反之亦然并不取决于你如何连接到互联网。 It is all about culture settings. 这全都与文化设置有关。

Since you use it as; 由于您将其用作

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

This code will use CurrentCulture settings by default where it's located. 默认情况下 ,此代码将使用CurrentCulture设置。 Since you said; 因为你说过

It is the same tablet being used on both WiFi and 4G, so we can rule out 2 tablets having different regional settings WiFi和4G使用的是同一台平板电脑, 因此我们可以排除2台具有不同区域设置的平板电脑

One regional settings parse your string as a 6 January and the other settings parse your string as 1 June. 一个区域设置将您的字符串解析为1月6日,而其他设置则将您的字符串解析为6月1日。 That's too normal. 正常了。 Looks like one setting uses dd/MM/yyyy format and the other one uses MM/dd/yyyy . 看起来其中一种设置使用dd/MM/yyyy格式,而另一种使用MM/dd/yyyy格式。

As a solution, you can use DateTime.ParseExact method to specify exact culture that matches with your string. 作为解决方案,您可以使用DateTime.ParseExact方法指定与您的字符串匹配的确切区域性。 Or you can equalize regional settings on both tablet. 或者,您可以在两个平板电脑上均衡区域设置。

For example; 例如;

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

will parse as 1 June 2015 but 将解析为2015年6月1日,但

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

will parse as 6 January 2015. 将于2015年1月6日解析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM