|
using System;
using System.Globalization;
namespace System.Management
{
/// <summary>
/// <para> Provides methods to convert DMTF datetime and time interval to CLR compliant
/// <see cref='System.DateTime'/> and <see cref='System.TimeSpan'/> format and vice versa.
/// </para>
/// </summary>
/// <example>
/// <code lang='C#'>
/// using System;
/// using System.Management;
///
/// // The sample below demonstrates the various conversions that can be done using ManagementDateTimeConverter class
/// class Sample_ManagementDateTimeConverterClass
/// {
/// public static int Main(string[] args)
/// {
/// string dmtfDate = "20020408141835.999999-420";
/// string dmtfTimeInterval = "00000010122532:123456:000";
///
/// // Converting DMTF datetime to System.DateTime
/// DateTime dt = ManagementDateTimeConverter.ToDateTime(dmtfDate);
///
/// // Converting System.DateTime to DMTF datetime
/// string dmtfDate = ManagementDateTimeConverter.ToDateTime(DateTime.Now);
///
/// // Converting DMTF timeinterval to System.TimeSpan
/// System.TimeSpan tsRet = ManagementDateTimeConverter. ToTimeSpan(dmtfTimeInterval);
///
/// //Converting System.TimeSpan to DMTF time interval format
/// System.TimeSpan ts = new System.TimeSpan(10,12,25,32,456);
/// string dmtfTimeInt = ManagementDateTimeConverter.ToDmtfTimeInterval(ts);
///
/// return 0;
///
/// }
/// }
/// </code>
/// <code lang='VB'>
/// Imports System
/// Imports System.Management
///
/// 'The sample below demonstrates the various conversions that can be done using ManagementDateTimeConverter class
/// Class Sample_ManagementClass
/// Overloads Public Shared Function Main(args() As String) As Integer
/// Dim dmtfDate As String = "20020408141835.999999-420"
/// Dim dmtfTimeInterval As String = "00000010122532:123456:000"
///
/// 'Converting DMTF datetime and intervals to System.DateTime
/// Dim dt As DateTime = ManagementDateTimeConverter.ToDateTime(dmtfDate)
///
/// 'Converting System.DateTime to DMTF datetime
/// dmtfDate = ManagementDateTimeConverter.ToDateTime(DateTime.Now)
///
/// ' Converting DMTF timeinterval to System.TimeSpan
/// Dim tsRet As System.TimeSpan = ManagementDateTimeConverter.ToTimeSpan(dmtfTimeInterval)
///
/// 'Converting System.TimeSpan to DMTF time interval format
/// Dim ts As System.TimeSpan = New System.TimeSpan(10, 12, 25, 32, 456)
/// String dmtfTimeInt = ManagementDateTimeConverter.ToDmtfTimeInterval(ts)
///
/// Return 0
/// End Function
/// End Class
///
/// </code>
/// </example>
public sealed class ManagementDateTimeConverter
{
// constants
private const int SIZEOFDMTFDATETIME = 25;
private const int MAXSIZE_UTC_DMTF = 999;
private const long MAXDATE_INTIMESPAN = 99999999;
private ManagementDateTimeConverter()
{
}
/// <summary>
/// <para>Converts a given DMTF datetime to <see cref='System.DateTime'/> object. The returned DateTime will be in the
/// current TimeZone of the system.</para>
/// </summary>
/// <param name='dmtfDate'>A string representing the datetime in DMTF format.</param>
/// <returns>
/// <para>A <see cref='System.DateTime'/> object that represents the given DMTF datetime.</para>
/// </returns>
/// <remarks>
/// <para> Date and time in WMI is represented in DMTF datetime format. This format is explained in WMI SDK documentation.
/// DMTF datetime string has an UTC offset which this datetime string represents.
/// During conversion to <see cref='System.DateTime'/>, UTC offset is used to convert the date to the
/// current timezone. According to DMTF format a particular field can be represented by the character
/// '*'. This will be converted to the MinValue of this field that can be represented in <see cref='System.DateTime'/>.
/// </para>
/// </remarks>
/// <example>
/// <code lang='C#'>
/// // Convert a DMTF datetime to System.DateTime
/// DateTime date = ManagementDateTimeConverter.ToDateTime("20020408141835.999999-420");
/// </code>
/// <code lang='VB'>
/// ' Convert a DMTF datetime to System.DateTime
/// Dim date as DateTime = ManagementDateTimeConverter.ToDateTime("20020408141835.999999-420")
/// </code>
/// </example>
public static DateTime ToDateTime(string dmtfDate)
{
int year = DateTime.MinValue.Year;
int month = DateTime.MinValue.Month;
int day = DateTime.MinValue.Day;
int hour = DateTime.MinValue.Hour;
int minute = DateTime.MinValue.Minute;
int second = DateTime.MinValue.Second;
int millisec = 0;
string dmtf = dmtfDate;
DateTime datetime = DateTime.MinValue;
// If the string passed is empty or null then throw
// an exception
if(dmtf == null)
{
throw new System.ArgumentOutOfRangeException("dmtfDate");
}
if (dmtf.Length == 0)
{
throw new System.ArgumentOutOfRangeException("dmtfDate");
}
// if the length of the string is not equal to the
// standard length of the DMTF datetime then throw an exception
if(dmtf.Length != SIZEOFDMTFDATETIME)
{
throw new System.ArgumentOutOfRangeException("dmtfDate");
}
IFormatProvider frmInt32 = (IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int32));
System.Int64 ticks = 0;
try
{
string tempString = System.String.Empty;
tempString = dmtf.Substring(0, 4);
if (("****" != tempString))
{
year = System.Int32.Parse(tempString,frmInt32);
}
tempString = dmtf.Substring(4, 2);
if (("**" != tempString))
{
month = System.Int32.Parse(tempString,frmInt32);
}
tempString = dmtf.Substring(6, 2);
if (("**" != tempString))
{
day = System.Int32.Parse(tempString,frmInt32);
}
tempString = dmtf.Substring(8, 2);
if (("**" != tempString))
{
hour = System.Int32.Parse(tempString,frmInt32);
}
tempString = dmtf.Substring(10, 2);
if (("**" != tempString))
{
minute = System.Int32.Parse(tempString,frmInt32);
}
tempString = dmtf.Substring(12, 2);
if (("**" != tempString))
{
second = System.Int32.Parse(tempString,frmInt32);
}
tempString = dmtf.Substring(15, 6);
if (("******" != tempString))
{
ticks = (System.Int64.Parse(tempString,(IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int64)))) * (System.TimeSpan.TicksPerMillisecond/1000);
}
if( year < 0 || month < 0 || day < 0 || hour < 0 || minute < 0 || second < 0 || ticks < 0)
{
throw new System.ArgumentOutOfRangeException("dmtfDate");
}
}
catch
{
throw new System.ArgumentOutOfRangeException("dmtfDate");
}
// Construct a new System.DateTime object
datetime = new System.DateTime(year, month, day, hour, minute, second, millisec);
// Then add the ticks calculated from the microseconds
datetime = datetime.AddTicks(ticks);
// Adjust the UTC time to reflect the current zone time
System.TimeZone curZone = System.TimeZone.CurrentTimeZone;
System.TimeSpan tickOffset = curZone.GetUtcOffset(datetime);
long OffsetMins = tickOffset.Ticks / System.TimeSpan.TicksPerMinute;
// Adjusting the DateTime for the current UTC
int UTCOffset = 0;
string tempString1 = dmtf.Substring(22, 3);
long OffsetToBeAdjusted = 0;
if (("***" != tempString1))
{
tempString1 = dmtf.Substring(21, 4);
try
{
UTCOffset = System.Int32.Parse(tempString1,frmInt32);
}
catch
{
throw new System.ArgumentOutOfRangeException();
}
OffsetToBeAdjusted = UTCOffset-OffsetMins;
// We have to substract the minutes from the time
datetime = datetime.AddMinutes(OffsetToBeAdjusted * -1);
}
return datetime;
}
/// <summary>
/// <para>Converts a given <see cref='System.DateTime'/> object to DMTF format.</para>
///
/// </summary>
/// <param name='date'>A <see cref='System.DateTime'/> object representing the datetime to be converted to DMTF datetime.</param>
/// <returns>
/// <para>A string that represents the DMTF datetime for the given DateTime object.</para>
/// </returns>
/// <remarks>
/// <para> Date and time in WMI is represented in DMTF datetime format. This format is explained in WMI SDK documentation.
/// The DMTF datetime string represented will be with respect to the UTC offset of the
/// current timezone. The lowest precision in DMTF is microseconds and
/// in <see cref='System.DateTime'/> is Ticks , which is equivalent to 100 of nanoseconds.
/// During conversion these Ticks are converted to microseconds and rounded
/// off to the the nearest microsecond.
/// </para>
/// </remarks>
/// <example>
/// <code lang='C#'>
/// // Convert the current time in System.DateTime to DMTF format
/// string dmtfDateTime = ManagementDateTimeConverter.ToDmtfDateTime(DateTime.Now);
/// </code>
/// <code lang='VB'>
/// ' Convert the current time in System.DateTime to DMTF format
/// Dim dmtfDateTime as String = ManagementDateTimeConverter.ToDmtfDateTime(DateTime.Now)
/// </code>
/// </example>
public static string ToDmtfDateTime(DateTime date)
{
string UtcString = String.Empty;
// Fill up the UTC field in the DMTF date with the current
// zones UTC value
System.TimeZone curZone = System.TimeZone.CurrentTimeZone;
System.TimeSpan tickOffset = curZone.GetUtcOffset(date);
long OffsetMins = (tickOffset.Ticks / System.TimeSpan.TicksPerMinute);
IFormatProvider frmInt32 = (IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int32));
// If the offset is more than that what can be specified in DMTF format, then
// convert the date to UniversalTime
if(Math.Abs(OffsetMins) > MAXSIZE_UTC_DMTF)
{
date = date.ToUniversalTime();
UtcString = "+000";
}
else
if ((tickOffset.Ticks >= 0))
{
UtcString = "+" + ((tickOffset.Ticks / System.TimeSpan.TicksPerMinute)).ToString(frmInt32).PadLeft(3,'0');
}
else
{
string strTemp = OffsetMins.ToString(frmInt32);
UtcString = "-" + strTemp.Substring(1, strTemp.Length-1).PadLeft(3,'0');
}
string dmtfDateTime = date.Year.ToString(frmInt32).PadLeft(4,'0');
dmtfDateTime = (dmtfDateTime + date.Month.ToString(frmInt32).PadLeft(2, '0'));
dmtfDateTime = (dmtfDateTime + date.Day.ToString(frmInt32).PadLeft(2, '0'));
dmtfDateTime = (dmtfDateTime + date.Hour.ToString(frmInt32).PadLeft(2, '0'));
dmtfDateTime = (dmtfDateTime + date.Minute.ToString(frmInt32).PadLeft(2, '0'));
dmtfDateTime = (dmtfDateTime + date.Second.ToString(frmInt32).PadLeft(2, '0'));
dmtfDateTime = (dmtfDateTime + ".");
// Construct a DateTime with with the precision to Second as same as the passed DateTime and so get
// the ticks difference so that the microseconds can be calculated
DateTime dtTemp = new DateTime(date.Year ,date.Month,date.Day ,date.Hour ,date.Minute ,date.Second,0);
System.Int64 microsec = ((date.Ticks-dtTemp.Ticks) * 1000) / System.TimeSpan.TicksPerMillisecond;
// fill the microseconds field
String strMicrosec = microsec.ToString((IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int64)));
if(strMicrosec.Length > 6)
{
strMicrosec = strMicrosec.Substring(0,6);
}
dmtfDateTime = dmtfDateTime + strMicrosec.PadLeft(6,'0');
// adding the UTC offset
dmtfDateTime = dmtfDateTime + UtcString;
return dmtfDateTime;
}
/// <summary>
/// <para>Converts a given DMTF time interval to <see cref='System.TimeSpan'/> object.</para>
/// </summary>
/// <param name='dmtfTimespan'>A string represesentation of the DMTF time interval.</param>
/// <returns>
/// <para>A <see cref='System.TimeSpan'/> object that represents the given DMTF time interval.</para>
/// </returns>
/// <remarks>
/// <para> Time interval in WMI is represented in DMTF format. This format is explained in WMI SDK documentation.
/// If the DMTF time interval value is more than that of
/// <see cref='System.TimeSpan.MaxValue'/> then <see cref='System.ArgumentOutOfRangeException'/> is thrown.
/// </para>
/// </remarks>
/// <example>
/// <code lang='C#'>
/// // Convert a DMTF time interval to System.TimeSpan
/// TimeSpan dmtfTimeInterval = ManagementDateTimeConverter.ToTimeSpan("00000010122532:123456:000");
/// </code>
/// <code lang='VB'>
/// ' Convert a DMTF time interval to System.TimeSpan
/// Dim ts as TimeSpan = ManagementDateTimeConverter.ToTimeSpan("00000010122532:123456:000")
/// </code>
/// </example>
public static TimeSpan ToTimeSpan(string dmtfTimespan)
{
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
IFormatProvider frmInt32 = (IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int32));
string dmtfts = dmtfTimespan;
TimeSpan timespan = TimeSpan.MinValue;
if (dmtfts == null)
{
throw new System.ArgumentOutOfRangeException("dmtfTimespan");
}
if (dmtfts.Length == 0)
{
throw new System.ArgumentOutOfRangeException("dmtfTimespan");
}
if(dmtfts.Length != SIZEOFDMTFDATETIME)
{
throw new System.ArgumentOutOfRangeException("dmtfTimespan");
}
if(dmtfts.Substring(21,4) != ":000")
{
throw new System.ArgumentOutOfRangeException("dmtfTimespan");
}
System.Int64 ticks = 0;
try
{
string tempString = System.String.Empty;
tempString = dmtfts.Substring(0, 8);
days = System.Int32.Parse(tempString,frmInt32);
tempString = dmtfts.Substring(8, 2);
hours = System.Int32.Parse(tempString,frmInt32);
tempString = dmtfts.Substring(10, 2);
minutes = System.Int32.Parse(tempString,frmInt32);
tempString = dmtfts.Substring(12, 2);
seconds = System.Int32.Parse(tempString,frmInt32);
tempString = dmtfts.Substring(15, 6);
ticks = (System.Int64.Parse(tempString,(IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int64)))) * (System.TimeSpan.TicksPerMillisecond/1000);
}
catch
{
throw new System.ArgumentOutOfRangeException("dmtfTimespan");
}
if( days < 0 || hours < 0 || minutes < 0 || seconds < 0 || ticks < 0 )
{
throw new System.ArgumentOutOfRangeException("dmtfTimespan");
}
timespan = new System.TimeSpan(days, hours, minutes, seconds, 0);
// Get a timepan for the additional ticks obtained for the microsecond part of DMTF time interval
// and then add it to the the original timespan
TimeSpan tsTemp = System.TimeSpan.FromTicks(ticks);
timespan = timespan + tsTemp;
return timespan;
}
/// <summary>
/// <para>Converts a given <see cref='System.TimeSpan'/> object to DMTF time interval.</para>
/// </summary>
/// <param name='timespan'> A <see cref='System.TimeSpan'/> object representing the datetime to be converted to DMTF time interval.
/// </param>
/// <returns>
/// <para>A string that represents the DMTF time interval for the given TimeSpan object.</para>
/// </returns>
/// <remarks>
/// <para> Time interval in WMI is represented in DMTF datetime format. This format
/// is explained in WMI SDK documentation. The lowest precision in
/// DMTF is microseconds and in <see cref='System.TimeSpan'/> is Ticks , which is equivalent
/// to 100 of nanoseconds.During conversion these Ticks are converted to
/// microseconds and rounded off to the the nearest microsecond.
/// </para>
/// </remarks>
/// <example>
/// <code lang='C#'>
/// // Construct a Timespan object and convert it to DMTF format
/// System.TimeSpan ts = new System.TimeSpan(10,12,25,32,456);
/// String dmtfTimeInterval = ManagementDateTimeConverter.ToDmtfTimeInterval(ts);
/// </code>
/// <code lang='VB'>
/// // Construct a Timespan object and convert it to DMTF format
/// Dim ts as System.TimeSpan = new System.TimeSpan(10,12,25,32,456)
/// Dim dmtfTimeInterval as String = ManagementDateTimeConverter.ToDmtfTimeInterval(ts)
/// </code>
/// </example>
public static string ToDmtfTimeInterval(TimeSpan timespan)
{
string dmtftimespan = timespan.Days.ToString((IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int32))).PadLeft(8,'0');
IFormatProvider frmInt32 = (IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int32));
// Days that can be represented is more than what can be represented
// then throw an exception
// and also negative timespan cannot be represented in DMTF
if(timespan.Days > MAXDATE_INTIMESPAN || timespan < TimeSpan.Zero)
{
throw new System.ArgumentOutOfRangeException();
}
dmtftimespan = (dmtftimespan + timespan.Hours.ToString(frmInt32).PadLeft(2, '0'));
dmtftimespan = (dmtftimespan + timespan.Minutes.ToString(frmInt32).PadLeft(2, '0'));
dmtftimespan = (dmtftimespan + timespan.Seconds.ToString(frmInt32).PadLeft(2, '0'));
dmtftimespan = (dmtftimespan + ".");
// Construct a DateTime with with the precision to Second as same as the passed DateTime and so get
// the ticks difference so that the microseconds can be calculated
TimeSpan tsTemp = new TimeSpan(timespan.Days ,timespan.Hours,timespan.Minutes ,timespan.Seconds ,0);
System.Int64 microsec = ((timespan.Ticks-tsTemp.Ticks) * 1000) / System.TimeSpan.TicksPerMillisecond;
// fill the microseconds field
String strMicrosec = microsec.ToString((IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(System.Int64)));
if(strMicrosec.Length > 6)
{
strMicrosec = strMicrosec.Substring(0,6);
}
dmtftimespan = dmtftimespan + strMicrosec.PadLeft(6,'0');
dmtftimespan = dmtftimespan + ":000";
return dmtftimespan;
}
} // ManagementDateTimeConverter
}
|