using System.Globalization;
namespace Infrastructure.StockData;
///
/// SEIBro 파서 공용 필드 변환 헬퍼 — 순수 C#. YYYYMMDD→DateOnly, 콤마 포함 숫자→decimal/long/int, Y/N→bool.
/// 값 없음/""/비형식 = null (SeibroXml 이 빈 value 를 이미 키 제외 처리하므로 여기 들어오는 raw 는 대개 비어있지 않지만 방어적으로 처리).
/// Wave 0 파서들(SeibroStkStatParser 등)의 로컬 헬퍼와 동일 규칙을 한 곳에 모아 Wave 1+ 파서가 재사용한다.
///
internal static class SeibroFieldParse
{
/// YYYYMMDD 8자리 → DateOnly. 그 외(빈값/형식 불일치)는 null.
public static DateOnly? Date(string? raw)
{
var value = raw?.Trim();
if (string.IsNullOrEmpty(value) || value.Length != 8)
{
return null;
}
return DateOnly.TryParseExact(value, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var date) ? date : null;
}
/// 콤마 제거 후 decimal. 빈값/비숫자는 null (0 과 구분).
public static decimal? Decimal(string? raw)
{
var value = raw?.Replace(",", string.Empty, StringComparison.Ordinal);
return decimal.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed) ? parsed : null;
}
public static int? Int(string? raw)
{
var value = raw?.Replace(",", string.Empty, StringComparison.Ordinal);
return int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsed) ? parsed : null;
}
/// NUMBER(15,4) 등 소수 표기 정수 → long (decimal 로 읽고 절사). 빈값/비숫자는 null.
public static long? Long(string? raw)
{
var value = raw?.Replace(",", string.Empty, StringComparison.Ordinal);
return decimal.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed) ? (long)parsed : null;
}
/// Y→true, N→false, 그 외(빈값/미제공)→null.
public static bool? Yn(string? raw)
{
return raw?.Trim().ToUpperInvariant() switch
{
"Y" => true,
"N" => false,
_ => null
};
}
}