【问题标题】:C# Work out time and date with timezone differenceC# 用时区差异计算时间和日期
【发布时间】:2016-02-02 16:57:47
【问题描述】:

我遇到了一个小问题,我正在连接到 Pokerstars.com 数据源以获取有关预定扑克锦标赛信息的更新 (https://www.pokerstars.com/datafeed/tournaments/all.xml)

然后我解析信息并将其存储在我的 Winforms 应用程序的 listView 中,但是我需要计算出正确的时间,包括本地时区差异。我知道 Pokerstars 服务器在 -05:00 运行,但我的问题是将其转换为我的应用程序特定用户的正确时间。

有人可以编写代码将其转换为该用户的当地时间,以便显示正确的开始时间。这是我用来读取 XML 文件的代码:

    private void LoadAllTournaments()
    {
        DataSet ds = new DataSet();
        ds.ReadXml("http://46.101.5.145/Feeds/all.xml");

        ListViewItem item;

        foreach (DataRow dr in ds.Tables["tournament"].Rows)
        {

            StartDate = dr["start_date"].ToString();

            if (dr["play_money"].ToString() != "true")
            {

                FPPFee = Convert.ToInt32(dr["fpp_fee"]);

                if (FPPFee == 0)
                {

                    if (dr["buy_in_fee"].ToString() != "$0 + $0")
                    {

                        item = new ListViewItem(new string[] { dr["name"].ToString(), StartDate.Substring(0, 10), StartDate.Substring(12, 7), dr["buy_in_fee"].ToString(), dr["prize"].ToString(), dr["players"].ToString(), dr["status"].ToString(), dr["id"].ToString()});
                        listView1.Items.Add(item);

                    }

                }

            }

        }

    }

为了记录,我连接到我自己的服务器来读取文件,因为 Pokerstars 只允许来自英国的人查看 XML 文件,所以他们每 10 分钟下载到我的英国 VPS。

【问题讨论】:

    标签: c# datetime timezone timestamp


    【解决方案1】:

    在xml中,提供的值如:

    <start_date>2015-11-02T12:50:00-05:00</start_date>
    

    因此,您不需要预先知道服务器的时区,因为偏移量已编码在数据中。只需将字符串解析为DateTimeOffset,然后使用TimeZoneInfo 转换为用户的时区。

    DateTimeOffset startDate = DateTimeOffset.ParseExact(
        (string) dr["start_date"],
        "yyyy-MM-dd'T'HH:mm:sszzz",
        CultureInfo.InvariantCulture);
    
    TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
    DateTimeOffset converted = TimeZoneInfo.ConvertTime(startDate, tz);
    

    在上面的示例中,"GMT Standard Time" 是伦敦的 Windows 时区标识符,冬季使用 GMT (UTC+00:00),夏季使用 BST (UTC+01:00)。当然,您需要知道哪个时区实际适用于您的用户。

    稍后在您的代码中,您使用Substring 提取部分日期 - 您不应该这样做,而应该使用格式化字符串。例如,converted.ToString("d") 表示日期,converted.ToString("t") 表示时间。请参阅 MSDN 中的 standardcustom 格式化字符串。

    【讨论】:

    • 太好了,这很好用。抱歉回复晚了,我只是使用以下方法设置时区: TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(localZone.StandardName.ToString());但是,我可以简单地使用用户输入的设置来设置时区......再次感谢您的帮助;)
    • 嗯,不。如果您想要本地区域,请使用TimeZoneInfo.Local。不要假设StandardName 会匹配Id。在非英语机器上,它们不匹配,有些也不匹配。
    • 另外,如果您只使用本地区域,则根本不需要TimeZoneInfo,因为DateTimeOffset 类型有一个ToLocalTime 方法可以转换为@987654339 @ 在本地区域中,或者在本地 DateTime 中具有相同值的 LocalDateTime 属性。
    【解决方案2】:

    首先,您必须将 StartDate 解析为日期时间。我不知道字符串是什么,您可能需要更精确地解析它,但总的来说:

    DateTime origDate = DateTime.Parse(StartDate);
    

    然后只需添加或减去小时数即可获得所需的时区。例如:

    DateTime newDate =   origDate.AddHours(-1);
    

    减去一小时。

    【讨论】:

    • 抱歉,不,您永远不应该使用加/减来调整时区。这是一个常见的坏主意,通常会导致灾难性的后果。
    • 呃,你可能是对的。但对于非 DST 国家/地区,这在技术上是可以的。
    • 并非如此。它改变了DateTime 值的含义,这通常会导致重新解释为其他值。换句话说,您不是在更改时区,而是在选择一个小时前的时间点。
    • 没错,我认为 DST 将是唯一的问题,为什么一个小时前的时间点与具有 -1 偏移量的 TimeZone 不同。也许当我更清醒时,我会在你的论点中看到更多的道理。
    • 您必须首先计算出正确的偏移量,是的,DST 可能会很困难,但也需要考虑其他非 DST 类型的转换(例如,Russian 2014 base-offset changes)。此外,DateTimeKind 可能会搞砸,尤其是当类型是 UtcLocal 时。 DateTimeOffsetTimeZoneInfo API 更安全。当然 - 如果您真的知道自己在做什么(我没有投反对票),这是可能的,但这不是必需的或推荐的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 2021-11-25
    相关资源
    最近更新 更多