/// <summary> /// Test if the input value is a non-null numeric type /// or a string that can be parsed as a number, with detection /// of hex strings controlled by <paramref name="parseFlags"/> /// </summary> /// <param name="value"></param> /// <param name="parseFlags"></param> public static bool IsNumeric(object value, ParseNumericStringFlags parseFlags) { if (null == value) { return(false); } if (value is string sValue) { if (double.TryParse(sValue, out _)) { return(true); } bool allowDigitSep = (parseFlags & ParseNumericStringFlags.AllowDigitSeparator) != 0; if (allowDigitSep) { bool changed = false; while (sValue.IndexOf('_') >= 0) { sValue = Regex.Replace(sValue, "([0-9a-fA-F])_+([0-9a-fA-F])", "$1$2"); changed = true; } if (changed && double.TryParse(sValue, out _)) { return(true); } } if ((parseFlags & ParseNumericStringFlags.HexString) != 0) { if (Regex.IsMatch(sValue, @"^\s*0[xX][0-9a-fA-F]+$")) { return(true); } } if ((parseFlags & ParseNumericStringFlags.OctalString) != 0) { if (Regex.IsMatch(sValue, @"^\s*0[oO][0-7]+$")) { return(true); } } if ((parseFlags & ParseNumericStringFlags.BinaryString) != 0) { if (Regex.IsMatch(sValue, @"^\s*0[bB][01]+$")) { return(true); } } return(false); } return(TypeInspection.IsNumberType(value.GetType())); }
private static TimeSpan _ToTimeSpan(object value) { if (value is TimeSpan) { return((TimeSpan)value); } if (value is string && Regex.IsMatch((string)value, @"^\s*\d+\.\d+\s*$")) { // Treat decimal string as seconds, not ticks return(TimeSpan.FromSeconds(To <double>(value))); } else if ((value != null && TypeInspection.IsNumberType(value.GetType())) || ValueInspection.IsNumeric(value)) { return(TimeSpan.FromTicks(To <long>(value))); } else if (value is string) { string sValue = (string)value; var m = Regex.Match(sValue, RX_MINUTES); if (m.Success) { // The input is a minutes : seconds string. The built-in TimeSpan.Parse requires a leading // hours segment as well. Append the 0: hours segment, and also pad the minutes segment with // a leading 0 if necessary sValue = "0:" + (m.Groups["minutes"].Value.Length == 2 ? "" : "0") + sValue; } return(TimeSpan.Parse(sValue)); } else if (value is DateTime) { return(TimeSpan.FromTicks(((DateTime)value).Ticks)); } // If the input is not a TimeSpan, this will throw an invalid cast exception in the localized language: return((TimeSpan)value); }
/// <summary> /// Test if the input value is a non-null numeric type /// or a string that can be parsed as a number, with detection /// of hex strings controlled by ConvertOptions flags /// </summary> /// <param name="value"></param> /// <param name="options"></param> public static bool IsNumeric(object value, ConvertOptions options) { if (value == null) { return(false); } if (value is string sValue) { if (double.TryParse(sValue, out double d)) { return(true); } if (options.HasFlag(ConvertOptions.AllowVBHex) && Regex.IsMatch(sValue, @"^\s*&[hH][0-9a-fA-F]+$")) { return(true); } if (options.HasFlag(ConvertOptions.Allow0xHex) && Regex.IsMatch(sValue, @"^\s*0[xX][0-9a-fA-F]+$")) { return(true); } return(false); } return(TypeInspection.IsNumberType(value.GetType())); }