在 Python 中将字符串转换为日期时间
Converting a String to Datetime in Python
我在我的 sqlite 数据库中搜索日期时遇到了一些问题(使用 peewee 作为 ORM)。如果用户以 03/31/2017 之类的格式输入特定日期,即使该日期在我的数据库中是有效日期,也不会发生任何事情。我很确定这是某种格式问题,但我在搜索输入和数据库查询中使用相同的格式——所以不确定可能是什么问题。
from collections import OrderedDict
import datetime
import os
from peewee import *
db = SqliteDatabase('wlg.db')
fmt = '%m/%d/%Y'
class Entry(Model):
notes = TextField()
name = TextField()
task = TextField()
minutes = IntegerField()
date = DateField(formats=[fmt])
class Meta:
database = db
def initialize():
"""Create database and table if they don't exist"""
db.connect()
db.create_tables([Entry], safe=True)
def clear():
os.system('cls' if os.name == 'nt' else 'clear')
def menu_loop():
"""Show the menu"""
choice = None
while choice != 'q':
clear()
print("Enter 'q' to quit")
for key, value in menu.items():
print('{}) {}'.format(key, value.__doc__))
choice = input('Action: ').lower().strip()
if choice in menu:
clear()
menu[choice]()
def add_entry():
"""Add an entry"""
print("Enter your name or 'm' to return to main menu.")
while True:
name = input('> ')
if name.lower().strip() != 'm':
task = input("What task did you do? ")
minutes = input("How many minutes did it take? ")
notes = input("Please enter any notes about the task: ")
date = datetime.date.today().strftime(fmt)
Entry.create(name=name, task=task, minutes=minutes, notes=notes, date=date)
input("Hit Enter/Return to go back and add a task or view previous entries.")
break
else:
menu_loop()
def view_entries(search_employee=None, search_date=None, search_time=None, search_term=None):
"""View previous entries"""
entries = Entry.select().order_by(Entry.date.desc())
if search_employee:
entries = entries.where(Entry.name.contains(search_employee))
elif search_date:
dt = datetime.datetime.strptime(search_date, fmt)
entries = entries.where(Entry.date == dt)
elif search_time:
entries = entries.where(Entry.minutes == int(search_time))
elif search_term:
entries = entries.where((Entry.task.contains(search_term))|(Entry.notes.contains(search_term)))
for entry in entries:
date = entry.date.strftime(fmt)
print(date)
print('='*len(date))
print("Name: " + entry.name)
print("Task: " + entry.task)
print("Minutes Taken: " + str(entry.minutes))
print("Task Notes: " + entry.notes)
print("Date: " + date)
print('n) next entry')
print('q) return to main menu')
next_action = input('Action: [Nq] ').lower().strip()
if next_action == 'q':
break
def search_by_employee():
view_entries(search_employee=input('Search query: '))
def search_by_date():
view_entries(search_date=input('Enter Date in Format(mm/dd/yyyy)): '))
def search_by_time():
view_entries(search_time=input('Search query: '))
# while True:
# search_time = (input('Search query: '))
# try:
# search_time = int(search_time)
# view_entries(search_time)
# except ValueError:
# print("Not a valid entry. Please try again")
def search_by_term():
view_entries(search_term = input('Search query: '))
def search_entries():
"""Search previous entries"""
# view_entries(input('Search query: '))
while True:
lookup = input("Lookup by Employee(E), Date(D), Time(T) or Search Term(S): ")
lookup.lower()
if lookup == 'e':
search_by_employee()
break
elif lookup == 'd':
search_by_date()
break
elif lookup == 't':
search_by_time()
break
elif lookup == 's':
search_by_term()
break
else:
print("Sorry invalid option. Please try again")
def delete_entry(entry):
"""Delete an entry"""
pass
menu = OrderedDict([
('a', add_entry),
('v', view_entries),
('s', search_entries)
])
if __name__ == '__main__':
initialize()
menu_loop()
03/31/2017 在此处不是有效日期(法国)。
如果您想要特定于语言环境的日期处理,我相信 python 日期时间支持它。
Locale date formatting in Python
但是,如果您的应用程序有国际用户,您应该非常非常小心,因为 01/02/2017 是 2 月 1 日或 1 月 2 日,具体取决于您的用户来自世界的哪个部分。
我发现文本日期更适合显示。例如,在法语中它将是“1er Février”,但是 "Feb. 1" 是明确的,并且如果网站设置为英语则绝对没问题。
但是,显示“02/01”是自找麻烦。
//吐槽结束
可以解释您的问题的假设:
使用datetime.datetime,但您的列是没有时间的日期。转换过程中可能会出错。使用正确的类型总是一个好主意。
添加 print() 以确保您的日期正确转换为 python 日期对象。
您声明:
date = DateField(formats=[fmt])
因为有一个 "fmt" 规范,这让我觉得 peewee 在 SQLite 内部日期格式 (ISO YYYY-MM-DD) 之间执行某种内部转换,并且可能需要一个"mm/dd/yyyy" 字符串而不是日期对象。你应该检查这个。
还要检查您的 ORM peewee 是否有办法显示它发出的 SQL 查询。这应该会使错误变得明显。
我在我的 sqlite 数据库中搜索日期时遇到了一些问题(使用 peewee 作为 ORM)。如果用户以 03/31/2017 之类的格式输入特定日期,即使该日期在我的数据库中是有效日期,也不会发生任何事情。我很确定这是某种格式问题,但我在搜索输入和数据库查询中使用相同的格式——所以不确定可能是什么问题。
from collections import OrderedDict
import datetime
import os
from peewee import *
db = SqliteDatabase('wlg.db')
fmt = '%m/%d/%Y'
class Entry(Model):
notes = TextField()
name = TextField()
task = TextField()
minutes = IntegerField()
date = DateField(formats=[fmt])
class Meta:
database = db
def initialize():
"""Create database and table if they don't exist"""
db.connect()
db.create_tables([Entry], safe=True)
def clear():
os.system('cls' if os.name == 'nt' else 'clear')
def menu_loop():
"""Show the menu"""
choice = None
while choice != 'q':
clear()
print("Enter 'q' to quit")
for key, value in menu.items():
print('{}) {}'.format(key, value.__doc__))
choice = input('Action: ').lower().strip()
if choice in menu:
clear()
menu[choice]()
def add_entry():
"""Add an entry"""
print("Enter your name or 'm' to return to main menu.")
while True:
name = input('> ')
if name.lower().strip() != 'm':
task = input("What task did you do? ")
minutes = input("How many minutes did it take? ")
notes = input("Please enter any notes about the task: ")
date = datetime.date.today().strftime(fmt)
Entry.create(name=name, task=task, minutes=minutes, notes=notes, date=date)
input("Hit Enter/Return to go back and add a task or view previous entries.")
break
else:
menu_loop()
def view_entries(search_employee=None, search_date=None, search_time=None, search_term=None):
"""View previous entries"""
entries = Entry.select().order_by(Entry.date.desc())
if search_employee:
entries = entries.where(Entry.name.contains(search_employee))
elif search_date:
dt = datetime.datetime.strptime(search_date, fmt)
entries = entries.where(Entry.date == dt)
elif search_time:
entries = entries.where(Entry.minutes == int(search_time))
elif search_term:
entries = entries.where((Entry.task.contains(search_term))|(Entry.notes.contains(search_term)))
for entry in entries:
date = entry.date.strftime(fmt)
print(date)
print('='*len(date))
print("Name: " + entry.name)
print("Task: " + entry.task)
print("Minutes Taken: " + str(entry.minutes))
print("Task Notes: " + entry.notes)
print("Date: " + date)
print('n) next entry')
print('q) return to main menu')
next_action = input('Action: [Nq] ').lower().strip()
if next_action == 'q':
break
def search_by_employee():
view_entries(search_employee=input('Search query: '))
def search_by_date():
view_entries(search_date=input('Enter Date in Format(mm/dd/yyyy)): '))
def search_by_time():
view_entries(search_time=input('Search query: '))
# while True:
# search_time = (input('Search query: '))
# try:
# search_time = int(search_time)
# view_entries(search_time)
# except ValueError:
# print("Not a valid entry. Please try again")
def search_by_term():
view_entries(search_term = input('Search query: '))
def search_entries():
"""Search previous entries"""
# view_entries(input('Search query: '))
while True:
lookup = input("Lookup by Employee(E), Date(D), Time(T) or Search Term(S): ")
lookup.lower()
if lookup == 'e':
search_by_employee()
break
elif lookup == 'd':
search_by_date()
break
elif lookup == 't':
search_by_time()
break
elif lookup == 's':
search_by_term()
break
else:
print("Sorry invalid option. Please try again")
def delete_entry(entry):
"""Delete an entry"""
pass
menu = OrderedDict([
('a', add_entry),
('v', view_entries),
('s', search_entries)
])
if __name__ == '__main__':
initialize()
menu_loop()
03/31/2017 在此处不是有效日期(法国)。
如果您想要特定于语言环境的日期处理,我相信 python 日期时间支持它。
Locale date formatting in Python
但是,如果您的应用程序有国际用户,您应该非常非常小心,因为 01/02/2017 是 2 月 1 日或 1 月 2 日,具体取决于您的用户来自世界的哪个部分。
我发现文本日期更适合显示。例如,在法语中它将是“1er Février”,但是 "Feb. 1" 是明确的,并且如果网站设置为英语则绝对没问题。
但是,显示“02/01”是自找麻烦。
//吐槽结束
可以解释您的问题的假设:
使用datetime.datetime,但您的列是没有时间的日期。转换过程中可能会出错。使用正确的类型总是一个好主意。
添加 print() 以确保您的日期正确转换为 python 日期对象。
您声明:
date = DateField(formats=[fmt])
因为有一个 "fmt" 规范,这让我觉得 peewee 在 SQLite 内部日期格式 (ISO YYYY-MM-DD) 之间执行某种内部转换,并且可能需要一个"mm/dd/yyyy" 字符串而不是日期对象。你应该检查这个。
还要检查您的 ORM peewee 是否有办法显示它发出的 SQL 查询。这应该会使错误变得明显。