国会图书馆edtf(扩展日期时间格式)规范的python实现
edtf的Python项目详细描述
python edtf
在python中edtf格式的一种实现,以及用于解析自然语言日期文本和将edtf日期转换为相关python对象的实用函数。
有关当前规范草案,请参见http://www.loc.gov/standards/datetime/" rel="nofollow">http://www.loc.gov/standards/datetime/。
安装
pip install edtf
使用
>>> from edtf import parse_edtf
# Parse an EDTF string to an EDTFObject
>>> e = parse_edtf("1979-08~") # approx August 1979
>>> e
UncertainOrApproximate: '1979-08~'
# normalised string representation (some different EDTF strings have identical meanings)
>>> unicode(e)
u'1979-08~'
# Derive Python date objects
# lower and upper bounds that strictly adhere to the given range
>>> e.lower_strict()[:3], e.upper_strict()[:3]
((1979, 8, 1), (1979, 8, 31))
# lower and upper bounds that are padded if there's indicated uncertainty
>>> e.lower_fuzzy()[:3], e.upper_fuzzy()[:3]
((1979, 7, 1), (1979, 9, 30))
# Date intervals
>>> interval = parse_edtf("1979-08~/open")
>>> interval
Level1Interval: '1979-08~/open'
# Intervals have lower and upper EDTF objects.
>>> interval.lower, interval.upper
(UncertainOrApproximate: '1979-08~', UncertainOrApproximate: 'open')
>>> interval.lower.upper_strict()[:3]
(1979, 8, 31)
>>> interval.upper.lower_strict() # 'open' is interpreted to mean 'still happening'.
[Today's date]
# Date collections
>>> coll = parse_edtf('{1667,1668, 1670..1672}')
>>> coll
MultipleDates: '{1667, 1668, 1670..1672}'
>>> coll.objects
(Date: '1667', Date: '1668', Consecutives: '1670..1672')
parse_edtf()
返回的对象是一个edtf.parser.parser_classes.edtf object
子类的实例,具体取决于分析的日期类型。这些类是:
# Level 0
Date
DateAndTime
Interval
# Level 1
UncertainOrApproximate
Unspecified
Level1Interval
LongYear
Season
# Level 2
PartialUncertainOrApproximate
PartialUnspecified
OneOfASet
MultipleDates
MaskedPrecision
Level2Interval
ExponentialYear
所有这些都实现了upper/lower_strict/fuzzy()
方法来派生pythondate
对象。
*interval
实例具有upper
和lower
属性,这些属性本身就是edtfobject
实例。
oneofset
和multipledates
实例有一个对象
属性,该属性是集合或列表中分析的所有EDTF日期的列表。
EDTF规范包含
该库包括edtf规范的0、1和2级的实现。
测试覆盖范围包括功能规格表中给出的每个示例。
0级ISO 8601功能
日期:
>>> parse_edtf('1979-08') # August 1979 Date: '1979-08'
日期和时间:
>>> parse_edtf('2004-01-01T10:10:10+05:00') DateAndTime: '2004-01-01T10:10:10+05:00'
间隔(开始/结束):
>>> parse_edtf('1979-08-28/1979-09-25') # From August 28 to September 25 1979 Interval: '1979-08-28/1979-09-25'
一级扩展
不确定/大概日期:
>>> parse_edtf('1979-08-28~') # Approximately August 28th 1979 UncertainOrApproximate: '1979-08-28~'
未指定日期:
>>> parse_edtf('1979-08-uu') # An unknown day in August 1979 Unspecified: '1979-08-uu' >>> parse_edtf('1979-uu') # Some month in 1979 Unspecified: '1979-uu'
延长间隔:
>>> parse_edtf('1984-06-02?/2004-08-08~') Level1Interval: '1984-06-02?/2004-08-08~'
超过四位数的年份:
0pip install edtf
季节:
1pip install edtf
2级扩展
部分不确定/近似:
2pip install edtf
部分未指定:
3pip install edtf
一组:
4pip install edtf
多个日期:
5pip install edtf
掩蔽精度:
6pip install edtf
2级延长间隔:
7pip install edtf
需要超过4位数的年份-指数形式:
8pip install edtf
自然语言表示法
该库包括一个基本的英语自然语言解析器(它还不够智能,无法处理诸如"复活节"或其他语言的场合):
pip install edtf
9
注意,结果是一个字符串,而不是一个etdfobject
解析器可以解析如下字符串:
>>> from edtf import parse_edtf
# Parse an EDTF string to an EDTFObject
>>> e = parse_edtf("1979-08~") # approx August 1979
>>> e
UncertainOrApproximate: '1979-08~'
# normalised string representation (some different EDTF strings have identical meanings)
>>> unicode(e)
u'1979-08~'
# Derive Python date objects
# lower and upper bounds that strictly adhere to the given range
>>> e.lower_strict()[:3], e.upper_strict()[:3]
((1979, 8, 1), (1979, 8, 31))
# lower and upper bounds that are padded if there's indicated uncertainty
>>> e.lower_fuzzy()[:3], e.upper_fuzzy()[:3]
((1979, 7, 1), (1979, 9, 30))
# Date intervals
>>> interval = parse_edtf("1979-08~/open")
>>> interval
Level1Interval: '1979-08~/open'
# Intervals have lower and upper EDTF objects.
>>> interval.lower, interval.upper
(UncertainOrApproximate: '1979-08~', UncertainOrApproximate: 'open')
>>> interval.lower.upper_strict()[:3]
(1979, 8, 31)
>>> interval.upper.lower_strict() # 'open' is interpreted to mean 'still happening'.
[Today's date]
# Date collections
>>> coll = parse_edtf('{1667,1668, 1670..1672}')
>>> coll
MultipleDates: '{1667, 1668, 1670..1672}'
>>> coll.objects
(Date: '1667', Date: '1668', Consecutives: '1670..1672')
0
从edtf表示生成自然文本是未来的目标。
当解释一个不明确的日期时,自然文本解析器做了什么假设?
"1800年代"模糊地说是一个世纪或十年。如果给定日期不确定或近似,则使用十年解释。如果日期确定且准确,则使用世纪解释。
如果未指定世纪(
edtf(natural_text="The'70s")
,则如果年份大于当前年份,则表示世纪为"19",否则表示世纪为当前世纪。默认情况下,使用自然语言假定美国订购日期(mm/dd/yyyy)。若要更改此设置,请在"设置"中将"天"设置为"真"。
如果一个自然语言组的日期是一个"/",它被解释为"或"而不是"和"。生成的edtf文本是一个由
[]
("其中一个日期")括起的列表,而不是{}
(所有这些日期)。
转换到python日期和从python日期转换到python日期
由于edtf日期通常是区域性的,而且常常不精确,因此我们需要根据具体情况使用一些不同的python日期。通常,python日期用于排序和筛选,不直接显示给用户。
结构时间
日期表示法
因为python的datetime
模块不支持超出1ad到9999ad范围的日期,所以我们返回日期a默认情况下是stime.struct\u time
对象,而不是您可能期望的datetime.date
或datetime.datetime
对象。
struct_time
表示更难使用,但可以按主要用例进行排序,并且可以相对容易地转换为date
或date time
对象(前提是年份在公元1到9999年内)或更灵活的库中的最新对象,例如astropy.time对于外部年份这些界限。
如果确定使用的日期在python的date time
模块支持的范围内,则可以使用edtf.struct\u time to\u date
和edtf.struct\u time to\u datetime
函数获得这些更方便的对象。
注意:在切换到struct-time
之前,默认情况下,此库确实从方法返回了date
和datetime
对象。见票据https://github.com/ixc/python edtf/issues/26
低严格
和高严格
这些日期表示日期范围内严格的最早和最晚日期,忽略不确定性或近似性。思考这个问题的一种方法是"如果你必须选择一个单独的日期来排序,那会是什么?"
在升序排序(最近的最后一次)中,按lower_strict
排序以获得自然排序顺序。在降序排序(最新排序)中,按upper_strict
排序:
>>> from edtf import parse_edtf
# Parse an EDTF string to an EDTFObject
>>> e = parse_edtf("1979-08~") # approx August 1979
>>> e
UncertainOrApproximate: '1979-08~'
# normalised string representation (some different EDTF strings have identical meanings)
>>> unicode(e)
u'1979-08~'
# Derive Python date objects
# lower and upper bounds that strictly adhere to the given range
>>> e.lower_strict()[:3], e.upper_strict()[:3]
((1979, 8, 1), (1979, 8, 31))
# lower and upper bounds that are padded if there's indicated uncertainty
>>> e.lower_fuzzy()[:3], e.upper_fuzzy()[:3]
((1979, 7, 1), (1979, 9, 30))
# Date intervals
>>> interval = parse_edtf("1979-08~/open")
>>> interval
Level1Interval: '1979-08~/open'
# Intervals have lower and upper EDTF objects.
>>> interval.lower, interval.upper
(UncertainOrApproximate: '1979-08~', UncertainOrApproximate: 'open')
>>> interval.lower.upper_strict()[:3]
(1979, 8, 31)
>>> interval.upper.lower_strict() # 'open' is interpreted to mean 'still happening'.
[Today's date]
# Date collections
>>> coll = parse_edtf('{1667,1668, 1670..1672}')
>>> coll
MultipleDates: '{1667, 1668, 1670..1672}'
>>> coll.objects
(Date: '1667', Date: '1668', Consecutives: '1670..1672')
1
下模糊
和上模糊
这些日期表示日期范围内可能的最早和最晚日期,对于"可能"的定义相当任意。
这些值对于筛选结果非常有用,例如,测试哪些edtf日期可能属于或重叠于所需的日期范围。
模糊日期是从严格日期派生出来的,加上或减去一个取决于日期规格说明的精确程度的填充级别。对于近似日期或不确定日期,我们(任意)将表面范围按不确定时间刻度的100%填充,或按季节填充12周。也就是说,如果一个日期是以月为单位的近似值,那么它将被一个月填充。如果是按年份比例计算的近似值,则用一年来填充:
>>> from edtf import parse_edtf
# Parse an EDTF string to an EDTFObject
>>> e = parse_edtf("1979-08~") # approx August 1979
>>> e
UncertainOrApproximate: '1979-08~'
# normalised string representation (some different EDTF strings have identical meanings)
>>> unicode(e)
u'1979-08~'
# Derive Python date objects
# lower and upper bounds that strictly adhere to the given range
>>> e.lower_strict()[:3], e.upper_strict()[:3]
((1979, 8, 1), (1979, 8, 31))
# lower and upper bounds that are padded if there's indicated uncertainty
>>> e.lower_fuzzy()[:3], e.upper_fuzzy()[:3]
((1979, 7, 1), (1979, 9, 30))
# Date intervals
>>> interval = parse_edtf("1979-08~/open")
>>> interval
Level1Interval: '1979-08~/open'
# Intervals have lower and upper EDTF objects.
>>> interval.lower, interval.upper
(UncertainOrApproximate: '1979-08~', UncertainOrApproximate: 'open')
>>> interval.lower.upper_strict()[:3]
(1979, 8, 31)
>>> interval.upper.lower_strict() # 'open' is interpreted to mean 'still happening'.
[Today's date]
# Date collections
>>> coll = parse_edtf('{1667,1668, 1670..1672}')
>>> coll
MultipleDates: '{1667, 1668, 1670..1672}'
>>> coll.objects
(Date: '1667', Date: '1668', Consecutives: '1670..1672')
2
人们可以将不确定或近似的日期解释为"加或减[精度级别]。
如果一个日期既不确定又近似,则填充两次,即得到100%*2填充或"加减两个[精度级别]。
季节
季节默认被解释为北半球。要更改此设置,请覆盖appsettings.py中的月份映射
比较
如果两个edtf日期的unicode()表示形式相同,则认为它们相等。如果EDTF日期的较低的严格值晚于其他日期,则认为该日期大于其他日期。
django orm字段
edtf.fields.edtf field
实现一个简单的django字段,该字段在数据库中存储一个edtf对象。
要在模型上存储自然语言值,请定义另一个字段,并设置edtfield
的natural\u文本字段
参数
保存模型时,会分析自然文本字段
值以设置日期edtf
值,并且基础edtf对象会将模型上的最早
和最新
字段设置为表示儒略日期的浮点值。
警告:与儒略日期之间的转换数值可能不准确,特别是对于公元前几千年的古代日期。理想情况下,julian日期值应该用于range和ordering仅在不要求完全准确的情况下操作。它们不应用于最终存储或往返转换后的显示。
示例用法:
>>> from edtf import parse_edtf
# Parse an EDTF string to an EDTFObject
>>> e = parse_edtf("1979-08~") # approx August 1979
>>> e
UncertainOrApproximate: '1979-08~'
# normalised string representation (some different EDTF strings have identical meanings)
>>> unicode(e)
u'1979-08~'
# Derive Python date objects
# lower and upper bounds that strictly adhere to the given range
>>> e.lower_strict()[:3], e.upper_strict()[:3]
((1979, 8, 1), (1979, 8, 31))
# lower and upper bounds that are padded if there's indicated uncertainty
>>> e.lower_fuzzy()[:3], e.upper_fuzzy()[:3]
((1979, 7, 1), (1979, 9, 30))
# Date intervals
>>> interval = parse_edtf("1979-08~/open")
>>> interval
Level1Interval: '1979-08~/open'
# Intervals have lower and upper EDTF objects.
>>> interval.lower, interval.upper
(UncertainOrApproximate: '1979-08~', UncertainOrApproximate: 'open')
>>> interval.lower.upper_strict()[:3]
(1979, 8, 31)
>>> interval.upper.lower_strict() # 'open' is interpreted to mean 'still happening'.
[Today's date]
# Date collections
>>> coll = parse_edtf('{1667,1668, 1670..1672}')
>>> coll
MultipleDates: '{1667, 1668, 1670..1672}'
>>> coll.objects
(Date: '1667', Date: '1668', Consecutives: '1670..1672')
3
由于edtfield
和'u earliest
和'u latest
字段值是自动设置的,因此您可能希望将它们设置为只读,或者在模型管理中不可见。