Aws-sdk-net: DateTime์€ DocumentModel์„ ์‚ฌ์šฉํ•œ ์™•๋ณต ์ง๋ ฌํ™”๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2014๋…„ 07์›” 02์ผ  ยท  3์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: aws/aws-sdk-net

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);
    }
}

๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ฐธ์กฐ:

๋ชจ๋“  3 ๋Œ“๊ธ€

์˜ฌ๋ ค์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ง€์ ํ–ˆ๋“ฏ์ด ํ˜„์žฌ ๊ตฌํ˜„์€ 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์˜ ๊ฒฝ์šฐ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋„์ž…๋˜๋ฏ€๋กœ ์ „ํ™˜์„ ์—…๋ฐ์ดํŠธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰