遇到一个问题,当用户选择一个比当前时区提前x小时的时区时,我想保存的日期会从屏幕上选择的日期发生变化。
例如,他们选择 UTC + 2雅典 和
25/02/2016 的日期,然后记录的日期将是 24/02/2016 。
我已经缩小了原因,这是因为选择的日期时间被记录为例如 25/02/2016 00:00:00 ,并且带有2小时的偏移量,这将使其变为 24/02/2016 22:00:00
以前从未使用过时区,或UTC日期/时间,这非常令人困惑。
以下是代码- oObject.RefDate = itTimeAndDate.ParseDateAndTimeNoUTCMap(Request, TextBox_RefDate.Text);
if (!string.IsNullOrEmpty(oObject.TimeZoneDetails))
{
TimeZoneInfo oTimeZone = TimeZoneInfo.FindSystemTimeZoneById(oObject.TimeZoneDetails);
oObject.RefDate = itTimeAndDate.GetUTCUsingTimeZone(oTimeZone, oObject.RefDate);
}
RefDate
在从 ParseDateAndTimeNoUTCMap
返回时会类似于 25/02/2016 00:00:00
(参见下面的代码)。
static public itDateTime ParseDateAndTimeNoUTCMap(HttpRequest oTheRequest, string sValue)
{
DateTime? oResult = ParseDateAndTimeNoUTCMapNull(oTheRequest, sValue);
if (oResult != null)
return new itDateTime(oResult.Value);
return null;
}
/// <summary>
/// Translate a string that has been entered by a user to a UTC date / time - mapping using the
/// current time zone
/// </summary>
/// <param name="oTheRequest">Request context</param>
/// <param name="sValue">Date / time string entered by a user</param>
/// <returns>UTC date / time object</returns>
static public DateTime? ParseDateAndTimeNoUTCMapNull(HttpRequest oTheRequest, string sValue)
{
try
{
if (string.IsNullOrEmpty(sValue))
return null;
sValue = sValue.Trim();
if (string.IsNullOrEmpty(sValue))
return null;
if (oTheRequest != null)
{
const DateTimeStyles iStyles = DateTimeStyles.AllowInnerWhite | DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite;
// Create array of CultureInfo objects
CultureInfo[] aCultures = new CultureInfo[oTheRequest.UserLanguages.Length + 1];
for (int iCount = oTheRequest.UserLanguages.GetLowerBound(0); iCount <= oTheRequest.UserLanguages.GetUpperBound(0);
iCount++)
{
string sLocale = oTheRequest.UserLanguages[iCount];
if (!string.IsNullOrEmpty(sLocale))
{
// Remove quality specifier, if present.
if (sLocale.Contains(";"))
sLocale = sLocale.Substring(0, sLocale.IndexOf(';'));
try
{
aCultures[iCount] = new CultureInfo(sLocale, false);
}
catch (Exception) { }
}
else
{
aCultures[iCount] = CultureInfo.CurrentCulture;
}
}
aCultures[oTheRequest.UserLanguages.Length] = CultureInfo.InvariantCulture;
// Parse input using each culture.
foreach (CultureInfo culture in aCultures)
{
DateTime oInputDate;
if (DateTime.TryParse(sValue, culture.DateTimeFormat, iStyles, out oInputDate))
return oInputDate;
}
}
return DateTime.Parse(sValue);
}
catch (Exception)
{
}
return null;
}
从以上返回后,执行以下代码 -
TimeZoneInfo oTimeZone = TimeZoneInfo.FindSystemTimeZoneById(oObject.TimeZoneDetails);
oObject.RefDate = itTimeAndDate.GetUTCUsingTimeZone(oTimeZone, oObject.RefDate);
在GetUTCUsingTimeZone
中,问题似乎出现在我这里。
static public itDateTime GetUTCUsingTimeZone(TimeZoneInfo oTimeZone, itDateTime oDateTime)
{
if (oDateTime == null || oTimeZone == null)
return oDateTime;
DateTime oLocal = DateTime.SpecifyKind(oDateTime.Value, DateTimeKind.Unspecified);
DateTime oResult = TimeZoneInfo.ConvertTimeToUtc(oLocal, oTimeZone);
return new itDateTime(oResult);
}
我已经检查了TimezoneInfo
的偏移值,并且oResult
始终等同于oLocal param
- 偏移量。因此,带有3小时偏移量的25/02/2016 00:00:00
将等同于24/02/2016 21:00:00
。当偏移量为负数时,它会朝另一个方向进行,因此oResult = oLocal + 偏移量
,如果这样说是有道理的。所以日期改变的主要问题并不发生在那些情况下。
显然,这不是我想要的。我想要的是用户选择的时间,以其所在时区为准。有人遇到过类似的问题吗?有可能的解决方案吗?
我不确定自己哪里做错了。