Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az mssql-python illesztőprogram kezeli az SQL Server dátum- és időtípusait, és azokat a Python datetime modul objektumainak felelteti meg. Az SQL Server több dátum- és időponttípust kínál, eltérő pontossággal és képességekkel:
| SQL-típus | Python-típus | Tartomány | Precision |
|---|---|---|---|
| date | datetime.date |
0001-01-01-től 9999-12-31-ig | Egy nap |
| time | datetime.time |
00:00:00.0000000-től 23:59:59.999999-ig | 100 nanoszekundum |
| datetime | datetime.datetime |
1753-01-01-től 9999-12-31-ig | 3,33 milliszekundum |
| datetime2 | datetime.datetime |
0001-01-01-től 9999-12-31-ig | 100 nanoszekundum |
| smalldatetime | datetime.datetime |
1900-01-01-től 2079-06-06-ig | 1 perc |
| datetimeoffset |
datetime.datetime (tzinfo-val) |
0001-01-01-től 9999-12-31-ig | 100 nanomásodperc + időzóna |
Dátumidő értékek beszedése
Használj Python datetime objektumokat
A következő példa különböző dátum- és időtípusokat helyez be az SQL Server-be a Python datetime moduljával:
from datetime import datetime, date, time
import mssql_python
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
# Create a temp table with date, time, and datetime columns
cursor.execute("""
CREATE TABLE #Events (
EventDate DATE,
StartTime TIME,
LogTime DATETIME2
)
""")
# Insert date
cursor.execute(
"INSERT INTO #Events (EventDate) VALUES (%(date)s)",
{"date": date(2024, 12, 25)}
)
# Insert time
cursor.execute(
"INSERT INTO #Events (StartTime) VALUES (%(time)s)",
{"time": time(14, 30, 0)}
)
# Insert datetime
cursor.execute(
"INSERT INTO #Events (LogTime) VALUES (%(ts)s)",
{"ts": datetime(2024, 3, 15, 14, 30, 45)}
)
conn.commit()
Aktuális időbélyeg beszúrása
Az aktuális dátumot és időpontot az datetime.now() SQL Server GETDATE() funkciójával beírhatod:
from datetime import datetime
# Create temp table for the demo
cursor.execute("CREATE TABLE #Logs (Message NVARCHAR(200), CreatedAt DATETIME2)")
# Python current time
now = datetime.now()
cursor.execute("INSERT INTO #Logs (Message, CreatedAt) VALUES (%(msg)s, %(ts)s)",
{"msg": "Event occurred", "ts": now})
# Or use SQL Server's GETDATE()
cursor.execute("INSERT INTO #Logs (Message, CreatedAt) VALUES (%(msg)s, GETDATE())",
{"msg": "Event occurred"})
conn.commit()
Nagy pontosságú datetime2
Nagyobb pontosságú időbélyegekhez használjuk azt a datetime2 típust, amely 100 nanomásodperces pontosságot támogat:
from datetime import datetime
# Create temp table with a datetime2(7) column
cursor.execute("CREATE TABLE #PreciseLogs (EventTime DATETIME2(7))")
# Microsecond precision (Python supports up to microseconds)
precise_time = datetime(2024, 3, 15, 14, 30, 45, 123456)
cursor.execute(
"INSERT INTO #PreciseLogs (EventTime) VALUES (%(ts)s)", # datetime2(7) column
{"ts": precise_time}
)
conn.commit()
Dátum- és időértékek lekérése
Dátumok és időpontok lekérése
Amikor dátumidő-értékeket kérünk az SQL Server-ről, automatikusan átkonvertálódnak Python datetime objektumokká:
from datetime import date, time, datetime
# Create and populate a temp table with date, time, and datetime columns
cursor.execute("""
CREATE TABLE #Events (
ID INT,
EventDate DATE,
StartTime TIME,
CreatedAt DATETIME2
)
""")
cursor.execute(
"INSERT INTO #Events (ID, EventDate, StartTime, CreatedAt) VALUES (1, %(d)s, %(t)s, %(dt)s)",
{"d": date(2024, 12, 25), "t": time(14, 30, 0), "dt": datetime(2024, 3, 15, 14, 30, 45)}
)
conn.commit()
cursor.execute("SELECT EventDate, StartTime, CreatedAt FROM #Events WHERE ID = 1")
row = cursor.fetchone()
print(type(row.EventDate)) # <class 'datetime.date'>
print(type(row.StartTime)) # <class 'datetime.time'>
print(type(row.CreatedAt)) # <class 'datetime.datetime'>
print(row.EventDate) # 2024-12-25
print(row.StartTime) # 14:30:00
print(row.CreatedAt) # 2024-03-15 14:30:45
Dátum- és időösszetevők elérése
A Python datetime objektumok attribútumokat biztosítanak az egyes dátum- és időpontkomponensekhez való hozzáféréshez:
cursor.execute("SELECT OrderDate FROM Sales.SalesOrderHeader WHERE SalesOrderID = 43659")
row = cursor.fetchone()
dt = row.OrderDate
# Date components
print(dt.year)
print(dt.month)
print(dt.day)
# Time components
print(dt.hour)
print(dt.minute)
print(dt.second)
print(dt.microsecond)
Időzónák
Az eltolást figyelembe vevő és az eltolást figyelmen kívül hagyó dátum- és időértékek
A Python datetime objektumai vagy eltolásinformációval rendelkeznek (van tzinfo), vagy nem rendelkeznek eltolásinformációval (nincs időzóna-információjuk). Az SQL Server mindkét típusú oszlopot tartalmazza:
| SQL Server-típus | Elvárások | Boltok időzónája? |
|---|---|---|
| datetime, datetime2, smalldatetime | Offset-naiv | No |
| datetimeoffset | Eltolást figyelembe vevő | Yes |
Időzónától ismert dátum küldése egy datetime2 oszlopba működik, de az időzóna információ csendben eltűnik. Egy naiv datetime datetimeoffset oszlopnak való elküldésekor az UTC (+00:00) lesz hozzárendelve eltolásként. Legyen egyértelmű, hogy mely fajtát küldöd:
Az alábbi példa bemutatja, hogyan lehet létrehozni és használni az offset-naiv és offset-tudatos dátumidőpontokat:
from datetime import datetime, timezone, timedelta
# Create temp tables: one datetime2 column and one datetimeoffset column
cursor.execute("CREATE TABLE #Logs (LogTime DATETIME2)")
cursor.execute("CREATE TABLE #GlobalEvents (EventTime DATETIMEOFFSET)")
# Offset-naive - use for datetime2 columns
naive_dt = datetime(2024, 3, 15, 14, 30, 45)
cursor.execute(
"INSERT INTO #Logs (LogTime) VALUES (%(log_time)s)", # datetime2 column
{"log_time": naive_dt}
)
# Offset-aware - use for datetimeoffset columns
eastern = timezone(timedelta(hours=-5))
aware_dt = datetime(2024, 3, 15, 14, 30, 45, tzinfo=eastern)
cursor.execute(
"INSERT INTO #GlobalEvents (EventTime) VALUES (%(event_time)s)", # datetimeoffset column
{"event_time": aware_dt}
)
conn.commit()
A kettő közötti átalakításhoz:
from datetime import datetime, timezone
# Make naive datetime timezone-aware
naive = datetime(2024, 3, 15, 14, 30)
aware = naive.replace(tzinfo=timezone.utc)
# Strip timezone from aware datetime
aware = datetime.now(timezone.utc)
naive = aware.replace(tzinfo=None)
datetimeoffset típus
Az SQL Server datetimeoffset időzóna információkat tárol. Az alábbi példa bemutatja az időzónától ismert dátumidőpontok behelyezését és visszakeresését:
from datetime import datetime, timezone, timedelta
# Create temp table with a datetimeoffset column
cursor.execute("CREATE TABLE #GlobalEvents (ID INT, EventTime DATETIMEOFFSET)")
# Create timezone-aware datetime
eastern = timezone(timedelta(hours=-5))
dt_eastern = datetime(2024, 3, 15, 14, 30, tzinfo=eastern)
cursor.execute(
"INSERT INTO #GlobalEvents (ID, EventTime) VALUES (1, %(ts)s)", # datetimeoffset column
{"ts": dt_eastern}
)
conn.commit()
# Retrieve timezone-aware datetime
cursor.execute("SELECT EventTime FROM #GlobalEvents WHERE ID = 1")
row = cursor.fetchone()
print(row.EventTime) # 2024-03-15 14:30:00-05:00
print(row.EventTime.tzinfo) # UTC-05:00
Időzónák közötti átalakítás
Használd a Python időzóna módszereit, hogy a datetime-offset értékeket különböző időzóna reprezentációk között konvertáld:
from datetime import datetime, timezone, timedelta
# Create and populate a temp table with a datetimeoffset column
cursor.execute("CREATE TABLE #GlobalEvents (EventTime DATETIMEOFFSET)")
eastern = timezone(timedelta(hours=-5))
cursor.execute(
"INSERT INTO #GlobalEvents (EventTime) VALUES (%(ts)s)",
{"ts": datetime(2024, 3, 15, 14, 30, tzinfo=eastern)}
)
conn.commit()
# Retrieve as-stored
cursor.execute("SELECT EventTime FROM #GlobalEvents")
row = cursor.fetchone()
stored_time = row.EventTime # Has timezone info
# Convert to UTC
utc_time = stored_time.astimezone(timezone.utc)
print(utc_time)
# Convert to local timezone
local_time = stored_time.astimezone() # System timezone
print(local_time)
AT TIME ZONE az SQL-ben
Az SQL Server záradéka AT TIME ZONE a lekérdezésen belüli időzónák között átalakítja a datetimeoffset értékeket:
from datetime import datetime, timezone, timedelta
# Create and populate a temp table with a datetimeoffset column
cursor.execute("CREATE TABLE #GlobalEvents (EventTime DATETIMEOFFSET)")
eastern = timezone(timedelta(hours=-5))
cursor.execute(
"INSERT INTO #GlobalEvents (EventTime) VALUES (%(ts)s)",
{"ts": datetime(2024, 3, 15, 14, 30, tzinfo=eastern)}
)
conn.commit()
# Convert timezone in SQL Server (2016+)
cursor.execute("""
SELECT
EventTime,
EventTime AT TIME ZONE 'Pacific Standard Time' AS PacificTime,
EventTime AT TIME ZONE 'UTC' AS UTCTime
FROM #GlobalEvents
""")
for row in cursor:
print(f"Original: {row.EventTime}")
print(f"Pacific: {row.PacificTime}")
print(f"UTC: {row.UTCTime}")
Dátumaritmetika
Dátumkülönbségek kiszámítása
Számoljuk ki a két dátum közötti napok számát a dátumidő-objektumok kivonásával:
from datetime import timedelta
cursor.execute("SELECT OrderDate, ShipDate FROM Sales.SalesOrderHeader WHERE SalesOrderID = 43659")
row = cursor.fetchone()
# Days between dates
if row.ShipDate and row.OrderDate:
difference = row.ShipDate - row.OrderDate
print(f"Shipped in {difference.days} days")
Intervallumok hozzáadása
A timedelta használatával napokat, hónapokat vagy más időintervallumokat adhat hozzá egy dátum- és időértékhez, illetve vonhat ki belőle:
from datetime import datetime, timedelta
# Create and populate a temp table
cursor.execute("""
CREATE TABLE #Subscriptions (
ID INT,
CreatedAt DATETIME2,
ExpiresAt DATETIME2
)
""")
cursor.execute(
"INSERT INTO #Subscriptions (ID, CreatedAt) VALUES (1, %(created)s)",
{"created": datetime(2024, 1, 1, 12, 0, 0)}
)
conn.commit()
cursor.execute("SELECT CreatedAt FROM #Subscriptions WHERE ID = 1")
row = cursor.fetchone()
# Calculate expiration (30 days from creation)
expiration = row.CreatedAt + timedelta(days=30)
print(f"Expires: {expiration}")
# Update with calculated date
cursor.execute(
"UPDATE #Subscriptions SET ExpiresAt = %(exp)s WHERE ID = %(id)s",
{"exp": expiration, "id": 1}
)
conn.commit()
DATEADD az SQL-ben
Az SQL Server függvénye közvetlenül végzi a DATEADD dátumaritmetikát lekérdezésekben:
# Use SQL Server date functions
cursor.execute("""
SELECT
OrderDate,
DATEADD(day, 30, OrderDate) AS DueDate,
DATEADD(month, 1, OrderDate) AS NextMonth
FROM Sales.SalesOrderHeader
""")
Értékek formázása
Megjelenítési formátum
Formázza a dátum- és időértékeket megjelenítéshez a(z) strftime() használatával, formátumspecifikátorokkal:
from datetime import datetime
cursor.execute("SELECT TOP(10) OrderDate FROM Sales.SalesOrderHeader")
for row in cursor:
# strftime formatting
print(row.OrderDate.strftime("%Y-%m-%d")) # 2024-03-15
print(row.OrderDate.strftime("%B %d, %Y")) # March 15, 2024
print(row.OrderDate.strftime("%m/%d/%Y %I:%M %p")) # 03/15/2024 02:30 PM
Feldolgozás karakterláncokból
A string reprezentációk átalakítása Python datetime objektumokká a következők segítségévelstrptime():
from datetime import datetime
# Create temp table for the demo
cursor.execute("CREATE TABLE #Events (EventDate DATE)")
# Parse incoming date strings
date_string = "2024-03-15"
parsed_date = datetime.strptime(date_string, "%Y-%m-%d").date()
cursor.execute(
"INSERT INTO #Events (EventDate) VALUES (%(date)s)",
{"date": parsed_date}
)
conn.commit()
ISO 8601 formátum
Az ISO 8601 formátum hasznos API-khoz és JSON serializációhoz. Használja a isoformat() és fromisoformat() elemeket az átalakításhoz:
from datetime import datetime
# Create and populate a temp table
cursor.execute("CREATE TABLE #Logs (ID INT, CreatedAt DATETIME2)")
cursor.execute(
"INSERT INTO #Logs (ID, CreatedAt) VALUES (1, %(ts)s)",
{"ts": datetime(2024, 3, 15, 14, 30, 45)}
)
conn.commit()
cursor.execute("SELECT CreatedAt FROM #Logs WHERE ID = 1")
row = cursor.fetchone()
# ISO format for APIs/JSON
iso_string = row.CreatedAt.isoformat()
print(iso_string) # 2024-03-15T14:30:45
# Parse ISO format
dt = datetime.fromisoformat("2024-03-15T14:30:45")
Gyakori minták
Lekérdezés dátumtartomány szerint
Lekérdezés a rekordokat egy adott dátumtartományban a kezdő és befejező dátumok paraméterezésével:
from datetime import date, datetime
# Query by date range
start_date = date(2024, 1, 1)
end_date = date(2024, 12, 31)
cursor.execute("""
SELECT SalesOrderID, OrderDate, TotalDue
FROM Sales.SalesOrderHeader
WHERE OrderDate >= %(start)s AND OrderDate < %(end)s
""", {"start": start_date, "end": end_date})
Keresés a mai rekordokat
A mai lekérdezési rekordokat úgy hozták létre, hogy a dátumidőpont oszlopot egy dátumra vetjük és összehasonlítjuk a mai dátummal:
from datetime import date
# Create and populate a temp table with a row logged today
cursor.execute("CREATE TABLE #Logs (LogTime DATETIME2)")
cursor.execute("INSERT INTO #Logs (LogTime) VALUES (GETDATE())")
conn.commit()
cursor.execute("""
SELECT * FROM #Logs
WHERE CAST(LogTime AS DATE) = %(today)s
""", {"today": date.today()})
# Or using SQL Server function
cursor.execute("""
SELECT * FROM #Logs
WHERE CAST(LogTime AS DATE) = CAST(GETDATE() AS DATE)
""")
NULL dátumok kezelése
Ellenőrizd az None értékeket a datetime oszlopok feldolgozása előtt, mivel a NULL dátumok úgy jelennek meg, mint None a Python-ban:
cursor.execute("SELECT TOP 5 FirstName, ModifiedDate FROM Person.Person")
for row in cursor:
if row.ModifiedDate is None:
print(f"{row.FirstName}: Date not on file")
else:
age = (date.today() - row.ModifiedDate.date()).days // 365
print(f"{row.FirstName}: modified {age} years ago")
Audit időbélyegek tárolása
Hozz létre audit oszlopokat, hogy nyomon kövesd, mikor hoznak létre és módosítanak a rekordokat:
from datetime import datetime
# Create temp table for audit timestamp demo
cursor.execute("""
CREATE TABLE #AuditOrders (
ID INT IDENTITY(1,1) PRIMARY KEY,
CustomerID INT,
Total DECIMAL(10,2),
CreatedAt DATETIME2,
ModifiedAt DATETIME2
)
""")
def create_order(cursor, customer_id: int, total: float) -> int:
now = datetime.now()
cursor.execute("""
INSERT INTO #AuditOrders (CustomerID, Total, CreatedAt, ModifiedAt)
VALUES (%(cust)s, %(total)s, %(created)s, %(modified)s);
SELECT SCOPE_IDENTITY();
""", {
"cust": customer_id,
"total": total,
"created": now,
"modified": now
})
return cursor.fetchval()
def update_order(cursor, order_id: int, total: float):
cursor.execute("""
UPDATE #AuditOrders
SET Total = %(total)s, ModifiedAt = %(modified)s
WHERE ID = %(id)s
""", {
"total": total,
"modified": datetime.now(),
"id": order_id
})
Konkrét forgatókönyvek
Dátumok 1753 előtt
Felhasználás datetime2 történelmi dátumokhoz (a datetime típus csak 1753-as éveket támogat). A következő példa történelmi dátumot ad be:
from datetime import datetime
# Create temp table with a datetime2 column
cursor.execute("CREATE TABLE #HistoricalEvents (EventDate DATETIME2, Description NVARCHAR(200))")
# Historical date (works with datetime2, fails with datetime)
historical = datetime(1500, 1, 1)
cursor.execute(
"INSERT INTO #HistoricalEvents (EventDate, Description) VALUES (%(date)s, %(desc)s)",
{"date": historical, "desc": "Archived historical record"}
)
conn.commit()
Csak időalapú értékek
Tároljuk a napszak értékeket a Python time objektumával:
from datetime import time
# Create temp table with time columns
cursor.execute("""
CREATE TABLE #BusinessHours (
DayOfWeek NVARCHAR(10),
OpenTime TIME,
CloseTime TIME
)
""")
# Store time of day without date
opening_time = time(9, 0, 0) # 9:00 AM
closing_time = time(17, 30, 0) # 5:30 PM
cursor.execute("""
INSERT INTO #BusinessHours (DayOfWeek, OpenTime, CloseTime)
VALUES (%(day)s, %(open)s, %(close)s)
""", {"day": "Monday", "open": opening_time, "close": closing_time})
conn.commit()
Munkanapok kiszámítása
Egy segítő függvény képes kiszámolni dátumintervallumokat a hétvégék kihagyása közben:
from datetime import date, timedelta
def add_business_days(start: date, days: int) -> date:
"""Add business days (skip weekends)."""
current = start
remaining = days
while remaining > 0:
current += timedelta(days=1)
if current.weekday() < 5: # Monday = 0, Friday = 4
remaining -= 1
return current
order_date = date(2024, 3, 15) # Friday
due_date = add_business_days(order_date, 5) # Skip weekend
print(f"Due date: {due_date}") # 2024-03-22 (next Friday)