# dateparse_demo **Repository Path**: leaveWhite9088/dateparse_demo ## Basic Information - **Project Name**: dateparse_demo - **Description**: 项目dateparse的演示demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-05-13 - **Last Updated**: 2025-05-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README

dateparse

## 介绍 dateparse 是一个基于 cangjie 标准库实现的高性能、功能丰富的日期时间解析库。它能够自动识别并解析多种格式的日期字符串,支持全球各种常见日期格式,包括各种区域标准、时区处理以及多语言日期表示。该库适合需要处理各种不同格式日期输入的应用程序。 ### 项目特性 - **多格式支持**:自动识别并解析几十种常见日期格式,无需指定格式模板。 - **时区处理**:内置全面的时区支持,可在不同时区之间准确转换。 - **灵活配置**:提供多种解析选项,可定制解析行为。 - **高性能实现**:经过优化的解析算法,处理速度快,资源占用少。 - 本项目参考了项目 [dateparse](https://github.com/araddon/dateparse),结合仓颉的时间解析特性设计 ### 项目计划 - 2025/3/12 function freeze - 2025/3/15 添加更多本地化日期格式支持 - 2025/3/21 优化性能并减少内存占用 - 2025/3/25 增加日期格式化功能模块 - 2025/3/28 新增支持的日期格式 ## 项目架构 架构图文说明,包括模块说明、架构层次等详细说明。 ### 源码目录 ```shell . ├── README.md #整体介绍 ├── doc #文档目录(计划中) │ ├── design.md #设计文档 │ └── feature_api.md #特性接口文档 ├── src #源码目录 │ ├── date_parse.cj #主类,提供对外API接口 │ ├── parser.cj #核心解析器实现 │ ├── parser_options.cj #解析选项配置 │ ├── parser_option.cj #解析选项接口 │ ├── constant.cj #常量定义 │ ├── util.cj #工具函数 │ ├── exception_ambiguous.cj #日期格式歧义异常 │ ├── exception_unknown.cj #未知日期格式异常 │ └── test #测试代码 │ ├── date_parse_test.cj #测试用例 └── cjpm.toml #项目配置文件 ``` ### 接口说明 主要类和函数接口说明如下,详见 API文档(计划中) #### DateParse类 ```cangjie /** 解析任意格式的日期字符串 * 自动检测字符串格式并转换为 DateTime 对象,使用 UTC 时区 * * @param dateStr 要解析的日期字符串 * @param loc 可选的时区信息,如果不提供则使用本地时区 * @param opts 可选的解析选项 * @return 解析后的 DateTime 对象 */ public func parseAny(dateStr: String, loc: ?TimeZone, opts: ?Array): DateTime ``` ```cangjie /** 在指定时区解析日期字符串 * 自动检测字符串格式并转换为指定时区的 DateTime 对象 * * @param dateStr 要解析的日期字符串 * @param loc 目标时区 * @param opts 可选的解析选项 * @return 解析后的 DateTime 对象 */ public func parseIn(dateStr: String, loc: TimeZone, opts: ?Array): DateTime ``` ```cangjie /** 在本地时区解析日期字符串 * 自动检测字符串格式并转换为本地时区的 DateTime 对象 * * @param dateStr 要解析的日期字符串 * @param opts 可选的解析选项 * @return 解析后的 DateTime 对象 */ public func parseLocal(dateStr: String, opts: ?Array): DateTime ``` ```cangjie /** 解析日期字符串,错误时抛出异常 * 如果解析失败则会抛出异常而不是返回错误 * * @param dateStr 要解析的日期字符串 * @param loc 可选的时区信息,如果不提供则使用 UTC 时区 * @param opts 可选的解析选项 * @return 解析后的 DateTime 对象 * @throws Exception 如果无法解析日期字符串 */ public func mustParse(dateStr: String, loc: ?TimeZone, opts: ?Array): DateTime ``` ```cangjie /** 获取日期字符串的格式模板 * 解析日期并返回其格式字符串,而不是 DateTime 对象 * * @param dateStr 要解析的日期字符串 * @param loc 可选的时区信息,如果不提供则使用本地时区 * @param opts 可选的解析选项 * @return 日期字符串的格式 */ public func parseFormat(dateStr: String, loc: ?TimeZone, opts: ?Array): String ``` ```cangjie /** 获取处理后的日期字符串 * 解析日期并返回其格式字符串,而不是 DateTime 对象 * * @param dateStr 要解析的日期字符串 * @param loc 可选的时区信息,如果不提供则使用本地时区 * @param opts 可选的解析选项 * @return 日期字符串的格式 */ public func parseDateStr(dateStr: String, loc: ?TimeZone, opts: ?Array): String ``` ```cangjie /** * 获取处理后的日期字符串和格式模板 * 解析日期并返回字符串数组,而不是 DateTime 对象 * * @param dateStr 要解析的日期字符串 * @param loc 可选的时区信息,如果不提供则使用本地时区 * @param opts 可选的解析选项 * @return 日期字符串的格式 */ public func parseStrAndFormat(dateStr: String, loc: ?TimeZone, opts: ?Array): Array ``` ```cangjie /** 严格解析日期字符串 * 如果日期格式存在歧义(如月/日顺序不确定)则抛出异常 * * @param dateStr 要解析的日期字符串 * @param loc 可选的时区信息,如果不提供则使用本地时区 * @param opts 可选的解析选项 * @return 解析后的 DateTime 对象 * @throws ExceptionAmbiguous 如果日期格式存在歧义 */ public func parseStrict(dateStr: String, loc: ?TimeZone, opts: ?Array): DateTime ``` #### ParserOptions类 ```cangjie /** 创建设置是否优先将第一个数字解析为月份的选项 * @param preferMonthFirst 如果为 true,则优先将第一个数字解析为月份;否则优先解析为日期 * @return 配置月份优先的解析选项 */ public static func preferMonthFirst(preferMonthFirst: Bool): ParserOption ``` ```cangjie /** 创建设置是否在月份解析出错时尝试交换日期和月份的选项 * @param retryAmbiguousDateWithSwap 如果为 true,则在月份超出范围时尝试交换日期和月份 * @return 配置交换重试的解析选项 */ public static func retryAmbiguousDateWithSwap(retryAmbiguousDateWithSwap: Bool): ParserOption ``` ## 使用说明 ### 编译构建 描述具体的编译过程: ```shell cjpm update cjpm build ``` ### 功能示例 #### 解析多种格式日期功能示例 功能示例描述: 这个示例展示了如何解析各种不同格式的日期字符串,而无需指定具体格式。 示例代码如下: ```cangjie import dateparse.* import std.collection.HashMap import std.time.DateTime main() { // 实例时间格式 let mainInputs = HashMap([ // 标准日期时间格式 ("May 8, 2009 5:57:51 PM","2009-05-08T17:57:51+08:00"), // 简单月日年格式 ("oct 7, 1970","1970-10-07T00:00:00+08:00"), ("oct 7, '70","1970-10-07T00:00:00+08:00"), ("oct. 7, 1970","1970-10-07T00:00:00+08:00"), ("oct. 7, 70","1970-10-07T00:00:00+08:00"), // Go的标准时间格式 ("Mon Jan 2 15:04:05 2006","2006-01-02T15:04:05+08:00"), ("Mon Jan 2 15:04:05 MST 2006","2006-01-02T15:04:05-07:00"), ("Mon Jan 02 15:04:05 -0700 2006","2006-01-02T15:04:05-07:00"), ("Monday, 02-Jan-06 15:04:05 MST","2006-01-02T15:04:05-07:00"), ("Mon, 02 Jan 2006 15:04:05 MST","2006-01-02T15:04:05-07:00"), // 带时区的日期时间格式 ("Tue, 11 Jul 2017 16:28:13 +0200 CEST","2017-07-11T16:28:13+04:00"), ("Mon, 02 Jan 2006 15:04:05 -0700","2006-01-02T15:04:05-07:00"), ("Mon Aug 10 15:44:11 UTC+0100 2015","2015-08-10T15:44:11+01:00"), ("Thu, 4 Jan 2018 17:53:36 +0000","2018-01-04T17:53:36Z"), ("Fri Jul 03 2015 18:04:07 GMT+0100 (GMT Daylight Time)","2015-07-03T18:04:07+01:00"), ("Sun, 3 Jan 2021 00:12:23 +0800 (GMT+08:00)","2021-01-03T00:12:23+08:00"), // 美式日期时间格式 ("September 17, 2012 10:09am","2012-09-17T10:09:00+08:00"), ("September 17, 2012 at 10:09am PST-08:00","2012-09-17T10:09:00-16:00"), ("September 17, 2012, 10:10:09","2012-09-17T10:10:09+08:00"), ("October 7, 1970","1970-10-07T00:00:00+08:00"), ("October 7th, 1970","1970-10-07T00:00:00+08:00"), // 欧式日期时间格式 ("12 Feb 2006, 19:17","2006-02-12T19:17:00+08:00"), ("12 Feb 2006 19:17","2006-02-12T19:17:00+08:00"), ("14 May 2019 19:11:40.164","2019-05-14T19:11:40.164+08:00"), ("7 oct 70","1970-10-07T00:00:00+08:00"), ("7 oct 1970","1970-10-07T00:00:00+08:00"), ("03 February 2013","2013-02-03T00:00:00+08:00"), ("1 July 2013","2013-07-01T00:00:00+08:00"), ("2013-Feb-03","2013-02-03T00:00:00+08:00"), // Apache日志格式 ("06/Jan/2008:15:04:05 -0700","2008-01-06T15:04:05-07:00"), ("06/Jan/2008 15:04:05 -0700","2008-01-06T15:04:05-07:00"), // mm/dd/yy格式 ("3/31/2014","2014-03-31T00:00:00+08:00"), ("03/31/2014","2014-03-31T00:00:00+08:00"), ("08/21/71","1971-08-21T00:00:00+08:00"), ("8/1/71","1971-08-01T00:00:00+08:00"), ("4/8/2014 22:05","2014-04-08T22:05:00+08:00"), ("04/08/2014 22:05","2014-04-08T22:05:00+08:00"), ("4/8/14 22:05","2014-04-08T22:05:00+08:00"), ("04/2/2014 03:00:51","2014-04-02T03:00:51+08:00"), // 12小时制时间格式 ("8/8/1965 12:00:00 AM","1965-08-08T00:00:00+08:00"), ("8/8/1965 01:00:01 PM","1965-08-08T13:00:01+08:00"), ("8/8/1965 01:00 PM","1965-08-08T13:00:00+08:00"), ("8/8/1965 1:00 PM","1965-08-08T13:00:00+08:00"), ("8/8/1965 12:00 AM","1965-08-08T00:00:00+08:00"), // 带毫秒的时间格式 ("4/02/2014 03:00:51","2014-04-02T03:00:51+08:00"), ("03/19/2012 10:11:59","2012-03-19T10:11:59+08:00"), ("03/19/2012 10:11:59.3186369","2012-03-19T10:11:59.3186369+08:00"), // yyyy/mm/dd格式 ("2014/3/31","2014-03-31T00:00:00+08:00"), ("2014/03/31","2014-03-31T00:00:00+08:00"), ("2014/4/8 22:05","2014-04-08T22:05:00+08:00"), ("2014/04/08 22:05","2014-04-08T22:05:00+08:00"), ("2014/04/2 03:00:51","2014-04-02T03:00:51+08:00"), ("2014/4/02 03:00:51","2014-04-02T03:00:51+08:00"), ("2012/03/19 10:11:59","2012-03-19T10:11:59+08:00"), ("2012/03/19 10:11:59.3186369","2012-03-19T10:11:59.3186369+08:00"), // yyyy:mm:dd格式 ("2014:3:31","2014-03-31T00:00:00+08:00"), ("2014:03:31","2014-03-31T00:00:00+08:00"), ("2014:4:8 22:05","2014-04-08T22:05:00+08:00"), ("2014:04:08 22:05","2014-04-08T22:05:00+08:00"), ("2014:04:2 03:00:51","2014-04-02T03:00:51+08:00"), ("2014:4:02 03:00:51","2014-04-02T03:00:51+08:00"), ("2012:03:19 10:11:59","2012-03-19T10:11:59+08:00"), ("2012:03:19 10:11:59.3186369","2012-03-19T10:11:59.3186369+08:00"), // ISO 8601格式 ("2006-01-02T15:04:05+0800","2006-01-02T15:04:05+08:00"), ("2009-08-12T22:15:09-07:00","2009-08-12T22:15:09-07:00"), ("2009-08-12T22:15:09","2009-08-12T22:15:09+08:00"), ("2009-08-12T22:15:09.988","2009-08-12T22:15:09.988+08:00"), ("2009-08-12T22:15:09","2009-08-12T22:15:09+08:00"), ("2017-07-19T03:21:51.897+0100","2017-07-19T03:21:51.897+01:00"), ("2019-05-29T08:41-04","2019-05-29T08:41:00-04:00"), // 标准日期时间带毫秒 ("2014-04-26 17:24:37.3186369","2014-04-26T17:24:37.3186369+08:00"), ("2012-08-03 18:31:59.257000000","2012-08-03T18:31:59.257+08:00"), ("2014-04-26 17:24:37.123","2014-04-26T17:24:37.123+08:00"), // 简单日期时间 ("2013-04-01 22:43","2013-04-01T22:43:00+08:00"), ("2013-04-01 22:43:22","2013-04-01T22:43:22+08:00"), // UTC/GMT时间 ("2014-12-16 06:20:00 UTC","2014-12-16T06:20:00Z"), ("2014-12-16 06:20:00 GMT","2014-12-16T06:20:00Z"), // 12小时制和时区组合 ("2014-04-26 05:24:37 PM","2014-04-26T17:24:37+08:00"), ("2014-04-26 13:13:43 +0800","2014-04-26T13:13:43+08:00"), ("2014-04-26 13:13:43 +0800 +08","2014-04-26T13:13:43+08:00"), ("2014-04-26 13:13:44 +09:00","2014-04-26T13:13:44+09:00"), // UTC时间戳格式 ("2012-08-03 18:31:59.257000000 +0000 UTC","2012-08-03T18:31:59.257Z"), ("2015-09-30 18:48:56.35272715 +0000 UTC","2015-09-30T18:48:56.35272715Z"), ("2015-02-18 00:12:00 +0000 GMT","2015-02-18T00:12:00Z"), ("2015-02-18 00:12:00 +0000 UTC","2015-02-18T00:12:00Z"), ("2017-07-19 03:21:51+00:00","2017-07-19T03:21:51Z"), // 仅日期 ("2014-04-26","2014-04-26T00:00:00+08:00"), // 带逗号的毫秒格式 ("2014-05-11 08:20:13,787","2014-05-11T08:20:13.787+08:00"), // 带时区的简单日期 ("2020-07-20+08:00","2020-07-20T00:00:00+08:00"), // 点分隔的日期格式 ("3.31.2014","2014-03-31T00:00:00+08:00"), ("03.31.2014","2014-03-31T00:00:00+08:00"), ("08.21.71","1971-08-21T00:00:00+08:00"), ("2014.03.30","2014-03-30T00:00:00+08:00"), // 紧凑格式 ("20140601","2014-06-01T00:00:00+08:00"), ("20140722105203","2014-07-22T10:52:03+08:00"), ("171113 14:14:20","2017-11-13T14:14:20+08:00"), // Unix时间戳格式 ("1332151919","2012-03-19T10:11:59+08:00"), ("1384216367189","2013-11-12T00:32:47.189+08:00"), ("1384216367111222","2013-11-12T00:32:47.111222+08:00"), ("1384216367111222333","2013-11-12T00:32:47.111222333+08:00") ]) // 创建解析器实例 let parser = DateParse.default // 循环输出解析后的时间 println("┌────────────────────────────────────────────┬────────────────────────────────────────────┐") println("│ 输入日期字符串 │ 实际解析结果 │") println("├────────────────────────────────────────────┼────────────────────────────────────────────┤") for (item in mainInputs){ var ts: DateTime = parser.parseAny(item[0], None, None) var actual = ts.toString() // 使用朴素方法而不是padEnd var inputStr = "│ " + item[0] while (inputStr.size < 47) { inputStr += " " } var outputStr = "│ " + actual while (outputStr.size < 46) { outputStr += " " } println(inputStr + outputStr + " │") } println("└────────────────────────────────────────────┴────────────────────────────────────────────┘") } ``` 执行结果如下: ```shell ┌────────────────────────────────────────────┬────────────────────────────────────────────┐ │ 输入日期字符串 │ 实际解析结果 │ ├────────────────────────────────────────────┼────────────────────────────────────────────┤ │ May 8, 2009 5:57:51 PM │ 2009-05-08T17:57:51+08:00 │ │ oct 7, 1970 │ 1970-10-07T00:00:00+08:00 │ │ oct 7, '70 │ 1970-10-07T00:00:00+08:00 │ │ oct. 7, 1970 │ 1970-10-07T00:00:00+08:00 │ │ oct. 7, 70 │ 1970-10-07T00:00:00+08:00 │ │ Mon Jan 2 15:04:05 2006 │ 2006-01-02T15:04:05+08:00 │ │ Mon Jan 2 15:04:05 MST 2006 │ 2006-01-02T15:04:05-07:00 │ │ Mon Jan 02 15:04:05 -0700 2006 │ 2006-01-02T15:04:05-07:00 │ │ Monday, 02-Jan-06 15:04:05 MST │ 2006-01-02T15:04:05-07:00 │ │ Mon, 02 Jan 2006 15:04:05 MST │ 2006-01-02T15:04:05-07:00 │ │ Tue, 11 Jul 2017 16:28:13 +0200 CEST │ 2017-07-11T16:28:13+04:00 │ │ Mon, 02 Jan 2006 15:04:05 -0700 │ 2006-01-02T15:04:05-07:00 │ │ Mon Aug 10 15:44:11 UTC+0100 2015 │ 2015-08-10T15:44:11+01:00 │ │ Thu, 4 Jan 2018 17:53:36 +0000 │ 2018-01-04T17:53:36Z │ │ Sun, 3 Jan 2021 00:12:23 +0800 (GMT+08:00) │ 2021-01-03T00:12:23+08:00 │ │ September 17, 2012 10:09am │ 2012-09-17T10:09:00+08:00 │ │ September 17, 2012 at 10:09am PST-08:00 │ 2012-09-17T10:09:00-16:00 │ │ September 17, 2012, 10:10:09 │ 2012-09-17T10:10:09+08:00 │ │ October 7, 1970 │ 1970-10-07T00:00:00+08:00 │ │ October 7th, 1970 │ 1970-10-07T00:00:00+08:00 │ │ 12 Feb 2006, 19:17 │ 2006-02-12T19:17:00+08:00 │ │ 12 Feb 2006 19:17 │ 2006-02-12T19:17:00+08:00 │ │ 14 May 2019 19:11:40.164 │ 2019-05-14T19:11:40.164+08:00 │ │ 7 oct 70 │ 1970-10-07T00:00:00+08:00 │ │ 7 oct 1970 │ 1970-10-07T00:00:00+08:00 │ │ 03 February 2013 │ 2013-02-03T00:00:00+08:00 │ │ 1 July 2013 │ 2013-07-01T00:00:00+08:00 │ │ 2013-Feb-03 │ 2013-02-03T00:00:00+08:00 │ │ 06/Jan/2008:15:04:05 -0700 │ 2008-01-06T15:04:05-07:00 │ │ 06/Jan/2008 15:04:05 -0700 │ 2008-01-06T15:04:05-07:00 │ │ 3/31/2014 │ 2014-03-31T00:00:00+08:00 │ │ 03/31/2014 │ 2014-03-31T00:00:00+08:00 │ │ 08/21/71 │ 1971-08-21T00:00:00+08:00 │ │ 8/1/71 │ 1971-08-01T00:00:00+08:00 │ │ 4/8/2014 22:05 │ 2014-04-08T22:05:00+08:00 │ │ 04/08/2014 22:05 │ 2014-04-08T22:05:00+08:00 │ │ 4/8/14 22:05 │ 2014-04-08T22:05:00+08:00 │ │ 04/2/2014 03:00:51 │ 2014-04-02T03:00:51+08:00 │ │ 8/8/1965 12:00:00 AM │ 1965-08-08T00:00:00+08:00 │ │ 8/8/1965 01:00:01 PM │ 1965-08-08T13:00:01+08:00 │ │ 8/8/1965 01:00 PM │ 1965-08-08T13:00:00+08:00 │ │ 8/8/1965 1:00 PM │ 1965-08-08T13:00:00+08:00 │ │ 8/8/1965 12:00 AM │ 1965-08-08T00:00:00+08:00 │ │ 4/02/2014 03:00:51 │ 2014-04-02T03:00:51+08:00 │ │ 03/19/2012 10:11:59 │ 2012-03-19T10:11:59+08:00 │ │ 03/19/2012 10:11:59.3186369 │ 2012-03-19T10:11:59.3186369+08:00 │ │ 2014/3/31 │ 2014-03-31T00:00:00+08:00 │ │ 2014/03/31 │ 2014-03-31T00:00:00+08:00 │ │ 2014/4/8 22:05 │ 2014-04-08T22:05:00+08:00 │ │ 2014/04/08 22:05 │ 2014-04-08T22:05:00+08:00 │ │ 2014/04/2 03:00:51 │ 2014-04-02T03:00:51+08:00 │ │ 2014/4/02 03:00:51 │ 2014-04-02T03:00:51+08:00 │ │ 2012/03/19 10:11:59 │ 2012-03-19T10:11:59+08:00 │ │ 2012/03/19 10:11:59.3186369 │ 2012-03-19T10:11:59.3186369+08:00 │ │ 2014:3:31 │ 2014-03-31T00:00:00+08:00 │ │ 2014:03:31 │ 2014-03-31T00:00:00+08:00 │ │ 2014:4:8 22:05 │ 2014-04-08T22:05:00+08:00 │ │ 2014:04:08 22:05 │ 2014-04-08T22:05:00+08:00 │ │ 2014:04:2 03:00:51 │ 2014-04-02T03:00:51+08:00 │ │ 2014:4:02 03:00:51 │ 2014-04-02T03:00:51+08:00 │ │ 2012:03:19 10:11:59 │ 2012-03-19T10:11:59+08:00 │ │ 2012:03:19 10:11:59.3186369 │ 2012-03-19T10:11:59.3186369+08:00 │ │ 2006-01-02T15:04:05+0800 │ 2006-01-02T15:04:05+08:00 │ │ 2009-08-12T22:15:09-07:00 │ 2009-08-12T22:15:09-07:00 │ │ 2009-08-12T22:15:09 │ 2009-08-12T22:15:09+08:00 │ │ 2009-08-12T22:15:09.988 │ 2009-08-12T22:15:09.988+08:00 │ │ 2017-07-19T03:21:51.897+0100 │ 2017-07-19T03:21:51.897+01:00 │ │ 2019-05-29T08:41-04 │ 2019-05-29T08:41:00-04:00 │ │ 2014-04-26 17:24:37.3186369 │ 2014-04-26T17:24:37.3186369+08:00 │ │ 2012-08-03 18:31:59.257000000 │ 2012-08-03T18:31:59.257+08:00 │ │ 2014-04-26 17:24:37.123 │ 2014-04-26T17:24:37.123+08:00 │ │ 2013-04-01 22:43 │ 2013-04-01T22:43:00+08:00 │ │ 2013-04-01 22:43:22 │ 2013-04-01T22:43:22+08:00 │ │ 2014-12-16 06:20:00 UTC │ 2014-12-16T06:20:00Z │ │ 2014-12-16 06:20:00 GMT │ 2014-12-16T06:20:00Z │ │ 2014-04-26 05:24:37 PM │ 2014-04-26T17:24:37+08:00 │ │ 2014-04-26 13:13:43 +0800 │ 2014-04-26T13:13:43+08:00 │ │ 2014-04-26 13:13:43 +0800 +08 │ 2014-04-26T13:13:43+08:00 │ │ 2014-04-26 13:13:44 +09:00 │ 2014-04-26T13:13:44+09:00 │ │ 2012-08-03 18:31:59.257000000 +0000 UTC │ 2012-08-03T18:31:59.257Z │ │ 2015-09-30 18:48:56.35272715 +0000 UTC │ 2015-09-30T18:48:56.35272715Z │ │ 2015-02-18 00:12:00 +0000 GMT │ 2015-02-18T00:12:00Z │ │ 2015-02-18 00:12:00 +0000 UTC │ 2015-02-18T00:12:00Z │ │ 2017-07-19 03:21:51+00:00 │ 2017-07-19T03:21:51Z │ │ 2014-04-26 │ 2014-04-26T00:00:00+08:00 │ │ 2014-05-11 08:20:13,787 │ 2014-05-11T08:20:13.787+08:00 │ │ 2020-07-20+08:00 │ 2020-07-20T00:00:00+08:00 │ │ 3.31.2014 │ 2014-03-31T00:00:00+08:00 │ │ 03.31.2014 │ 2014-03-31T00:00:00+08:00 │ │ 08.21.71 │ 1971-08-21T00:00:00+08:00 │ │ 2014.03.30 │ 2014-03-30T00:00:00+08:00 │ │ 20140601 │ 2014-06-01T00:00:00+08:00 │ │ 20140722105203 │ 2014-07-22T10:52:03+08:00 │ │ 171113 14:14:20 │ 2017-11-13T14:14:20+08:00 │ │ 1332151919 │ 2012-03-19T10:11:59+08:00 │ │ 1384216367189 │ 2013-11-12T00:32:47.189+08:00 │ │ 1384216367111222 │ 2013-11-12T00:32:47.111222+08:00 │ │ 1384216367111222333 │ 2013-11-12T00:32:47.111222333+08:00 │ └────────────────────────────────────────────┴────────────────────────────────────────────┘ ``` #### 时区处理功能示例 功能示例描述: 此示例展示了如何在不同时区解析日期字符串,并进行时区转换。 示例代码如下: ```cangjie import dateparse.* import std.time.TimeZone main() { // 创建解析器实例 let parser = DateParse.default // 在不同时区解析相同的日期字符串 let dateUTC = parser.parseIn("2023-01-15 12:00:00", TimeZone.UTC, None) let dateLocal = parser.parseLocal("2023-01-15 12:00:00", None) // 输出结果 println("UTC时间: " + dateUTC.toString("yyyy-MM-dd HH:mm:ss z")) println("本地时间: " + dateLocal.toString("yyyy-MM-dd HH:mm:ss z")) } ``` 执行结果如下: ```shell UTC时间: 2023-01-15 12:00:00 GMT 本地时间: 2023-01-15 12:00:00 UTC+08:00 ``` #### 格式识别功能示例 功能示例描述: 这个示例展示了如何获取日期字符串的格式模板。特别注意:由于本库对原始字符串有所处理,所以最后使用的格式不一定能够直接解析原字符串 示例代码如下: ```cangjie import dateparse.* import std.time.* main() { // 创建解析器实例 let parser = DateParse.default // 识别各种日期格式 let format1 = parser.parseFormat("2023-01-15", None, None) let format2 = parser.parseFormat("Jan 15, 2023", None, None) // 处理后的日期字符串 let dateStr1 = parser.parseDateStr("2023-01-15", None, None) let dateStr2 = parser.parseDateStr("Jan 15, 2023", None, None) // 获取处理后的日期字符串和格式模板 let temp = parser.parseStrAndFormat("2023-01-15", None, None) let dateStr3 = temp[0] let format3 = temp[1] let temp2 = parser.parseStrAndFormat("Jan 15, 2023", None, None) let dateStr4 = temp2[0] let format4 = temp2[1] // 输出识别的格式 println("处理后的日期字符串1: " + dateStr1) println("识别的格式1: " + format1) println("--------------------------------") println("处理后的日期字符串2: " + dateStr2) println("识别的格式2: " + format2) println("--------------------------------") println("处理后的日期字符串3: " + dateStr3) println("识别的格式3: " + format3) println("--------------------------------") println("处理后的日期字符串4: " + dateStr4) println("识别的格式4: " + format4) } ``` 执行结果如下: ```shell 处理后的日期字符串1: 2023-01-15 识别的格式1: y-MM-dd -------------------------------- 处理后的日期字符串2: Jan 15, 2023 识别的格式2: MMM dd, y -------------------------------- 处理后的日期字符串3: 01/15/2023 识别的格式3: MM/dd/y -------------------------------- 处理后的日期字符串4: 2023/01/15 15:04:05 识别的格式4: y/MM/dd H:m:s ``` #### 严格解析功能示例 功能示例描述: 此示例展示了如何使用严格解析模式,避免月/日顺序歧义。 示例代码如下: ```cangjie import dateparse.* main() { // 创建解析器实例 let parser = DateParse.default // 配置解析选项 let opts = [ ParserOptions.preferMonthFirst(false), // 优先将第一个数字解析为日期,而非月份 ParserOptions.retryAmbiguousDateWithSwap(false) // 不自动尝试交换月/日 ] try { // 尝试严格解析可能有歧义的日期 let date = parser.parseStrict("04/05/2023", None, opts) println("解析结果: " + date.toString("yyyy-MM-dd")) } catch (e: ExceptionAmbiguous) { println("日期格式存在歧义: " + e.message) } catch (e: Exception) { println("解析错误: " + e.message) } // 解析无歧义的日期 try { let date = parser.parseStrict("2023-04-05", None, None) println("解析结果: " + date.toString("yyyy-MM-dd")) } catch (e: Exception) { println("解析错误: " + e.message) } } ``` 执行结果如下: ```shell 日期格式存在歧义: This date has ambiguous mm/dd vs dd/mm type format 解析结果: 2023-04-05 ``` #### 配置解析选项功能示例 功能示例描述: 该示例展示了如何配置解析选项来自定义解析器的行为。 示例代码如下: ```cangjie import dateparse.* main() { // 创建解析器实例 let parser = DateParse.default var ts = parser.parseAny("04/02/2014 04:08:09 +0000 UTC", None, None) println("默认格式解析: ${ts.toString()}") let preferMonthFirstTrue = ParserOptions.preferMonthFirst(true) ts = parser.parseAny("04/02/2014 04:08:09 +0000 UTC", None, [preferMonthFirstTrue]) println("美式格式解析: ${ts.toString()}") let preferMonthFirstFalse = ParserOptions.preferMonthFirst(false) ts = parser.parseAny("04/02/2014 04:08:09 +0000 UTC", None, [preferMonthFirstFalse]) println("欧式格式解析: ${ts.toString()}") let retryAmbiguousDateWithSwapTrue = ParserOptions.retryAmbiguousDateWithSwap(true) ts = DateParse.default.parseAny("13/02/2014 04:08:09 +0000 UTC", None, [retryAmbiguousDateWithSwapTrue]) println("自动重试解析结果: ${ts.toString()}") } ``` 执行结果如下: ```shell 默认格式解析: 2014-04-02T04:08:09Z 美式格式解析: 2014-04-02T04:08:09Z 欧式格式解析: 2014-02-04T04:08:09Z 自动重试解析结果: 2014-02-13T04:08:09Z ``` ## 约束与限制 - 部分罕见的日期格式可能无法自动识别,需要手动指定格式 - 在处理有歧义的日期格式(如MM/DD vs DD/MM)时,默认采用美式格式(MM/DD) - 对于以下格式,由于仓颉语言的时间解释特性和该库的实现方式,暂不支持 | 不支持的格式 | 示例 | | ------------------------------------------ | ----------------------------------------------- | | `ANSIC_GLIBC` | `Mon 02 Jan 2006 03:04:05 PM UTC` | | `中文日期格式` | `2014年04月18日` | | `扩展的 ISO 8601 格式(带时区和额外信息)` | `2015-02-08 03:02:00 +0200 CEST m=+0.000000001` | | `RFC 2822 格式` | `Tue, 11 Jul 2017 04:08:03 +0200 (CEST)` | ## 开源协议 本项目基于 MIT License ## 参与贡献 本项目基于测试用例开发,所以可能会有一些格式会有疏漏,在使用过程中,如果您发现不支持的格式,欢迎给我们提交PR,欢迎给我们提交Issue,欢迎参与任何形式的贡献。 本项目committer:[@leaveWhite088](https://gitcode.com/leaveWhite9088) This project is supervised by [@zhangyin_gitcode](https://gitcode.com/zhangyin_gitcode) (HUAWEI Developer Advocate). ![img](https://raw.gitcode.com/SIGCANGJIE/homepage/attachment/uploads/9b648c07-efc2-4eb3-b02f-eab18c77beea/devadvocate.png)