in csharp/EPAM.Deltix.HdTime/Formatter.cs [854:957]
public static Boolean TryParseExact(String source, String format, IFormatProvider formatProvider, out HdDateTime result)
{
if (String.IsNullOrEmpty(source))
{
throw new ArgumentNullException("source", "source is null.");
}
if (String.IsNullOrEmpty(format))
{
throw new ArgumentNullException("format", "format is null.");
}
// we can parse from exactly 3 occurences of precise time format in format and source.
// if it will be more, we NotSupportedException will be thrown.
// ptf is PreciseTimeFormat
// pts is PreciseTimeSource
Int32 ptfPosition1, ptfCount1, ptsCount1;
Boolean isLowerCasePtf1;
// first occurence of precise time format and source
Boolean isPreciseTimeFormat = Formatter.FindAndReplacePreciseTimeFormat(format, out ptfPosition1, out ptfCount1, out isLowerCasePtf1);
if (!isPreciseTimeFormat)
{
DateTime dateTime;
Boolean isParsed = DateTime.TryParseExact(source, format, formatProvider, DateTimeStyles.None, out dateTime);
result = dateTime;
return isParsed;
}
// due to contract with DateTime ParseExact
// source of ticks (nanoseconds) must be the same in all of the occurences
// it means, that nanoseconds in the first occurence are the same as in other; otherwise FormatException will be thrown.
Byte ptfSource1;
Formatter.ExtractAndReplacePreciseTimeSource(ref source, ptfPosition1, ptfCount1, isLowerCasePtf1, out ptfSource1, out ptsCount1);
Int32 ptfPosition2, ptfCount2, ptsCount2 = 0, ptfPosition3 = 0, ptfCount3 = 0, ptsCount3 = 0;
Boolean isLowerCasePtf2, ptfExists2, isLowerCasePtf3 = false, ptfExists3 = false;
Byte ptfSource2 = 0, ptfSource3 = 0;
// second occurence of precise time format and source
ptfExists2 = Formatter.FindAndReplacePreciseTimeFormat(format, out ptfPosition2, out ptfCount2, out isLowerCasePtf2);
if (ptfExists2)
{ // add reverted offset, because of format != source in case of UpperCase letters.
Formatter.ExtractAndReplacePreciseTimeSource(ref source, ptfPosition2, ptfCount2, isLowerCasePtf2, out ptfSource2, out ptsCount2);
if (ptfSource1 != ptfSource2)
{
throw new FormatException("In multiple occurences of precise time format, precise time source is not identical in all of the cases.");
}
// third occurence of precise time format and source
ptfExists3 = Formatter.FindAndReplacePreciseTimeFormat(format, out ptfPosition3, out ptfCount3, out isLowerCasePtf3);
if (ptfExists3)
{
Formatter.ExtractAndReplacePreciseTimeSource(ref source, ptfPosition3, ptfCount3, isLowerCasePtf3, out ptfSource3, out ptsCount3);
if (ptfSource1 != ptfSource3)
{
throw new FormatException("In multiple occurences of precise time format, precise time source is not identical in all of the cases.");
}
}
// forth occurence of precise time format and source
Int32 ptfPosition4, ptfCount4;
Boolean isLowerCasePtf4, ptfExists4;
ptfExists4 = Formatter.FindAndReplacePreciseTimeFormat(format, out ptfPosition4, out ptfCount4, out isLowerCasePtf4);
if (ptfExists4)
{
throw new NotSupportedException("Parsing format with more than 3 occurences is not supported.");
}
}
// parse time
DateTime timestamp;
Boolean isTimestampParsed = false;
try
{
isTimestampParsed = DateTime.TryParseExact(source, format, formatProvider, DateTimeStyles.None, out timestamp);
result = new HdDateTime(timestamp, ptfSource1);
return isTimestampParsed;
}
finally
{
// rollback all replacements
// rollback first
Formatter.RollbackPreciseTimeSourceReplacement(source, ptfPosition1, ptsCount1, ptfSource1);
Formatter.RollbackPreciseTimeFormatReplacement(format, ptfPosition1, ptfCount1, isLowerCasePtf1);
// rollback second
if (ptfExists2)
{
Formatter.RollbackPreciseTimeSourceReplacement(source, ptfPosition2, ptsCount2, ptfSource2);
Formatter.RollbackPreciseTimeFormatReplacement(format, ptfPosition2, ptfCount2, isLowerCasePtf2);
// rollback third
if (ptfExists3)
{
Formatter.RollbackPreciseTimeSourceReplacement(source, ptfPosition3, ptsCount3, ptfSource3);
Formatter.RollbackPreciseTimeFormatReplacement(format, ptfPosition3, ptfCount3,
isLowerCasePtf3);
}
}
}
}