我正在開發 .Net Core 3.1 REST Api。
我有接近午夜的日期和時區問題。
我以 UTC 格式保存資料庫中的所有資料,前端呼叫 API 以 UTC 格式傳遞時間。
我目前在 GTM 2 時區。
我必須將用戶執行的“操作”分成不同的日期。
輸出示例:
{
days: [
{
day: '2021-10-28',
actions: [
{
id: 123456,
actionType: 1,
startDate: '2021-10-28T12:04:12Z',
endDate: '2021-10-28T13:04:39Z'
},
{
...
}
],
actualHours: 1,
expectedHours: 4
},
{
day: '2021-10-29',
actions: [
{
id: 123467,
actionType: 1,
startDate: '2021-10-29T12:00:45Z',
endDate: '2021-10-29T14:00:40Z'
},
{
...
}
],
actualHours: 2,
expectedHours: 4
}
]
}
當我們有接近午夜的時間時會出現問題,因為在資料庫中,這一天將被保存為用戶輸入的前一天。
為一整天添加操作的用戶示例。
前端側:
- 開始日期:2021-10-28T00:00:00.000
- 結束日期:2021-10-28T23:59:59.999
JSON 請求:
{
actionType: 1,
startDate: '2021-10-27T22:00:00.000Z',
endDate: '2021-10-28T21:59:59.999Z'
}
在資料庫中,日期將保存為:
- 開始日期:2021-10-27T22:00:00.000Z
- 結束日期:2021-10-28T21:59:59.999Z
為了采取行動并按天將它們分開,我寫了這個代碼片段..
public async Task<IList<DailyActionItem>> GetAsync(string userId, DateTime startDate, DateTime? endDate)
{
// Other code here..
// Get actions by dates
var tActions = await _actionsQuery.GetPeriodAsync(userId, startDate, endDate).ConfigureAwait(false);
// Create a list of days
var days = new List<DailyActionItem>();
// Cycling the range of dates and also adding the missing days
var ed = endDate.HasValue ? endDate.Value.Date : DateTime.UtcNow.Date;
for (var sd = startDate.Date; sd <= ed; sd = sd.AddDays(1))
{
var daily = new DailyActionItem
{
Day = sd.Date,
Actions = new List<ActionItem>()
};
// Other code here..
var actions = tActions
.Where(t => (t.StartDate <= sd.AddDays(1).AddTicks(-1) && t.StartDate >= sd) ||
(t.StartDate <= sd.AddDays(1).AddTicks(-1) && t.EndDate.HasValue && t.EndDate >= sd))
.OrderBy(c => c.StartDate);
// Add actions nella risposta e calcolo i valori attuali
if (actions?.Any() == true)
{
foreach (var action in actions)
{
daily.Actions.Add(new ActionItem
{
Id = action.Id,
ActionType = action.ActionType,
StartDate = action.StartDate,
EndDate = action.EndDate,
Comment = action.Comment
});
}
// Other code here..
}
// Important: calculations made on the day
daily.ActualHours = tActions.Sum(...);
daily.ExpectedHours = contract.ExpectedHours;
// Other code here..
days.Add(daily);
}
return days;
}
除錯示例(單日 - 2021-10-28 從本地 00:00 到本地 23:59):
- 開始日期:2021-10-27T22:00:00.000Z
- 結束日期:2021-10-28T21:59:59.999Z
在 foreach 中:
第一輪 -> sd = 2021-10-27T00:00:00.000Z 最后一輪 -> sd = 2021-10-28T00:00:00.000Z
輸出:
{
days: [
{
day: '2021-10-27',
actions: [
{
id: 123987,
actionType: 1,
startDate: '2021-10-27T22:00:00.000Z',
endDate: '2021-10-28T21:59:59.999Z'
}
],
actualHours: 24, // full day, wrong place!
expectedHours: 4
},
{
day: '2021-10-28',
actions: [
{
...
},
{
...
}
]
}
]
}
由于 API 在 UTC 中作業,因此此代碼根據 UTC 中的值拆分日期。
例如,輸入“2021-10-28T00:00:00.000 LOCAL”的最后一天將被放置在“2021-10-27 UTC”日之下。
我怎么解決這個問題?我錯過了什么?
管理這些案例的最佳方法是什么?
理論上結果是正確的。但是在前端讀取資料是不正確的。
uj5u.com熱心網友回復:
看起來像一個奇怪的錯誤。我建議更換 DateTime與DateTimeOffset無處不在,使DB遷移和更新資料庫。
告訴我上述方法是否無效。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/342519.html
標籤:C# asp.net核心 约会时间 .net核心 时区
上一篇:將日期字串轉換為日期時間C#
