在 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 查询。这应该会使错误变得明显。