@@ -37,10 +37,12 @@ public static class CryptoUtility
3737 internal static readonly DateTime UnixEpoch = new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 , 0 , DateTimeKind . Utc ) ;
3838 internal static readonly DateTime UnixEpochLocal = new DateTime ( 1970 , 1 , 1 , 0 , 0 , 0 , 0 , DateTimeKind . Local ) ;
3939 internal static readonly Encoding Utf8EncodingNoPrefix = new UTF8Encoding ( false , true ) ;
40+ static string koreanZoneId = "Korea Standard Time" ;
41+ static TimeZoneInfo koreaZone = TimeZoneInfo . FindSystemTimeZoneById ( koreanZoneId ) ;
4042
41- private static Func < DateTime > utcNowFunc = UtcNowFuncImpl ;
43+ private static Func < DateTime > utcNowFunc = UtcNowFuncImpl ;
4244
43- private static DateTime UtcNowFuncImpl ( )
45+ private static DateTime UtcNowFuncImpl ( )
4446 {
4547 // this is the only place in the code that DateTime.UtcNow is allowed. DateTime.UtcNow and DateTime.Now should not exist anywhere else in the code.
4648 return DateTime . UtcNow ;
@@ -181,13 +183,19 @@ public static byte[] DecompressDeflate(byte[] bytes)
181183 }
182184 }
183185
186+ public enum SourceTimeZone
187+ {
188+ /// <summary> time zone is specifically specified in string </summary>
189+ AsSpecified ,
190+ Local , Korea , UTC
191+ }
184192 /// <summary>
185193 /// Convert object to a UTC DateTime
186194 /// </summary>
187195 /// <param name="obj">Object to convert</param>
188196 /// <param name="defaultValue">Default value if no conversion is possible</param>
189197 /// <returns>DateTime in UTC or defaultValue if no conversion possible</returns>
190- public static DateTime ToDateTimeInvariant ( this object obj , bool isSourceObjUTC = true , DateTime defaultValue = default )
198+ public static DateTime ToDateTimeInvariant ( this object obj , SourceTimeZone sourceTimeZone = SourceTimeZone . UTC , DateTime defaultValue = default )
191199 {
192200 if ( obj == null )
193201 {
@@ -200,9 +208,20 @@ public static DateTime ToDateTimeInvariant(this object obj, bool isSourceObjUTC
200208 return defaultValue ;
201209 }
202210 DateTime dt = ( DateTime ) Convert . ChangeType ( jValue == null ? obj : jValue . Value , typeof ( DateTime ) , CultureInfo . InvariantCulture ) ;
203- if ( dt . Kind == DateTimeKind . Utc || isSourceObjUTC ) return dt ;
204- else return dt . ToUniversalTime ( ) ; // convert to UTC
205- }
211+ switch ( sourceTimeZone )
212+ {
213+ case SourceTimeZone . AsSpecified :
214+ throw new NotImplementedException ( ) ; // TODO: implement this when needed
215+ case SourceTimeZone . Local :
216+ return DateTime . SpecifyKind ( dt , DateTimeKind . Local ) . ToUniversalTime ( ) ; // convert to UTC
217+ case SourceTimeZone . Korea :
218+ return TimeZoneInfo . ConvertTime ( dt , koreaZone , TimeZoneInfo . Utc ) ; // convert to UTC
219+ case SourceTimeZone . UTC :
220+ return DateTime . SpecifyKind ( dt , DateTimeKind . Utc ) ;
221+ default :
222+ throw new NotImplementedException ( $ "Unexpected { nameof ( sourceTimeZone ) } : { sourceTimeZone } ") ;
223+ }
224+ }
206225
207226 /// <summary>
208227 /// Convert an object to another type using invariant culture. Consider using the string or DateTime conversions if you are dealing with those types.
@@ -698,10 +717,13 @@ public static DateTime ParseTimestamp(object value, TimestampType type)
698717 switch ( type )
699718 {
700719 case TimestampType . Iso8601Local :
701- return value . ToDateTimeInvariant ( false ) ;
720+ return value . ToDateTimeInvariant ( SourceTimeZone . Local ) ;
721+
722+ case TimestampType . Iso8601Korea :
723+ return value . ToDateTimeInvariant ( SourceTimeZone . Korea ) ;
702724
703725 case TimestampType . Iso8601UTC :
704- return value . ToDateTimeInvariant ( true ) ;
726+ return value . ToDateTimeInvariant ( SourceTimeZone . UTC ) ;
705727
706728 case TimestampType . UnixNanoseconds :
707729 return UnixTimeStampToDateTimeNanoseconds ( value . ConvertInvariant < long > ( ) ) ;
@@ -1481,13 +1503,18 @@ public enum TimestampType
14811503 UnixSeconds ,
14821504
14831505 /// <summary>
1484- /// ISO 8601 in UTC
1506+ /// ISO 8601 in local time
14851507 /// </summary>
1486- Iso8601UTC ,
1508+ Iso8601Local ,
14871509
14881510 /// <summary>
1489- /// ISO 8601 in local time
1511+ /// ISO 8601 in Korea Standard Time
14901512 /// </summary>
1491- Iso8601Local ,
1513+ Iso8601Korea ,
1514+
1515+ /// <summary>
1516+ /// ISO 8601 in UTC
1517+ /// </summary>
1518+ Iso8601UTC ,
14921519 }
14931520}
0 commit comments