默認情況下,DynamoDB 將 .NET 轉換DateTime為字串型別 (S) 并以 ISO-8601 格式存盤日期。請參閱支持的資料型別。問題是 .NET 捕獲 7 位數的刻度,而 ISO-8601 存盤 3。因此,如果我要存盤 a DateTime,獲取物體,并將 .NET 日期與獲取的日期進行比較(例如在測驗中),這將失敗。
TimeOfDay比較:
15:28:21.4731507 (.NET)
15:28:21.473 (DynamoDB)
我看到的另一個問題是DynamoDBSDK 將在檢索專案時將 UTC 轉換為本地時間。使用解決方法查看報告的問題。建議的修復對我不起作用。轉換器將通過成功轉換日期ToUniversalTime(),但似乎回傳的值被忽略了。因此,我仍然得到當地時間。
我想避免將日期存盤在 ISO-8601 中。我知道我可以將刻度作為long屬性存盤在我的物體中。這消除了上述兩個問題。需要注意的是,以后我將無法DateTime在我的物體中的任何地方使用屬性型別。
這讓我想到了我的問題。是否可以覆寫默認的 SDK 行為,以便DateTime在 DynamoDB 中存盤為數字型別 (N)?
uj5u.com熱心網友回復:
要解決截斷刻度的問題,您可以使用“o”日期格式字串,這是“往返”日期格式,用于這種確切的場景。GitHub 示例沒有在其 lambda 中指定格式ToEntry,所以我相信它會進一步截斷資訊ToString()沒有任何格式資訊的情況下呼叫它時會進一步截斷資訊。
您可以像這樣修改 GitHub 中的示例:
public class CustomDateTimeConverter : IPropertyConverter
{
public DynamoDBEntry ToEntry(object value)
{
DateTime? dateTimeValue = value as DateTime?;
if (dateTimeValue == null)
{
throw new ArgumentOutOfRangeException();
}
string dateTimeString = dateTimeValue?.ToUniversalTime().ToString("o");
DynamoDBEntry entry = new Primitive
{
Value = dateTimeString,
};
return entry;
}
public object FromEntry(DynamoDBEntry entry)
{
Primitive primitive = entry as Primitive;
if (primitive == null || !(primitive.Value is string) || string.IsNullOrEmpty((string)primitive.Value))
{
throw new ArgumentOutOfRangeException();
}
string dateTimeString = primitive.Value as string;
DateTime dateTimeValue = DateTime.Parse(dateTimeString).ToUniversalTime();
return dateTimeValue;
}
}
這里有幾點需要注意:
- 我們打電話
ToString來"o"獲取往返格式 - 我們在呼叫之前強制使用 UniversalTime,
ToString("o");以獲取字串的“Z”格式而不是偏移格式,無論您是否傳入 aDateTimeKind.Local或DateTimeKind.Utcin。 - 我們也強制使用 UniversalTime
FromEntry,因為您似乎想使用 Utc。比較DateTime時,總是值得比較.Kind。
我們仍然將其添加到我們的背景關系中,如 GitHub 示例中所示:
context.ConverterCache.Add(typeof(DateTime), new CustomDateTimeConverter());
請注意DateTimeKind通過此示例設定輸出的影響:
var utcDate = DateTime.UtcNow;
// Create a book.
DimensionType myBookDimensions = new DimensionType()
{
Length = 8M,
Height = 11M,
Thickness = 0.5M,
};
Book utcBook = new Book
{
Id = 501,
Title = "UtcBook",
Isbn = "999-9999999999",
BookAuthors = new List<string> { "Author 1", "Author 2" },
Dimensions = myBookDimensions,
publishedOn = utcDate,
};
var localDate = DateTime.Now;
Book localBook = new Book
{
Id = 502,
Title = "Local Book",
Isbn = "999-1111",
BookAuthors = new List<string> { "Author 1", "Author 2" },
Dimensions = myBookDimensions,
publishedOn = localDate,
};
// Add the book to the DynamoDB table ProductCatalog.
await context.SaveAsync(utcBook);
await context.SaveAsync(localBook);
// Retrieve the book.
Book utcBookRetrieved = await context.LoadAsync<Book>(501);
Console.WriteLine(@$"Original: {utcDate.TimeOfDay}({utcDate.Kind}) => Saved: {
utcBookRetrieved.publishedOn.TimeOfDay}({utcBookRetrieved.publishedOn.Kind}). Equal? {
utcDate.TimeOfDay == utcBookRetrieved.publishedOn.TimeOfDay} ToUniversal() Equal? {
utcDate.ToUniversalTime().TimeOfDay == utcBookRetrieved.publishedOn.ToUniversalTime().TimeOfDay}");
Book localBookRetrieved = await context.LoadAsync<Book>(502);
Console.WriteLine(@$"Original: {localDate.TimeOfDay}({localDate.Kind}) => Saved: {
localBookRetrieved.publishedOn.TimeOfDay}({localBookRetrieved.publishedOn.Kind}). Equal? {
localDate.TimeOfDay == localBookRetrieved.publishedOn.TimeOfDay} ToUniversal() Equal? {
localDate.ToUniversalTime().TimeOfDay == localBookRetrieved.publishedOn.ToUniversalTime().TimeOfDay}");
這列印:
Original: 20:12:52.4810270(Utc) => Saved: 20:12:52.4810270(Utc). Equal? True ToUniversal() Equal? True
Original: 15:12:52.4812120(Local) => Saved: 20:12:52.4812120(Utc). Equal? False ToUniversal() Equal? True
相反,您也可以使用此方法匯出刻度。只需更改 ToEntry/FromEntry 即可轉換為數字刻度。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/532790.html
下一篇:睡眠時長條形圖
