如何解析日期和期权日期?
How to Parse Dates & Option Dates?
当我遍历 CSVProvider
返回的行时,有些情况下日期要么包含在选项中,要么未包含在选项中。以下是数据样本:
+======+==============+============+===============+
| Site | Order Number | Order Date | Delivery Date |
+======+==============+============+===============+
| xyz | 100 | 12/14/2019 | 3/16/2020 |
+------+--------------+------------+---------------+
| xyz | 101 | 12/14/2019 | 3/16/2020 |
+------+--------------+------------+---------------+
| xyz | 102 | 12/14/2019 | 3/16/2020 |
+------+--------------+------------+---------------+
| xyz | 103 | 3/25/2020 | |
+------+--------------+------------+---------------+
| xyz | 104 | 3/26/2020 | |
+------+--------------+------------+---------------+
| xyz | 105 | 3/31/2020 | 4/5/2020 |
+------+--------------+------------+---------------+
| xyz | 106 | 4/4/2020 | |
+------+--------------+------------+---------------+
| xyz | 107 | 4/10/2020 | |
+------+--------------+------------+---------------+
| xyz | 108 | 4/12/2020 | |
+------+--------------+------------+---------------+
我想解析这些日期并构建包含日期字符串(当提供日期时)和空字符串的记录。
type example = { orderNumber: int; orderDate: string; deliveryDate: string }
如何实现以上目标?我想到并尝试了(见下面的代码),构建了一个自定义类型,该类型为包装和未包装的 DateTimes 加上别名,然后根据需要 extracting/converting。
注意:下面包含的代码无效:
type DateTimeOption<DateTime> =
| Some of DateTime
| DateTime
| None
let parseDate (date: DateTimeOption) =
match date with
| Some d -> d.ToString()
| None -> ""
| d: DateTime -> d.ToString()
通常,这采用解包的形式 - 从放大类型中提取内部值。
unwrap: (T | A<T>) -> T
我们没有任何多态约束可以让我们将类型表达为 DateTime | DateTime option
,所以我们只需要使用对象。
let rec dateUnwrap (opt: obj) =
match opt with
| :? DateTime as dt -> string dt
| :? Option<DateTime> as opt ->
opt |> Option.map(dateUnwrap) |> Option.defaultValue ""
| _ -> ""
测试
let now = DateTime.Now
assert ((dateUnwrap (Some now)) = string now)
assert ((dateUnwrap now) = string now)
assert ((dateUnwrap None) = "")
P.S.
如果您没有好的模式或示例,类型提供程序推断可能会很脆弱。
CsvProvider
有选项 - InferRows
。这是提供程序为了构建模式而扫描的行数 - 它的默认值恰好是 1000。
如果您想使用样本的所有可用行:
type OrderProvider = CsvProvider<uri, InferRows = 0>
CSV 提供程序尝试推断列的类型并将它们推断为日期或可选日期。在您的情况下,您似乎只需要 CSV 文件中的字符串值。
您可以通过在 CSV 类型提供程序中指定 Schema
并覆盖日期列的默认行为来轻松实现这一点,这样它只会为您提供一个字符串。
鉴于以下 CSV 文件另存为 C:/temp/b.csv
:
Site,OrderNumber,OrderDate,DeliveryDate
xyz,100,12/14/2019,3/16/2020
xyz,103,3/25/2020,
xyz,104,3/26/2020,
xyz,105,3/31/2020,4/5/2020
xyz,106,4/4/2020,
您可以使用您想要的格式获取数据:
type B = CsvProvider<"c:/temp/b.csv",Schema=",,string,string">
type example =
{ orderNumber: int; orderDate: string; deliveryDate: string }
[ for r in B.GetSample().Rows ->
{ orderNumber = r.OrderNumber;
orderDate = r.OrderDate;
deliveryDate = r.DeliveryDate } ]
当我遍历 CSVProvider
返回的行时,有些情况下日期要么包含在选项中,要么未包含在选项中。以下是数据样本:
+======+==============+============+===============+
| Site | Order Number | Order Date | Delivery Date |
+======+==============+============+===============+
| xyz | 100 | 12/14/2019 | 3/16/2020 |
+------+--------------+------------+---------------+
| xyz | 101 | 12/14/2019 | 3/16/2020 |
+------+--------------+------------+---------------+
| xyz | 102 | 12/14/2019 | 3/16/2020 |
+------+--------------+------------+---------------+
| xyz | 103 | 3/25/2020 | |
+------+--------------+------------+---------------+
| xyz | 104 | 3/26/2020 | |
+------+--------------+------------+---------------+
| xyz | 105 | 3/31/2020 | 4/5/2020 |
+------+--------------+------------+---------------+
| xyz | 106 | 4/4/2020 | |
+------+--------------+------------+---------------+
| xyz | 107 | 4/10/2020 | |
+------+--------------+------------+---------------+
| xyz | 108 | 4/12/2020 | |
+------+--------------+------------+---------------+
我想解析这些日期并构建包含日期字符串(当提供日期时)和空字符串的记录。
type example = { orderNumber: int; orderDate: string; deliveryDate: string }
如何实现以上目标?我想到并尝试了(见下面的代码),构建了一个自定义类型,该类型为包装和未包装的 DateTimes 加上别名,然后根据需要 extracting/converting。
注意:下面包含的代码无效:
type DateTimeOption<DateTime> =
| Some of DateTime
| DateTime
| None
let parseDate (date: DateTimeOption) =
match date with
| Some d -> d.ToString()
| None -> ""
| d: DateTime -> d.ToString()
通常,这采用解包的形式 - 从放大类型中提取内部值。
unwrap: (T | A<T>) -> T
我们没有任何多态约束可以让我们将类型表达为 DateTime | DateTime option
,所以我们只需要使用对象。
let rec dateUnwrap (opt: obj) =
match opt with
| :? DateTime as dt -> string dt
| :? Option<DateTime> as opt ->
opt |> Option.map(dateUnwrap) |> Option.defaultValue ""
| _ -> ""
测试
let now = DateTime.Now
assert ((dateUnwrap (Some now)) = string now)
assert ((dateUnwrap now) = string now)
assert ((dateUnwrap None) = "")
P.S.
如果您没有好的模式或示例,类型提供程序推断可能会很脆弱。
CsvProvider
有选项 - InferRows
。这是提供程序为了构建模式而扫描的行数 - 它的默认值恰好是 1000。
如果您想使用样本的所有可用行:
type OrderProvider = CsvProvider<uri, InferRows = 0>
CSV 提供程序尝试推断列的类型并将它们推断为日期或可选日期。在您的情况下,您似乎只需要 CSV 文件中的字符串值。
您可以通过在 CSV 类型提供程序中指定 Schema
并覆盖日期列的默认行为来轻松实现这一点,这样它只会为您提供一个字符串。
鉴于以下 CSV 文件另存为 C:/temp/b.csv
:
Site,OrderNumber,OrderDate,DeliveryDate
xyz,100,12/14/2019,3/16/2020
xyz,103,3/25/2020,
xyz,104,3/26/2020,
xyz,105,3/31/2020,4/5/2020
xyz,106,4/4/2020,
您可以使用您想要的格式获取数据:
type B = CsvProvider<"c:/temp/b.csv",Schema=",,string,string">
type example =
{ orderNumber: int; orderDate: string; deliveryDate: string }
[ for r in B.GetSample().Rows ->
{ orderNumber = r.OrderNumber;
orderDate = r.OrderDate;
deliveryDate = r.DeliveryDate } ]