/// <param name="iso8601String"> a date string that is ISO 8601 conform. </param> /// <param name="binValue"> an existing XMPDateTime to set with the parsed date </param> /// <returns> Returns an XMPDateTime-object containing the ISO8601-date. </returns> /// <exception cref="XmpException"> Is thrown when the string is non-conform. </exception> public static IXmpDateTime Parse(string iso8601String, IXmpDateTime binValue) { if (iso8601String == null) { throw new XmpException("Parameter must not be null", XmpError.BADPARAM); } if (iso8601String.Length == 0) { return binValue; } ParseState input = new ParseState(iso8601String); if (input.Ch(0) == '-') { input.Skip(); } // Extract the year. int value = input.GatherInt("Invalid year in date string", 9999); if (input.HasNext() && input.Ch() != '-') { throw new XmpException("Invalid date string, after year", XmpError.BADVALUE); } if (input.Ch(0) == '-') { value = -value; } binValue.Year = value; if (!input.HasNext()) { return binValue; } input.Skip(); // Extract the month. value = input.GatherInt("Invalid month in date string", 12); if (input.HasNext() && input.Ch() != '-') { throw new XmpException("Invalid date string, after month", XmpError.BADVALUE); } binValue.Month = value; if (!input.HasNext()) { return binValue; } input.Skip(); // Extract the day. value = input.GatherInt("Invalid day in date string", 31); if (input.HasNext() && input.Ch() != 'T') { throw new XmpException("Invalid date string, after day", XmpError.BADVALUE); } binValue.Day = value; if (!input.HasNext()) { return binValue; } input.Skip(); // Extract the hour. value = input.GatherInt("Invalid hour in date string", 23); binValue.Hour = value; if (!input.HasNext()) { return binValue; } // Extract the minute. if (input.Ch() == ':') { input.Skip(); value = input.GatherInt("Invalid minute in date string", 59); if (input.HasNext() && input.Ch() != ':' && input.Ch() != 'Z' && input.Ch() != '+' && input.Ch() != '-') { throw new XmpException("Invalid date string, after minute", XmpError.BADVALUE); } binValue.Minute = value; } if (!input.HasNext()) { return binValue; } if (input.HasNext() && input.Ch() == ':') { input.Skip(); value = input.GatherInt("Invalid whole seconds in date string", 59); if (input.HasNext() && input.Ch() != '.' && input.Ch() != 'Z' && input.Ch() != '+' && input.Ch() != '-') { throw new XmpException("Invalid date string, after whole seconds", XmpError.BADVALUE); } binValue.Second = value; if (input.Ch() == '.') { input.Skip(); int digits = input.Pos(); value = input.GatherInt("Invalid fractional seconds in date string", 999999999); if (input.HasNext() && (input.Ch() != 'Z' && input.Ch() != '+' && input.Ch() != '-')) { throw new XmpException("Invalid date string, after fractional second", XmpError.BADVALUE); } digits = input.Pos() - digits; for (; digits > 9; --digits) { value = value/10; } for (; digits < 9; ++digits) { value = value*10; } binValue.NanoSecond = value; } } else if (input.Ch() != 'Z' && input.Ch() != '+' && input.Ch() != '-') { throw new XmpException("Invalid date string, after time", XmpError.BADVALUE); } if (!input.HasNext()) { // no Timezone at all return binValue; } if (input.Ch() == 'Z') { input.Skip(); } else if (input.HasNext()) { if (input.Ch() == '+') { } else if (input.Ch() == '-') { } else { throw new XmpException("Time zone must begin with 'Z', '+', or '-'", XmpError.BADVALUE); } input.Skip(); // Extract the time zone hour. if (input.HasNext()) { if (input.Ch() == ':') { input.Skip(); } else { throw new XmpException("Invalid date string, after time zone hour", XmpError.BADVALUE); } } } // create a corresponding TZ and set it time zone binValue.TimeZone = TimeZone.CurrentTimeZone; if (input.HasNext()) { throw new XmpException("Invalid date string, extra chars at end", XmpError.BADVALUE); } return binValue; }
/// <param name="iso8601String"> a date string that is ISO 8601 conform. </param> /// <param name="binValue"> an existing XMPDateTime to set with the parsed date </param> /// <returns> Returns an XMPDateTime-object containing the ISO8601-date. </returns> /// <exception cref="XmpException"> Is thrown when the string is non-conform. </exception> public static IXmpDateTime Parse(string iso8601String, IXmpDateTime binValue) { if (iso8601String == null) { throw new XmpException("Parameter must not be null", XmpError.BADPARAM); } if (iso8601String.Length == 0) { return(binValue); } ParseState input = new ParseState(iso8601String); if (input.Ch(0) == '-') { input.Skip(); } // Extract the year. int value = input.GatherInt("Invalid year in date string", 9999); if (input.HasNext() && input.Ch() != '-') { throw new XmpException("Invalid date string, after year", XmpError.BADVALUE); } if (input.Ch(0) == '-') { value = -value; } binValue.Year = value; if (!input.HasNext()) { return(binValue); } input.Skip(); // Extract the month. value = input.GatherInt("Invalid month in date string", 12); if (input.HasNext() && input.Ch() != '-') { throw new XmpException("Invalid date string, after month", XmpError.BADVALUE); } binValue.Month = value; if (!input.HasNext()) { return(binValue); } input.Skip(); // Extract the day. value = input.GatherInt("Invalid day in date string", 31); if (input.HasNext() && input.Ch() != 'T') { throw new XmpException("Invalid date string, after day", XmpError.BADVALUE); } binValue.Day = value; if (!input.HasNext()) { return(binValue); } input.Skip(); // Extract the hour. value = input.GatherInt("Invalid hour in date string", 23); binValue.Hour = value; if (!input.HasNext()) { return(binValue); } // Extract the minute. if (input.Ch() == ':') { input.Skip(); value = input.GatherInt("Invalid minute in date string", 59); if (input.HasNext() && input.Ch() != ':' && input.Ch() != 'Z' && input.Ch() != '+' && input.Ch() != '-') { throw new XmpException("Invalid date string, after minute", XmpError.BADVALUE); } binValue.Minute = value; } if (!input.HasNext()) { return(binValue); } if (input.HasNext() && input.Ch() == ':') { input.Skip(); value = input.GatherInt("Invalid whole seconds in date string", 59); if (input.HasNext() && input.Ch() != '.' && input.Ch() != 'Z' && input.Ch() != '+' && input.Ch() != '-') { throw new XmpException("Invalid date string, after whole seconds", XmpError.BADVALUE); } binValue.Second = value; if (input.Ch() == '.') { input.Skip(); int digits = input.Pos(); value = input.GatherInt("Invalid fractional seconds in date string", 999999999); if (input.HasNext() && (input.Ch() != 'Z' && input.Ch() != '+' && input.Ch() != '-')) { throw new XmpException("Invalid date string, after fractional second", XmpError.BADVALUE); } digits = input.Pos() - digits; for (; digits > 9; --digits) { value = value / 10; } for (; digits < 9; ++digits) { value = value * 10; } binValue.NanoSecond = value; } } else if (input.Ch() != 'Z' && input.Ch() != '+' && input.Ch() != '-') { throw new XmpException("Invalid date string, after time", XmpError.BADVALUE); } if (!input.HasNext()) { // no Timezone at all return(binValue); } if (input.Ch() == 'Z') { input.Skip(); } else if (input.HasNext()) { if (input.Ch() == '+') { } else if (input.Ch() == '-') { } else { throw new XmpException("Time zone must begin with 'Z', '+', or '-'", XmpError.BADVALUE); } input.Skip(); // Extract the time zone hour. if (input.HasNext()) { if (input.Ch() == ':') { input.Skip(); } else { throw new XmpException("Invalid date string, after time zone hour", XmpError.BADVALUE); } } } // create a corresponding TZ and set it time zone binValue.TimeZone = TimeZone.CurrentTimeZone; if (input.HasNext()) { throw new XmpException("Invalid date string, extra chars at end", XmpError.BADVALUE); } return(binValue); }