public string GetTimestamp(int length, TimestampResolution resolution = TimestampResolution.Microsecond, DateTime? sinceUtc = null, bool strict = false)
{
if (length < 1 || length > 12)
throw new ArgumentOutOfRangeException(nameof(length), "Length must be between 1 and 12; 36^13 overflows Int64.MaxValue");
var origin = sinceUtc ?? _epoch;
var elapsed = DateTime.UtcNow.Subtract(origin);
long intervals;
switch (resolution)
{
case TimestampResolution.Day:
intervals = elapsed.Days;
break;
case TimestampResolution.Hour:
intervals = Convert.ToInt64(elapsed.TotalHours);
break;
case TimestampResolution.Minute:
intervals = Convert.ToInt64(elapsed.TotalMinutes);
break;
case TimestampResolution.Second:
intervals = Convert.ToInt64(elapsed.TotalSeconds);
break;
case TimestampResolution.Millisecond:
intervals = Convert.ToInt64(elapsed.TotalMilliseconds);
break;
case TimestampResolution.Microsecond:
intervals = (long)(elapsed.TotalMilliseconds * 1000.0); // elapsed.TotalMicroseconds();
break;
case TimestampResolution.Ticks:
intervals = elapsed.Ticks;
break;
case TimestampResolution.None:
default:
throw new ArgumentOutOfRangeException(nameof(resolution));
}
var combinations = Math.Pow(36, length);
if (combinations < intervals)
{
if (strict)
{
throw new OverflowException(string.Format("At resolution {0}, value is greater than {1}-character timestamps can express.", resolution.ToString(), length));
}
intervals = intervals % 36;
}
string encoded = Base36Converter.FromLong(intervals);
return encoded.Length > length ?
encoded.Substring(0, length) :
encoded.PadLeft(length, '0');
}