diff --git a/Core/InteropServices/time_t.cs b/Core/InteropServices/time_t.cs new file mode 100644 index 00000000..6e810ca4 --- /dev/null +++ b/Core/InteropServices/time_t.cs @@ -0,0 +1,203 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace Vanara.PInvoke +{ + /// Managed instance of the time_t type. + [StructLayout(LayoutKind.Sequential), Serializable] + [TypeConverter(typeof(time_tTypeConverter))] +#pragma warning disable IDE1006 // Naming Styles + public struct time_t : IEquatable, IComparable, IEquatable, IComparable, IConvertible, IComparable +#pragma warning restore IDE1006 // Naming Styles + { + private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local); + + private readonly long val; + + /// Initializes a new instance of the struct. + /// + /// The number of seconds since the start of the epoch: midnight UTC of January 1, 1970 (not counting leap seconds). + /// + public time_t(long ticks) => val = ticks; + + /// Initializes a new instance of the struct. + /// The date. + public time_t(DateTime dateTime) => val = (long)(dateTime.ToLocalTime() - epoch).TotalSeconds; + + /// + /// Represents the largest possible value of . This property is determined by the maximum bit-size of a pointer. + /// + public static readonly time_t MaxValue = (time_t)long.MaxValue; + + /// Represents the smallest possible value of . This field is constant. + public static readonly time_t MinValue = (time_t)long.MinValue; + + /// Represents the zero value of . This field is constant. + public static readonly time_t Zero = default; + + /// Gets the value. + /// The value. + public DateTime Value => epoch.AddSeconds(val); + + /// Performs an explicit conversion from to . + /// The value. + /// The result of the conversion. + public static explicit operator time_t(long value) => new time_t(value); + + /// Performs an explicit conversion from to . + /// The value. + /// The result of the conversion. + public static explicit operator long(time_t value) => value.val; + + /// Performs an implicit conversion from to . + /// The value. + /// The resulting instance from the conversion. + public static implicit operator time_t(DateTime value) => new time_t(value); + + /// Performs an implicit conversion from to . + /// The value. + /// The resulting instance from the conversion. + public static implicit operator DateTime(time_t value) => value.Value; + + /// Indicates whether two instances are not equal. + /// The first integral size to compare. + /// The second integral size to compare. + /// + /// if the value of is not equal to the value of ; otherwise, . + /// + public static bool operator !=(time_t s1, time_t s2) => !s1.Equals(s2); + + /// Indicates whether a specified is less than another specified . + /// The first integral size to compare. + /// The second integral size to compare. + /// + /// if the value of is less than the value of ; otherwise, . + /// + public static bool operator <(time_t s1, time_t s2) => (s1.CompareTo(s2) < 0); + + /// Indicates whether a specified is less than or equal to another specified . + /// The first integral size to compare. + /// The second integral size to compare. + /// + /// if the value of is less than or equal to the value of ; + /// otherwise, . + /// + public static bool operator <=(time_t s1, time_t s2) => (s1.CompareTo(s2) <= 0); + + /// Indicates whether two instances are equal. + /// The first integral size to compare. + /// The second integral size to compare. + /// + /// if the value of is equal to the value of ; otherwise, . + /// + public static bool operator ==(time_t s1, time_t s2) => s1.Equals(s2); + + /// Indicates whether a specified is greater than another specified . + /// The first integral size to compare. + /// The second integral size to compare. + /// + /// if the value of is greater than the value of ; otherwise, . + /// + public static bool operator >(time_t s1, time_t s2) => (s1.CompareTo(s2) > 0); + + /// Indicates whether a specified is greater than or equal to another specified . + /// The first integral size to compare. + /// The second integral size to compare. + /// + /// if the value of is greater than or equal to the value of ; + /// otherwise, . + /// + public static bool operator >=(time_t s1, time_t s2) => (s1.CompareTo(s2) >= 0); + + /// + public int CompareTo(time_t other) => val.CompareTo(other.val); + + /// + public int CompareTo(DateTime other) => Value.CompareTo(other); + + /// + public override bool Equals(object obj) => obj is time_t s ? Equals(s) : Value.Equals(obj); + + /// + public bool Equals(time_t other) => val.Equals(other.val); + + /// + public bool Equals(DateTime other) => Value.Equals(other); + + /// + public override int GetHashCode() => val.GetHashCode(); + + /// + public TypeCode GetTypeCode() => val.GetTypeCode(); + + /// + public override string ToString() => ToString(null); + + /// + public string ToString(IFormatProvider provider) => Value.ToString(provider); + + /// + int IComparable.CompareTo(object obj) => Value.CompareTo(Convert.ChangeType(obj, typeof(DateTime))); + + /// + bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider); + + /// + byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider); + + /// + char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider); + + /// + DateTime IConvertible.ToDateTime(IFormatProvider provider) => Value; + + /// + decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider); + + /// + double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)Value).ToDouble(provider); + + /// + short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider); + + /// + int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider); + + /// + long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider); + + /// + sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider); + + /// + float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider); + + /// + object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToType(conversionType, provider); + + /// + ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider); + + /// + uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider); + + /// + ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider); + +#pragma warning disable IDE1006 // Naming Styles + internal class time_tTypeConverter : DateTimeConverter +#pragma warning restore IDE1006 // Naming Styles + { + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (value is not time_t sz) throw new ArgumentException(); + return base.ConvertTo(context, culture, sz.Value, destinationType); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) => + new time_t((DateTime)base.ConvertFrom(context, culture, value)); + } + } +} \ No newline at end of file