DocumentModel Primitive๋ ์๋ณต ์ง๋ ฌํ๋ฅผ ์ ๋๋ก ์ง์ํ์ง ์์ต๋๋ค. ์๊ฐ๋์ ๋ฐ๋ฆฌ์ด๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ ์ง๋๋๋ก DateTime์ ์ง๋ ฌํํ ๋ ํ์ ์ง์ ์ "o"๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
DateTime ๋ฐ NullableDateTime์ ๋ํ ์ฌ๋ฐ๋ฅธ ์ง๋ ฌํ๋ฅผ ์ค๋ช ํ๊ธฐ ์ํด ์๋์ IPropertyConverter๋ฅผ ๋ง๋ค์์ต๋๋ค.
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.DocumentModel;
using System.Globalization;
/// <summary>
/// The <see cref="IPropertyConverter"/> to properly support round-trip serialization of <see cref="DateTime"/>.
/// </summary>
public class RoundTripNullableDateTimeTypeConverter : IPropertyConverter
{
/// <summary>
/// Converts the <c>value</c> to a <see cref="Primitive"/>.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>The primitive of the <c>value</c>.</returns>
public DynamoDBEntry ToEntry(object value)
{
var date = value as DateTime?;
return new Primitive
{
Value = date.HasValue ? date.Value.ToString("o", CultureInfo.InvariantCulture) : null
};
}
/// <summary>
/// Converts the <c>entry</c> to <see cref="DateTime"/>.
/// </summary>
/// <param name="entry">The entry to convert.</param>
/// <returns>The date time of the entry.</returns>
public object FromEntry(DynamoDBEntry entry)
{
var entryString = entry.AsString();
if (string.IsNullOrEmpty(entryString))
return null;
else
return DateTime.ParseExact(entryString, "o", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
}
}
/// <summary>
/// The <see cref="IPropertyConverter"/> to properly support round-trip serialization of <see cref="DateTime"/>.
/// </summary>
public class RoundTripDateTimeTypeConverter : IPropertyConverter
{
/// <summary>
/// Converts the <c>value</c> to a <see cref="Primitive"/>.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>The primitive of the <c>value</c>.</returns>
public DynamoDBEntry ToEntry(object value)
{
return new Primitive
{
Value = ((DateTime)value).ToString("o", CultureInfo.InvariantCulture)
};
}
/// <summary>
/// Converts the <c>entry</c> to <see cref="DateTime"/>.
/// </summary>
/// <param name="entry">The entry to convert.</param>
/// <returns>The date time of the entry.</returns>
public object FromEntry(DynamoDBEntry entry)
{
return DateTime.ParseExact(entry.AsString(), "o", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind);
}
}
๋ช ๊ฐ์ง ์ค์ํ ์ฐธ์กฐ:
์ฌ๋ ค์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ์ง์ ํ๋ฏ์ด ํ์ฌ ๊ตฌํ์ ISO 8601 UTC ํ์์ ์ฌ์ฉํฉ๋๋ค. ์ด ํ์์ ์๊ฐ๋๋ฅผ ์ ์ฅํ์ง ์๊ณ "o" ํ์์ผ๋ก ๊ฐ๋ฅํ ๊ฒ๋ณด๋ค ์ ๋ฐ๋๊ฐ ๋ฎ์ต๋๋ค.
์ด ํ์์ ์ฌ์ฉํ๊ธฐ๋ก ํ ์๋ ๊ฒฐ์ ์ ๋์ ์์ค์ DynamoDB API(.NET์ ํ ์ด๋ธ ๋ฐ DynamoDBContext, Java์ DynamoDBMapper ๋ฑ)๋ฅผ ๊ตฌํํ๋ ๋ชจ๋ AWS SDK์์ ์ด๋ฃจ์ด์ก์ต๋๋ค. ISO 8601 UTC ํ์์ผ๋ก ๋ ์ง๋ฅผ ์ ์ฅํ๋ฉด ์ผ๊ด๋ ๊ฒ์ ๋ฐ ์ ๋ ฌ์ด ๊ฐ๋ฅํฉ๋๋ค. ์๊ฐ๋๊ฐ ์ง์ ๋๋ฉด ๋ถ๊ฐ๋ฅํฉ๋๋ค. ๋ ํฐ ๋ฌธ์์ด ๊ฐ์ด ๋ฐ๋์ "๋ ํฐ" ๋ ์ง ๊ฐ์ ์๋ฏธํ๋ ๊ฒ์ ์๋๋ฉฐ ๋จ์ผ "๊ณ ์ ํ" ๋ ์ง์ ๋ํด ์ฌ๋ฌ ํํ์ ๊ฐ์ง ์ ์์ต๋๋ค. ํ์๋ ๊ฒ์(์ฟผ๋ฆฌ ๋ฐ ์ค์บ)๋ฟ๋ง ์๋๋ผ ๋ชจ๋ ์์ ์ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ต๋๋ค. DateTime์ ํค๋ก ์ฌ์ฉํ๋ ํญ๋ชฉ์ด ํน์ ์๊ฐ๋์ ํจ๊ป ์ ์ฅ๋ ๊ฒฝ์ฐ ๋์ผํ ์ ํํ ์๊ฐ๋๊ฐ ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ์๋ง ๊ฒ์ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์กฐ์ ๋ฐ๋ผ ํค๊ฐ ์ผ์นํ์ง ์๊ธฐ ๋๋ฌธ์ ์๊ฐ๋ ๋ณ๊ฒฝ์ผ๋ก ์ธํด ๋ชจ๋ ๋ฐ์ดํฐ ํธ์ถ์ด ์คํจํ ์ ์์ต๋๋ค.
์ ๋ฐ์ดํธ๋์ง ์์ ํด๋ผ์ด์ธํธ๋ ์ ํ์์ ๊ตฌ๋ฌธ ๋ถ์ํ ์ ์๊ธฐ ๋๋ฌธ์ .NET SDK์ ๋ํ ์์ ๋ณ๊ฒฝ ์ฌํญ์ ์ฌ๋ฌ SDK ๋๋ ๋ค๋ฅธ ๋ฒ์ ์ .NET SDK๋ฅผ ์ฌ์ฉํ๋ ์ฌ์ฉ์์๊ฒ ํฐ ๋ณํ๊ฐ ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ ์ ๊ณต๋ ๋ณํ๊ธฐ๋ ๋์ผํ ํ์์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ผ๊ด๋๊ฒ ์ฝ๊ณ ์ฐ๊ณ ์ธ๊ธ๋ ๊ณ ๋ ค ์ฌํญ ์ค ์ผ๋ถ๋ฅผ ๊ณ ๋ คํ๋ ํ ๊ณ ์ ๋ฐ ๋ ์ง๋ฅผ ํ์ค ์๊ฐ๋์ ํจ๊ป ์ ์ฅํ๋ ํ์ํ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค.
@PavelSafronov , ์๋ต ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
๋ด๊ฐ ๊ทธ๊ฒ์ ๊ฐ์ ธ์จ ์ด์ ๋ UTC ๋ ์ง๋ฅผ ์ ์ฅํ ๋ค์ ํญ๋ชฉ์ ๊ฐ์ ธ์ฌ ๋ ํ์ง ์๊ฐ๋๋ก ๋์์ค๋ ์๊ธฐ์น ์์ ๋์์ด์์ต๋๋ค. API๋ฅผ ์ฌ์ฉํ์ฌ UTC๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ ํ๊ฒ ์ ์ฅํ๊ณ ๊ฒ์ํ๋ ์ฐ๋ฆฌ์๊ฒ๋ ์์์น ๋ชปํ ์ผ์ ๋๋ค. API๋ ๋ค์ด์ค๋ DateTime์ด UTC๊ฐ ์๋๋ผ๊ณ ๊ฐ์ ํ๋ฏ๋ก ์ญ์ง๋ ฌํ ์ ํ์ง ์๊ฐ์ด์ด์ผ ํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. ๊ทธ๋์ ๋ชจ์๋ ๊ฐ์ ์ ํ๊ฒ ๋ฉ๋๋ค.
๋ ์ง์ ์ผ๊ด๋ ์ง๋ ฌํ ๋์์ด ํ์ํ ๋ค๋ฅธ ์ฌ์ฉ์๋ฅผ ๋๊ธฐ ์ํด AWSSDK.DynamoDBv2.Converters ๋ผ๋ Nuget ํจํค์ง๋ฅผ ๊ตฌ์ฑํ์ต๋๋ค. (์์ค๋ GitHub ์
์ด ์ ๋ณด๊ฐ ํ์ ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
@radleta์ ์ ์ฌํ ์ฌ์ฉ ์ฌ๋ก๊ฐ ์๋ ๊ฒฝ์ฐ ์์ ๋งํฌ๋ ๋ณํ๊ธฐ๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๊ธฐ๋ณธ SDK์ ๊ฒฝ์ฐ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ด ๋์ ๋๋ฏ๋ก ์ ํ์ ์ ๋ฐ์ดํธํ์ง ์์ต๋๋ค.