首页 > 解决方案 > 在 C# 中将语言设置为阿拉伯语时读取和转换 Google 日历事件日期的问题

问题描述

我正在使用 Google APIs .net 客户端库来读取日历事件。

我有以下代码行

newRow["Start"] = pEventItem.Start.DateTime.HasValue ? 
Convert.ToDateTime(pEventItem.Start.DateTime) : Convert.ToDateTime(pEventItem.Start.Date);

其中 PEventItem 属于 Google.Apis.Calendar.v3.Data.Event 类型,而 NewRow[...] 属于 DataRow 类型。pEventItem.Start.Date 的值为“2019-06-24”(如调试窗口所示)

上面的代码行完美,但是当 UI 语言/文化设置为阿拉伯语(沙特阿拉伯)时失败。相同的 Convert.ToDateTime 引发错误“字符串未被识别为有效的日期时间”。

顺便说一句,我如何更改 UI 语言如下所示,供您参考。

 Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo(ChangeLanguageTo);
 Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.GetCultureInfo(ChangeLanguageTo);

我试图设置 Convert.ToDateTime 函数的第二个参数,希望它能正确转换日期......

CultureInfo enUsCulture = new CultureInfo("en-us");
newRow["Start"] = pEventItem.Start.DateTime.HasValue ? Convert.ToDateTime(pEventItem.Start.DateTime, enUsCulture) : Convert.ToDateTime(pEventItem.Start.Date, enUsCulture);

那么现在它不会抛出异常,但是返回的日期不正确。返回的值是 {21/10/40 12:00:00 ص}

而实际日期 pEventItem.Start.Date 是“2019-06-24”

我也尝试过不变的文化,但结果是一样的,转换的日期是错误的。可能是什么问题?

问候

在此处输入图像描述

标签: c#-4.0google-calendar-apidatetime-formatgoogle-api-dotnet-client

解决方案


这里发生了一些事情。

首先,如果您使用EventDateTime.DateTime(例如 via pEventItem.Start.DateTime),则不需要调用Convert.ToDateTime,因为那已经是 a DateTime?... 您只需获取Value属性即可DateTime从 a 获取 a DateTime?。但是,我应该警告说,这可能会执行您可能不想要的时区转换。(我们无法修复库来避免这些,因为这将是一个重大更改。)相反,您可能想要 parse EventDateTime.DateTimeRaw,这是 API 返回的原始字符串值。

解析时,我建议使用不变文化 using CultureInfo.InvariantCulture(而不是创建 en-US 文化),并使用 解析DateTime.ParseExact,根据您是解析日期还是完整日期/时间来指定您期望的格式。

就“返回的日期不正确”而言 - 我相信这实际上只是使用默认文化的格式化值,包括日历系统。我们可以在下面的代码中看到这一点,它DateTime直接构造了(因此不会受到任何文本解析等的影响)。使用不变区域性格式化时,它显示为 2019-06-24,但使用 ar-SA 格式化时,它显示为“1440-10-21”,因为该区域性的默认日历系统是System.Globalization.UmAlQuraCalendar

// Note: when a calendar system is not specified,
// it's implicitly Gregorian.
DateTime date = new DateTime(2019, 6, 24);

Console.WriteLine(date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture));
Console.WriteLine(date.ToString("yyyy-MM-dd", new CultureInfo("ar-SA")));

因此,您在调试器中看到的是正确的日期——但以您未预料到的方式格式化。


推荐阅读