当前位置: 首页 > 面试题库 >

SQLite日期存储和转换

呼延凌
2023-03-14
问题内容

我在使用Python和SQLite进行日期存储/检索时遇到设计问题。

我了解SQLite日期列将日期存储为ISO格式的文本(即'2010-05-25')。因此,当我显示英国日期(例如,在网页上)时,我使用

datetime.datetime.strptime(mydate,'%Y-%m-%d').strftime('%d/%m/%Y')

但是,当涉及将数据写回表时,SQLite非常宽容并且非常乐意将其存储'25/06/2003'在日期字段中,但这并不理想,因为

  • 我可能在同一列中混用了多种日期格式,

  • SQLite的日期函数仅适用于ISO格式。

因此,在提交之前,我需要将日期字符串转换回ISO格式,但是随后,我将需要一个通用函数,该函数检查要在所有日期字段中写入的数据,并在必要时转换为ISO。对我来说这听起来有些乏味,但也许是不可避免的。

有更简单的解决方案吗?将日期字段更改为10个字符的字段并'dd/mm/yyyy'在整个表格中存储会更容易吗?这样,从表读取或写入数据时无需进行任何转换,并且如果需要执行任何日期算术,则可以使用datetime()函数。

其他开发人员如何克服这个问题?任何帮助,将不胜感激。作为记录,我将SQLite3与Python 3.1结合使用。


问题答案:

如果设置detect_types=sqlite3.PARSE_DECLTYPESsqlite3.connect,则当您从数据库中提取数据时,连接将尝试将sqlite数据类型转换为Python数据类型。

这是因为它更漂亮的工作比随机日期字符串一样,你再有解析datetime对象一件非常好的事情
datetime.datetime.strptimedateutil.parser.parse

不幸的是,使用detect_types并不能阻止sqlite将 字符串作为DATE数据 接受 ,但是当您尝试从数据库中提取数据时(如果以YYYY-
MM-DD以外的其他格式插入数据),将会收到错误消息,因为将无法将其转换为datetime.date对象:

conn=sqlite3.connect(':memory:',detect_types=sqlite3.PARSE_DECLTYPES) 
cur=conn.cursor()
cur.execute('CREATE TABLE foo(bar DATE)')
# Unfortunately, this is still accepted by sqlite
cur.execute("INSERT INTO foo(bar) VALUES (?)",('25/06/2003',))

# But you won't be able to draw the data out later because parsing will fail
try:
    cur.execute("SELECT * FROM foo")
except ValueError as err:
    print(err)
    # invalid literal for int() with base 10: '25/06/2003'
    conn.rollback()

但是,至少该错误会提醒您,当您确实应该插入datetime.date对象时,已经为DATE插入了一个字符串:

cur.execute("INSERT INTO foo(bar) VALUES (?)",(datetime.date(2003,6,25),))
cur.execute("SELECT ALL * FROM foo")
data=cur.fetchall()
data=zip(*data)[0]
print(data)
# (datetime.date(2003, 6, 25),)

只要您使用YYYY-MM-DD格式,就可以将字符串作为DATE数据插入。请注意,尽管您插入了一个字符串,但它作为一个datetime.date对象返回:

cur.execute("INSERT INTO foo(bar) VALUES (?)",('2003-06-25',))
cur.execute("SELECT ALL * FROM foo")
data=cur.fetchall()
data=zip(*data)[0]
print(data)
# (datetime.date(2003, 6, 25), datetime.date(2003, 6, 25))

因此,如果您受训只将datetime.date对象插入DATE字段,那么以后将数据提取出来就不会有问题。

如果您的用户以各种格式输入日期数据,请检出dateutil.parser.parse。它可能能够帮助您将各种字符串转换为datetime.datetime对象。



 类似资料:
  • 这是我的Firebase结构 我想在每个用户的第二个名字下面的“预订”下存储一天中的日期和时间,然后选择一天中的日期和时间。 这是我到目前为止用错误的方法得到的结果。它在名为“MyBookings”的单独子节点下设置日期 基本上,我所做的是单击一个显示日期和时间选择器的EditText,我需要将该日期存储在Firebase实时数据库中。 这是我的Firebase参考,我知道它是错误的,但不知道如何

  • 基于egg 封装公共上传类 配置上传路径 config.default.js // 上传文件类型限制 config.multipart = { fileExtensions: [ '.apk' ] // 增加对 apk 扩展名的文件支持 } // add your user config here const userConfig = { // 上传路径配置 upload_path: 'ap

  • 我有一个解析模板,它将从appsync查询中获取开始日期作为日期。但我在迪纳摩的约会是有日期时间戳的。我们如何在没有时间的情况下比较这两个日期。以下是我的解析器模板查询:

  • 主要内容:时间字符串,修饰符(Modifier),格式化,实例SQLite 支持以下五个日期和时间函数: 序号 函数 实例 1 date(timestring, modifier, modifier, ...) 以 YYYY-MM-DD 格式返回日期。 2 time(timestring, modifier, modifier, ...) 以 HH:MM:SS 格式返回时间。 3 datetime(timestring, modifier, modifier

  • 我的应用程序中有一个日期选择器,以的形式返回日期(yyyy-mm-dd)。我遇到的问题是如何将其从转换为或任何其他格式,以便将其插入SQLite,以便稍后查询。

  • 问题内容: 我已经进行了所有设置,将当前日期存储到Java中的变量中。我要弄清楚的是如何存储当前日期之后1年的日期。 这是我当前的日期: 因此,例如,如果今天是今天,它将存储2/18/2013。我正在尝试存储日期2/18/2014。我将如何去做呢? 问题答案: 如果您不想拖动外部库,只需使用 请注意,如果日期是,并且您添加了1年,则将获得