在填充的数据表中将 datetime 列从 utc 转换为本地时间
Posted
技术标签:
【中文标题】在填充的数据表中将 datetime 列从 utc 转换为本地时间【英文标题】:Convert datetime column from utc to local time in a populated datatable 【发布时间】:2020-01-20 16:28:10 【问题描述】:我正在尝试使用 EPPLUS 将一些数据从 Sql Server 导出到一个 excel 文件中,并传递一个自定义 sql select statemet。这工作正常,但问题是日期时间字段以 UTC 格式存储在数据库中,而不是我想以本地时区格式(es.GMT +2)显示它们。有没有办法以最小的性能损失来完成?使用 EPPLUS 方法在数据表或 excel 文件中转换列都没有关系。我希望最终输出以 +2 小时为单位显示时间。
我尝试添加 DataColumn col.ExtendedProperties.Add("TZ", +2);但没有任何改变。 DataColumn.DateTimeMode 不适用于填充的 DataTable。我正在尝试用添加 +2 小时的公式替换 excel 列,但我无法弄清楚。 下面你可以看到我的代码。
string connString = @"Data Source=" + DataSourceName + ";Initial Catalog=" + InitialCatalog + ";User ID=" + UserID + "; Password=" + password + ";Integrated Security=SSPI;";
SqlConnection conn = new SqlConnection(connString);
conn.Open();
//retreive data from the report query
SqlCommand Reportcmd = new SqlCommand(ReportQuery, conn);
Reportcmd.CommandTimeout = 0;
SqlDataAdapter Reportda = new SqlDataAdapter(Reportcmd);
Reportda.Fill(ReportDtTbl);
conn.Close();
//var fileName = "Example-CRM-" + DateTime.Now.ToString("yyyy-MM-dd--hh-mm-ss") + ".xlsx";
MemoryStream stream = new MemoryStream();
using (ExcelPackage pck = new ExcelPackage(stream))
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Report");
Tempaltesheet.Cells[1, 1, 1, 100].Copy(ws.Cells[1, 1, 1, 100]); //Cells[RowStart, ColumnStart, RowEnd, ColumnEnd ]
int colNumber = 1;
foreach (DataColumn col in ReportDtTbl.Columns)
if (col.DataType == typeof(DateTime))
ws.Column(colNumber).Style.Numberformat.Format = "dd/MM/yyyy hh:mm:ss";
//DataColumn col.ExtendedProperties.Add("TZ", +2);
colNumber++;
ws.Cells["A2"].LoadFromDataTable(ReportDtTbl, false);
// save our new workbook in the output directory and we are done!
ReportExcel = pck.GetAsByteArray();
//pck.Save();
return ReportExcel;
【问题讨论】:
如果日期存储在 DateTime 中,则无需转换。只要确保您在当地时间显示。如果日期存储不正确,则需要进行更改。如果您确实需要进行更改,最好的方法是使用 SQL Server Management Studio 并编写一个 SQL 过程。 【参考方案1】:您应该更改对数据库的查询以考虑与 UTC 相比的本地时间差异,而不是在返回数据后更改日期时间。
SELECT CONVERT(datetime,
SWITCHOFFSET(CONVERT(datetimeoffset,
MyTable.UtcColumn),
DATENAME(TzOffset, SYSDATETIMEOFFSET())))
AS ColumnInLocalTime
FROM MyTable
如本答案所述,不要减去小时数: Convert Datetime column from UTC to local time in select statement
【讨论】:
A familiar-looking answer 还指出,这不会针对 DST 进行调整。【参考方案2】:因为它已经是日期时间类型:
TimeZoneInfo tz= TimeZoneInfo.FindSystemTimeZoneById("<timezone column?>");//"Central Standard Time"
DateTime tzTime = TimeZoneInfo.ConvertTimeFromUtc(<utctime>, tzTime );
使用 IsDaylightSavingTime 检查夏令时。
如果您不知道本地时区是什么(它不存储在一个 coumn 中),请使用 ToLocalTime 作为当前时区。
【讨论】:
以上是关于在填充的数据表中将 datetime 列从 utc 转换为本地时间的主要内容,如果未能解决你的问题,请参考以下文章