Skip to content

Instantly share code, notes, and snippets.

@mstum
Created September 16, 2016 23:52
Show Gist options
  • Save mstum/6258481fae8bcce582b5c116a1bb36b4 to your computer and use it in GitHub Desktop.
Save mstum/6258481fae8bcce582b5c116a1bb36b4 to your computer and use it in GitHub Desktop.
using System;
namespace mstum.utils
{
/// <summary>
/// A Date type for .net, essentially a <see cref="DateTime" /> without the time portion.
/// </summary>
/// <remarks>
/// If using Dapper, use this to map directly to a Date column in SQL Server:
/// <code>SqlMapper.AddTypeMap(typeof(Date), DbType.Date);</code>
/// </remarks>
public struct Date : IComparable, IFormattable, IComparable<Date>, IEquatable<Date>, IConvertible
{
public static Date FromDateTime(DateTime dt)
{
return new Date(dt.Year, dt.Month, dt.Day);
}
public static Date Now => FromDateTime(DateTime.Now);
private readonly DateTime _backingDateTime;
public int Year => _backingDateTime.Year;
public int Month => _backingDateTime.Month;
public int Day => _backingDateTime.Day;
public DayOfWeek DayOfWeek => _backingDateTime.DayOfWeek;
public bool IsLastDayOfTheMonth { get; }
/// <summary>
/// Return this <see cref="Date"/> as a string in MM/dd/yyyy format.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return $"{Month:D2}/{Day:D2}/{Year}";
}
public Date(int year, int month, int day)
{
_backingDateTime = new DateTime(year, month, day);
var nextDay = _backingDateTime.AddDays(1);
IsLastDayOfTheMonth = (nextDay.Month != month);
}
public Date AddDays(int days)
{
var newDate = _backingDateTime.AddDays(days);
return FromDateTime(newDate);
}
public Date AddMonths(int months)
{
var newDate = _backingDateTime.AddMonths(months);
return FromDateTime(newDate);
}
public Date AddYears(int years)
{
var newDate = _backingDateTime.AddYears(years);
return FromDateTime(newDate);
}
public DateTime ToDateTime()
{
return new DateTime(Year, Month, Day);
}
public int CompareTo(Date other)
{
return _backingDateTime.CompareTo(other._backingDateTime);
}
public bool Equals(Date other)
{
return _backingDateTime.Equals(other._backingDateTime);
}
public override bool Equals(object obj)
{
if (obj is Date)
{
return _backingDateTime.Equals(((Date) obj)._backingDateTime);
}
return false;
}
public override int GetHashCode()
{
return _backingDateTime.GetHashCode();
}
public string ToString(string format, IFormatProvider formatProvider)
{
return _backingDateTime.ToString(format, formatProvider);
}
public int CompareTo(object obj)
{
if (obj == null) return 1;
if (!(obj is Date))
{
throw new ArgumentException(nameof(obj) + " must be a Date", nameof(obj));
}
return _backingDateTime.CompareTo(((Date) obj)._backingDateTime);
}
public static explicit operator DateTime(Date d)
{
return d.ToDateTime();
}
public static explicit operator Date(DateTime d)
{
return FromDateTime(d);
}
public static bool operator ==(Date lhs, Date rhs)
{
return lhs.Equals(rhs);
}
public static bool operator !=(Date lhs, Date rhs)
{
return !lhs.Equals(rhs);
}
public static bool operator >(Date lhs, Date rhs)
{
return lhs._backingDateTime.Ticks > rhs._backingDateTime.Ticks;
}
public static bool operator <(Date lhs, Date rhs)
{
return lhs._backingDateTime.Ticks < rhs._backingDateTime.Ticks;
}
public static bool operator >=(Date lhs, Date rhs)
{
return lhs._backingDateTime.Ticks >= rhs._backingDateTime.Ticks;
}
public static bool operator <=(Date lhs, Date rhs)
{
return lhs._backingDateTime.Ticks <= rhs._backingDateTime.Ticks;
}
TypeCode IConvertible.GetTypeCode()
{
return _backingDateTime.GetTypeCode();
}
bool IConvertible.ToBoolean(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToBoolean(provider);
}
char IConvertible.ToChar(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToChar(provider);
}
sbyte IConvertible.ToSByte(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToSByte(provider);
}
byte IConvertible.ToByte(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToByte(provider);
}
short IConvertible.ToInt16(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToInt16(provider);
}
ushort IConvertible.ToUInt16(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToUInt16(provider);
}
int IConvertible.ToInt32(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToInt32(provider);
}
uint IConvertible.ToUInt32(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToUInt32(provider);
}
long IConvertible.ToInt64(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToInt64(provider);
}
ulong IConvertible.ToUInt64(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToUInt64(provider);
}
float IConvertible.ToSingle(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToSingle(provider);
}
double IConvertible.ToDouble(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToDouble(provider);
}
decimal IConvertible.ToDecimal(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToDecimal(provider);
}
DateTime IConvertible.ToDateTime(IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToDateTime(provider);
}
string IConvertible.ToString(IFormatProvider provider)
{
return _backingDateTime.ToString(provider);
}
object IConvertible.ToType(Type conversionType, IFormatProvider provider)
{
return ((IConvertible) _backingDateTime).ToType(conversionType, provider);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment