public static Boolean TryParseExact()

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);
					}
				}
			}
		}