| File: System\ComponentModel\DateTimeOffsetConverter.cs | Web Access |
| Project: src\runtime\src\libraries\System.ComponentModel.TypeConverter\src\System.ComponentModel.TypeConverter.csproj (System.ComponentModel.TypeConverter) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.ComponentModel.Design.Serialization; using System.Diagnostics.CodeAnalysis; using System.Globalization; namespace System.ComponentModel { /// <summary> /// Provides a type converter to convert <see cref='System.DateTimeOffset'/> /// objects to and from various other representations. /// </summary> public class DateTimeOffsetConverter : TypeConverter { /// <summary> /// Gets a value indicating whether this converter can convert an /// object in the given source type to a <see cref='System.DateTimeOffset'/> /// object using the specified context. /// </summary> public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } /// <summary> /// Gets a value indicating whether this converter can convert an /// object to the given destination type using the context. /// </summary> public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen(true)] Type? destinationType) { return destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType); } /// <summary> /// Converts the given value object to a <see cref='System.DateTime'/> /// object. /// </summary> public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { if (value is string text) { text = text.Trim(); if (text.Length == 0) { return DateTimeOffset.MinValue; } try { // See if we have a culture info to parse with. If so, then use it. DateTimeFormatInfo? formatInfo = null; if (culture != null) { formatInfo = (DateTimeFormatInfo?)culture.GetFormat(typeof(DateTimeFormatInfo)); } if (formatInfo != null) { return DateTimeOffset.Parse(text, formatInfo); } else { return DateTimeOffset.Parse(text, culture); } } catch (FormatException e) { throw new FormatException(SR.Format(SR.ConvertInvalidPrimitive, (string)value, nameof(DateTimeOffset)), e); } } return base.ConvertFrom(context, culture, value); } /// <summary> /// Converts the given value object to a <see cref='System.DateTimeOffset'/> /// object using the arguments. /// </summary> public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) { // logic is exactly as in DateTimeConverter, only the offset pattern ' zzz' is added to the default // ConvertToString pattern. if (destinationType == typeof(string) && value is DateTimeOffset) { DateTimeOffset dto = (DateTimeOffset)value; if (dto == DateTimeOffset.MinValue) { return string.Empty; } culture ??= CultureInfo.CurrentCulture; DateTimeFormatInfo? formatInfo; formatInfo = (DateTimeFormatInfo?)culture.GetFormat(typeof(DateTimeFormatInfo)); string format; if (culture == CultureInfo.InvariantCulture) { // note: the y/m/d format used when there is or isn't a time component is not consistent // when the culture is invariant, because for some reason InvariantCulture's date format is // MM/dd/yyyy. However, this matches the behavior of DateTimeConverter so it is preserved here. if (dto.TimeOfDay.TotalSeconds == 0) { // pattern just like DateTimeConverter when DateTime.TimeOfDay.TotalSeconds==0 // but with ' zzz' offset pattern added. return dto.ToString("yyyy-MM-dd zzz", culture); } else { return dto.ToString(culture); } } if (dto.TimeOfDay.TotalSeconds == 0) { // pattern just like DateTimeConverter when DateTime.TimeOfDay.TotalSeconds==0 // but with ' zzz' offset pattern added. format = formatInfo!.ShortDatePattern + " zzz"; } else { // pattern just like DateTimeConverter when DateTime.TimeOfDay.TotalSeconds!=0 // but with ' zzz' offset pattern added. format = formatInfo!.ShortDatePattern + " " + formatInfo.ShortTimePattern + " zzz"; } return dto.ToString(format, culture); } if (destinationType == typeof(InstanceDescriptor) && value is DateTimeOffset) { DateTimeOffset dto = (DateTimeOffset)value; if (dto.Ticks == 0) { // Special case for empty DateTimeOffset return new InstanceDescriptor( typeof(DateTimeOffset).GetConstructor(new Type[] { typeof(long) }), new object[] { dto.Ticks } ); } return new InstanceDescriptor( typeof(DateTimeOffset).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(TimeSpan) }), new object[] { dto.Year, dto.Month, dto.Day, dto.Hour, dto.Minute, dto.Second, dto.Millisecond, dto.Offset } ); } return base.ConvertTo(context, culture, value, destinationType); } } }