国会图书馆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实例具有upperlower属性,这些属性本身就是edtfobject实例。

oneofsetmultipledates实例有一个对象属性,该属性是集合或列表中分析的所有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~'
    
  • 超过四位数的年份:

    pip install edtf
    
    0
  • 季节:

    pip install edtf
    
    1

2级扩展

  • 部分不确定/近似:

    pip install edtf
    
    2
  • 部分未指定:

    pip install edtf
    
    3
  • 一组:

    pip install edtf
    
    4
  • 多个日期:

    pip install edtf
    
    5
  • 掩蔽精度:

    pip install edtf
    
    6
  • 2级延长间隔:

    pip install edtf
    
    7
  • 需要超过4位数的年份-指数形式:

    pip install edtf
    
    8

自然语言表示法

该库包括一个基本的英语自然语言解析器(它还不够智能,无法处理诸如"复活节"或其他语言的场合):

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.datedatetime.datetime对象。

struct_time表示更难使用,但可以按主要用例进行排序,并且可以相对容易地转换为datedate time对象(前提是年份在公元1到9999年内)或更灵活的库中的最新对象,例如astropy.time对于外部年份这些界限。

如果确定使用的日期在python的date time模块支持的范围内,则可以使用edtf.struct\u time to\u dateedtf.struct\u time to\u datetime函数获得这些更方便的对象。

注意:在切换到struct-time之前,默认情况下,此库确实从方法返回了datedatetime对象。见票据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对象。

要在模型上存储自然语言值,请定义另一个字段,并设置edtfieldnatural\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字段值是自动设置的,因此您可能希望将它们设置为只读,或者在模型管理中不可见。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java连接usb到uart设备到安卓设备>3.1   可以强制Php中的web应用程序与Java中的桌面应用程序一起工作吗?   java为什么自定义系统类加载器不工作?   数组在Java中解析具有多个分隔符的字符串   PMD Java 8德米特定律   JavaSpringMVC表单验证不适用于嵌套的复杂类型   让Eclipse Java组织导入以使用Google checkstyle   java Appium:无法创建新会话   java如何在数组中声明新字段   java如何解决“无法初始化类org.apache.cassandra.config.DatabaseDescriptor”?   java AsyncTask创建socket   java向@CreatedBy添加更多信息   如何在ubuntu中运行包含大量jars依赖项的java文件   java如何使用<s:select>标记并在中休眠来填充下拉列表?   java获取错误:找不到符号变量“level”和“next_level_button”   javaweb应用中基于UI的ajax显示代码流   Java长到MySql   java JvisualVM:奇怪的应用程序行为   ubuntu将Java程序的输出结果保存到一个文件中